Django-Paypal standard subscriptions integration

Want to have a site with PayPal integration using Django with no fuss? That is just django-paypal’s game. I’ll show you how to integrate with Website Payments Standard in a jiffy.

pip install django-paypal

You are using pip, right? If not:

apt-get install python-setuptools
easy_install pip

Whew! Thats better. Let’s fix up your settings.py:

PAYPAL_RECEIVER_EMAIL = "yourbusinessaccount@example.com"

INSTALLED_APPS = ( ...,
  'paypal.standard.ipn',
  ...)

Now, you’ll have to add an entry in your urls.py for the Instant Payment Notifications (IPNs) from PayPal that let you know when people have paid:

urlpatterns = patterns('',
  ...
  url(r'^/something/hard/to/guess/, include('paypal.standard.ipn.urls')),
  ...
)

We need a view in views.py. That is easy too:

from django.conf import settings
...
def subscribe(request):
    # What you want the button to do.
    paypal_dict = {
    "cmd": "_xclick-subscriptions",
	"business": settings.PAYPAL_RECEIVER_EMAIL,
	"a1": "0",	                   # trial price
	"p1": 1,	                   # trial duration, duration of unit defaults to month
	"a3": "29.95",                     # yearly price
	"p3": 1,                           # duration of each unit (depends on unit)
	"t3": "Y",                         # duration unit ("M for Month")
    "src": "1",                        # make payments recur
	"sra": "1",                        # reattempt payment on payment error
	"no_note": "1",                    # remove extra notes (optional)
    "item_name": "PayPal Shows This To The User",
    "invoice": "101",
    "notify_url": "http://example.com/something/hard/to/guess/",
    "return_url": "http://example.com/thanks/",
    "cancel_return": "http://example.com/cancel/",
    "custom": request.user.username,   # put whatever data you need to track things here
    }

    # Create the instance.
    form = PayPalPaymentsForm(initial=paypal_dict, button_type="subscribe")

    context = {"form": form, "encoded_email" : urlquote(settings.PAYPAL_RECEIVER_EMAIL), "paid" : request.user.get_profile().paid}

The reason I’ve included the encoded_email in the view is related to the unsubscribe button we’ll setup in a minute. The button in that view will be a subscription. You can easily modify it to be a buy now button. See the README for django-paypal. If you browse the code on github and checkout paypal.standard.forms.py you can see all the possible options for buttons.

Now we can create the template and the (optional) unsubscribe button:

{% extends "base.html" %}

{% block content %}

{% if paid %}
<h2>Thank you! You are currently subscribed.</h2>
<p id="page-intro">You can cancel anytime online using your PayPal account or from this page.
	If you have any questions or problems please <a href="mailto:you@example.com">email us</a>.
	</p>

	<A HREF="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias={{ encoded_email }}" _fcksavedurl="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias={{ encoded_email }}"><IMG BORDER="0" SRC="https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif"></A>
{% else %}
	<!-- Page Head -->
	<h2>Please subscribe to Example using PayPal.</h2>
	<p id="page-intro">You can cancel anytime online using your PayPal account or on this page.
		If you have any questions or problems please <a href="mailto:you@example.com">email us</a>.
		</p>

	{{ form.render }}
{% endif %}
{% endblock %}

Keying off of if the user has paid or not means we can use this template for subscribing or unsubscribing. Now go get paid!

WordPress, Ubuntu – Now

I recently found cause to setup some mini-sales sites according to advice I’ve seen from Tim Ferriss, Rob Walling, and others. If you need to get something up fast, cheap, and quick this is for you.

Login to the Rackspace Cloud site and create a new server instance with your favorite flavor of Ubuntu. I used Lucid Lynx 10.02.

ssh root@
apt-get update
apt-get install ufw mysql-server wordpress links

I grabbed Uncomplicated Firewall (ufw) to lockdown the box. It’s an simplified wrapper for iptables on Ubuntu. This will install wordpress to /usr/share/wordpress.

For my purposes (mini-sales site) I wanted the wordpress installation at the domain root. You might want it to be at /wordpress or another url. I’ll show it both ways here:

# Show apache2 where wordpress lives
#for wordpress at http://example.com/wordpress
ln -s /usr/share/wordpress /var/www/wordpress
# (site root and not /wordpress/)
rm -rf /var/www && ln -s /usr/share/wordpress /var/www
mkdir -p /usr/share/wordpress/wp-updates
mkdir -p /usr/share/wordpress/wp-updates/localhost

If you wanted it at http://example.com/wordpress you’d use line 3 only. Otherwise you need lines 5-7. Now we can install the database and wordpress itself:

# Install WordPress to db using the provided script
bash /usr/share/doc/wordpress/examples/setup-mysql -n wordpress localhost
/etc/init.d/apache2 restart

Now we need to install wordpress from localhost so we’re forced to use a text based browser. Load up links and fill in a blog name and email. The site will give you an admin login and password. Login using that username and password and navigate to Settings -> General. Change the WordPress Address and Blog Address domains to your URL: http://example.com. You’ll want to use http://example.com/wordpress/ if you didn’t install at the site root.

links http://localhost

Finally we can set the permissions and prep the site for being public (be sure to change example.com to your domain):

chown -R www-data /usr/share/wordpress
ln -s /etc/wordpress/config-localhost.php /etc/wordpress/config-example.com.php
/etc/init.d/apache2 restart

Voila! Use your local machine to navigate to your domain. Happy blogging/mini-sales sites.