Recurly

Python Client Library

The Recurly Python Client library is an open source library to interact with Recurly’s subscription management from your Python website. The library interacts with Recurly’s REST API.

View the GitHub project site for a list of requirements and download/install instructions.

Configuration

First, import the recurly library and setup your authentication credentials:

import recurly

recurly.SUBDOMAIN = 'YOUR-SUBDOMAIN'
recurly.API_KEY = 'abcdef01234567890abcdef01234567890'
recurly.js.PRIVATE_KEY = '01234567890abcdef01234567890abcdef'

# Set a default currency for your API requests
recurly.DEFAULT_CURRENCY = 'USD'
All the examples will assume that you have properly set up your configuration.

Handling Dates

Dates from Recurly are converted into DateTime objects, which gives your methods to compare or format dates using that Python class. Dates are returned in UTC format.

sub = Subscription.get('1dd2129544f3e57ecf7d84467985eaf6')
sub.activated_at
#datetime.datetime(2013, 1, 22, 17, 21, 24, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>)

#find local time

UTC_OFFSET_TIMEDELTA = datetime.datetime.utcnow() - datetime.datetime.now()
localtime = s.activated_at - UTC_OFFSET_TIMEDELTA
#datetime.datetime(2013, 1, 22, 11, 21, 24, 11, tzinfo=<iso8601.iso8601.Utc object at 0xa06396c>)

Using the API

Each endpoint is documented with examples here. Feel free to explore them for more information related to specific endpoints.

Handling Errors

When using the Python library, Recurly recommends proper exception handling. Not handling exceptions properly could result in unexpected results or sudden termination of your code. Below is a sample example in Python as how to properly catch exceptions thrown by the Recurly Python library.

try:
  #will throw a not found error if account does not exist
  account = Account.get('1')
  
  subscription = Subscription()
  subscription.account = account

  #this will throw an error because a plan_code was not set
  subscription.save()
except NotFoundError:
  print "Account not found.\n"
except ValidationError, errors:
  for e in errors.itervalues():
    print "%s:%s" % (e.field, e.message)

For a list of possible exception types review: https://github.com/recurly/recurly-client-python/blob/master/recurly/errors.py

Logging

You can collect logging from Recurly to have more information when you encounter an unexpected error.

import recurly
import logging

log = logging.getLogger('recurly.http.response')
log.setLevel(logging.DEBUG)
#create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
#create formatter
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#add formatter to ch
ch.setFormatter(formatter)
#add ch to logger
log.addHandler(ch)

Recurly.js

You can easily use the Python library to create signatures for all the forms. Here is an example of a new subscription form. The full documenatation with all the available options are here

This example is using Python’s SimpleHTTPServer.

This example is not meant to be put into production but rather to provide you with a starting point for your integration.
import SimpleHTTPServer
import recurly
import SocketServer

class ServeRecurlyJS(SimpleHTTPServer.SimpleHTTPRequestHandler):

    def do_GET(self):
        #you would need to handle serving javascript/css files
        #as well as a success page
        recurly.SUBDOMAIN = 'YOUR-SUBDOMAIN'
        recurly.API_KEY = 'abcdef01234567890abcdef01234567890'
        recurly.js.PRIVATE_KEY = '01234567890abcdef01234567890abcdef'
        sig = recurly.js.sign({'subscription': {'plan_code': 'gold_plan'}})
        my_html = """<html>
                      <head>
                        <link href="recurlyjs/themes/default/recurly.css" rel="stylesheet">
                        <script src="js/jquery.js"></script>
                        <script src="recurlyjs/build/recurly.js"></script>
                        <script>
                        $(function(){
                          Recurly.config({
                            subdomain: 'YOUR-SUBDOMAIN'
                            , currency: 'USD' // GBP | CAD | EUR, etc...
                          });
                     
                     
                          Recurly.buildSubscriptionForm({
                            target: '#recurly-form',
                            planCode: 'gold_plan',
                            successURL: 'success',
                            signature: '%s',
                          });
                     
                        });
                        </script>
                      </head>
                      <body>
                        <h1>Test Form</h1>
                        <div id="recurly-form"></div>
                      </body>
                    </html>""" % sig
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(my_html)

PORT = 8001

Handler = ServeRecurlyJS

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()

Handle Push Notifications

There is a built in class to help handle push notifications. For a list of the different push notifications and their format, you can view the documentation.

Here is an example using Python’s SimpleHTTPServer.

This example is not meant to be put into production but rather to provide you with a starting point for your integration.
#Recurly will POST an XML payload to your URL that you designate
#in your push notifications' configuration

import SimpleHTTPServer
import recurly
import SocketServer


class PushNotificationHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    def do_POST(self):
        bytes = int(self.headers["content-length"])
        data = self.rfile.read(bytes)
        notification = recurly.objects_for_push_notification(data)
        #each push notification is defined by a type
        if notification['type'] == "successful_payment_notification":
            print "Payment Received"
        elif notification['type'] == "failed_payment_notification":
            print "The payment did not work"
        self.send_response(200)
        self.wfile.write("OK")
        self.wfile.flush()


PORT = 8000

Handler = PushNotificationHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT
httpd.serve_forever()

Support

Looking for help? Please contact support@recurly.com or visit support.recurly.com. Stackoverflow is also a great place to talk to the community and find answers to common questions.

Announcements

For the latest API and client library announcements follow Recurly on Twitter and join our Google Group: