PayPal IPN Revised for Python

Configuring with Nginx

Normally you can serve your applications directly to the web for tasks such as these, but some instances may require serving static files such as graphics or css. You can do this with circuits.web, but you can also use a webserver such as Nginx to serve both static files and your python applications. Primarily handy if you don’t wish link directly to a non-standard port.

A typical configuration for Nginx:

#!/usr/bin/env python

The try_files directive is available on Nginx 0.7.26 and above. Its a very useful directive that allows you to test the request URI a number of ways before falling back to a catch-all location. With this a static file such as css, or javascript, or a folder such as /images, would be served directly by Nginx. Anything else not caught by location rules would be sent to @app to be proxied to your Python application.

You’ll also notice a few extras on the bottom of the server configuration. To cut down on access log clutter as well as erorr log clutter if you don’t have a favicon or robots.txt file ,you can specifically turn off the logging of those types of access. Also its always a good idea to deny access to any possible .hidden unix files that may exist in your document’s root path (such as an .htpasswd copied over from another host).

Uninterrupted Source
For your convenience, the complete example source has been pasted below in uninterrupted form.

from time import time
from urllib import urlencode
from sqlite3 import connect, Error as sqerr
from urllib2 import urlopen, Request
from circuits.web import Controller, Server


  1. Mark Johnson says:

    This is great! Thanks for this post. I am just starting python and this will help a lot.

  2. Carlton Oetzel says:

    Hello can I reference some of the content from this blog if I link back to you?

  3. kbeezie says:

    Sure, however I do not know what most of it has to do with free gift cards? (potential spam url was removed)

  4. Robert Payne says:

    I highly recommend also using dcramer’s django-payapl branch:

  5. kbeezie says:

    Course one would have to use django (which isn’t a bad thing if you’re already down that route).

  6. Alex says:

    I am tinkering with Paypal’s IPN, and I have a question about your code.

    According to PayPal’s docs, the POST you send back to them must contain the variables in the exact same order as they were sent to you (with cmd=_notify-validate in the beginning).

    In your code, you’re just adding a new item to the dictionary (thus you cannot predict in which order the final request will be formed). I suspect that in certain cases PayPal will refuse to accept your response, because the order of the values has changed.

    Has that ever happened to you? Or are PayPal’s rules more relaxed than the docs say?

  7. kbeezie says:

    Has not happened to me, though one would assume that if unchanged the info goes right back to them in the same order. But I’ve never encountered that problem with either code.