Recurly

Recurly.js Signature Generation

Note—This information is provided for Recurly users not implementing in a language for which we provide a client library. If you are using one of our client libraries, you can ignore this page.

Format

A RecurlyJS signature is sent as a single string passed to the form building functions that takes the form:

<secure_hash>|<protected_string>

where the components are:

secure_hash
a 160-bit HMAC-SHA1 hash code, represented as a hex digest
protected_string
a URL encoded query string of all the protected parameters being signed

Real World Example

f716dfe95ea8d7c3cdd2c5e6421ee40a97bf46d5|account%5Baccount_code%5D=1235813&nonce=93634c1a1580454fa48cd5b51aec3b3f&subscription%5Bplan_code%5D=premium&timestamp=1330550736

Building the Protected String

For the most part, the protected string is a standard form encoded query string. The only item of note is that Recurly's API requires nesting of attributes - for example, the plan_code is part of a larger subscription structure.

For this, Recurly relies on a commonly used convention, where attribute nesting is indicated via brackets. For the above example, this would translate into an attribute name of subscription[plan_code]. The documentation for PHP's http_build_query function does a good job of completely describing this convention, with examples covering nested attributes, as well as array data.

A Concrete Example

When creating a new subscription with RecurlyJS, the subscription[plan_code] parameter must be signed. In addition, the signature will include a "nonce" value, and timestamp (see next section on Mandatory Parameters.) These might map to the following un-encoded string:

Un-encoded Version

nonce=e7a35566884d478bbbcf413e6600901c&subscription[plan_code]=premium_monthly&timestamp=1330557114

Because the bracket characters are reserved characters in URIs, and because other values could contain reserved characters (for instance, the @ sign in an email address), the names and values must be percent encoded. This yields the following, which is the actual protected string that would be used:

Final Protected String

nonce=e7a35566884d478bbbcf413e6600901c&subscription%5Bplan_code%5D=premium_monthly&timestamp=1330557114

Mandatory Parameters Shared by All Signatures

In addition to the actual Recurly API parameters you specify, all signed requests must include the following:

parameter description
timestamp Unix timestamp, i.e. elapsed seconds since Midnight, Jan 1st 1970, UTC
nonce A randomly generated string

Both of these serve to enhance security. The nonce value (number used only once) is a random string you supply (a generated UUID/GUID would be a good candidate) that will be remembered by Recurly, so that the signed request is only good for one use. The timestamp parameter is a Unix timestamp denoting when the signature was generated.

Generating the HMAC-SHA1 Hash

The HMAC-SHA1 hash is generated using a shared secret between you and Recurly - your private key. This key, along with the protected string, are used as input to the HMAC function. The output will be a 160 bit (20 byte) value, which will likely contain non-printable characters. For this reason, we use a hex digest of the hash, where each byte maps to a 2 character hexadecimal number, i.e 0 -> 00, 255 -> FF. This digest will be 40 characters long.

Libraries for generating the HMAC are either included, or can be found for most programming languages in use on the web. Here's what it looks like in Ruby:

Ruby HMAC Example

require 'openssl'

def create_hmac key, protected_string
  OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest::Digest.new('SHA1'),
    key,
    protected_string
  )
end