• Content

Customize Your Checkout Process and Accept Payments Securely

Securely accept sensitive payment details within your checkout process with a fully customizable user experience. The Recurly.js JavaScript library secures your checkout forms. Create subscriptions, process one-time transactions, and update customer billing information worry-free.

PCI Compliance with Recurly.js Elements

Recurly.js provides Elements, which inject transparent iframes that allow you to deliver a customized customer checkout experience, while ensuring you meet the latest PCI DSS SAQ A compliance requirements.

Open Source

Recurly.js is open source, and we welcome all to view the code and work with us on GitHub. We’re here to make Recurly.js the best possible tool for your needs.

 View code on GitHub


How It Works

When a customer submits your payment form, Recurly.js sends customer payment information to be encrypted and stored at Recurly and gives you an authorization key to complete the subscription process using our API.

With this authorization key (or token), you can do anything with our API that requires payment information. Because you never handle any sensitive payment information, your PCI scope is drastically reduced.


Getting Started

To begin, you’ll include the Recurly.js script on your page.

<script src="https://js.recurly.com/v4/recurly.js"></script>
<link href="https://js.recurly.com/v4/recurly.css" rel="stylesheet" type="text/css">

This exposes a single global object, recurly.

It is not necessary to include recurly.css, but we highly recommend it while you’re getting set up. It provides some helpful default styles to Recurly Elements.

Self-Hosting Recurly.js

The Recurly-hosted version of recurly.js is designed and updated to maintain compatibility with system update deployments that take place from time-to-time. Locally hosted versions of recurly.js run the risk of encountering issues with system interaction and incompatibility which may result in avoidable service interruptions on your client page. It is for this reason, we highly recommend against and do not support locally hosted copies of recurly.js.

Configure

Simply call recurly.configure anywhere on your page, passing your public key. This identifies your site to Recurly servers. You can find your public key in the API Access section of your admin app.

recurly.configure('sc-ABCDEFGHI123456789');

Use Your Site’s Public Key

Be sure to replace sc-ABCDEFGHI123456789 with your own public key.

recurly.configure accepts other options not detailed here. You may refer to the source for more detail.

Build a Payment Form With Elements

To collect card payment information from your customers, you may build an HTML form however you wish, collecting all user data that you require. Use the data-recurly attribute to identify any non-card billing fields to Recurly.js. Card fields are built using Elements

<form id="my-form">
  <input type="text" data-recurly="first_name">
  <input type="text" data-recurly="last_name">

  <div id="recurly-elements">
    <!-- Recurly Elements will be attached here -->
  </div>

  <!-- Recurly.js will update this field automatically -->
  <input type="hidden" name="recurly-token" data-recurly="token">

  <button>submit</button>
</form>

The Card Element

This is the simplest and most streamlined way to accept customer card data. Recurly will inject a single field that will accept the card number, expiry, and cvv. This field is responsive and includes helpful UX enhancements to make card entry as smooth as possible on a multitude of devices.

const elements = recurly.Elements();
const cardElement = elements.CardElement();
cardElement.attach('#recurly-elements');

Other Elements

Recurly.js has Elements for individual card fields as well. Use these fields when you would like to display card fields separately from each other. This is helpful when the combined field does not fit your design needs.

See Elements for more details on creating and interacting with Elements

The example forms above contain the minimum required input fields, and the tables below document all possible input fields.

Billing fields

Field Name Example Description  
first_name Ben Cardholder first name. Required  
last_name du Monde Cardholder last name. Required  
address1 1313 Main St. First line of a street address.  
address2 Unit 1 Second line of a street address.  
city Hope Town or locality.  
state WA Province or region.  
postal_code 98552 Postal code.  
country US ISO 3166-1 alpha-2 country code.  
phone 555-867-5309 Phone number.  
vat_number SE0000 Customer VAT number. Used for VAT exclusion  
tax_identifier 972.791.615-53, 20-12345678-6 A valid CPF or CUIT. Required if it is a consumer card in Brazil early access or in Argentina.  
tax_identifier_type cpf, cuit cpf and cuit are the only accepted values for this field. Required if it is a consumer card in Brazil early access or in Argentina.  

Depending on how you’ve configured your billing address requirements, some of the fields in the table above may be required.

Try it now

This page includes recurly.js. Try it out now it your browser’s developer console.

Styling Elements

Since elements are within iframes, any style properties within those iframes must be configured on your Element. See the code example and table below.

const cardElement = elements.CardElement({
  inputType: 'mobileSelect',
  style: {
    fontSize: '1em',
    placeholder: {
      color: 'gray !important',
      fontWeight: 'bold',
      content: {
        number: 'Card number',
        cvv: 'CVC'
      }
    },
    invalid: {
      fontColor: 'red'
    }
  }
});

Styling the card element

Options available to the card element are detailed in the following table.

Property Default Description
displayIcon true If false, the card brand icon will be hidden
inputType 'text' Modifies the input type of the card field: text - text input for all fields. mobileSelect - if the user is using a mobile device, a native expiry select interface will appear when entering the expiration date. select - Expiration date will be input using a select field on all devices. Mobile devices will display an optimized interface.
style {} See common field style properties section below.
style.fontColor '#545457' Font color for each input element
style.fontFamily 'Source Sans Pro' font-family for each input element
style.fontSize '16px' font-size for each input element
style.fontWeight 700 font-weight for each input element
style.placeholder {} Object
style.placeholder.color '#a3a3a7' Font color applied to all placeholder text
style.placeholder.content {} Object
style.placeholder.content.number 'Card number' Placeholder content for the number input.
style.placeholder.content.expiry 'MM / YY' Placeholder content for the expiry input.
style.placeholder.content.cvv 'CVV' Placeholder content for the card verification value input.
style.invalid {} Object. Style to apply to input elements when they contain an invalid value. See common field style properties section below.
style.invalid.fontColor '#a3a3a7' Font color applied to invalid input elements.
tabIndex   tabindex property to be applied to the outer iframe.

Styling the individual card elements

Options unique to the individual card elements are detailed in the following table.

Property Default Description
format true Enables contextual input formatting, injecting spaces to match the card brand, and forcing numeric input on expiry and cvv.
inputType text Modifies the input type of the expiry fields. 'text' - normal text input. 'mobileSelect' - if the user is using a mobile device, a native select interface will appear. 'select' - A select field will display on all devices
style {} See common field style properties section below.
style.padding   padding
style.placeholder.color   Font color applied to the placeholder text.
style.placeholder.content '' Placeholder content (e.g. 'Card number', 'CVV')
tabIndex   tabIndex property to be applied to the outer iframe.

Common field style properties

Property Default Reference
style.fontColor 'black' color
style.fontFamily 'Helvetica' font-family
style.fontFeatureSettings 'normal' font-feature-settings
style.fontKerning 'auto' font-kerning
style.fontSize 'normal' font-size
style.fontSmoothing 'normal' font-smoothing
style.fontStretch 'normal' font-stretch
style.fontStyle 'normal' font-style
style.fontVariant 'normal' font-variant
style.fontWeight 'normal' font-weight
style.letterSpacing 'normal' letter-spacing
style.lineHeight 'normal' line-height
style.textAlign   text-align
style.textDecoration   text-decoration
style.textRendering 'auto' text-rendering
style.textShadow 'none' text-shadow
style.textTransform 'none' text-transform

CSS Classes

Since Recurly.js Elements are contained within iframes, the default browser appearance for those fields will likely not match the appearance of the other inputs in your billing form. We provide the following CSS classes to achieve a look and feel similar to your form. Using these classes, you may specify Element size, colors, and a full range of appearance customization to make the injected Elements blend into your payment form.

Class Description
recurly-element Styles for all Recurly Element containers.
recurly-element-focus Styles applied when a user focuses on an Element.
recurly-element-invalid Styles applied when an Element contains invalid input.
recurly-element-card Styles specific to combined card Element container.
recurly-element-number Styles specific to the card number Element container.
recurly-element-month Styles specific to the card expiry month Element container.
recurly-element-year Styles specific to the card expiry year Element container.
recurly-element-cvv Styles specific to the card cvv Element container.

Custom Fonts

Custom fonts are sourced from Google Web Fonts. Simply use the name of the font as it appears on the Google Web Fonts site.

Responsive Styles

All of the built in element CSS classes will support and respond to media queries. You may call Element.configure to change style properties for an individual Element – thus you may change any property according to your responsive needs.

Getting a Token

Interrupt your form submit to send billing info to Recurly and get a secure token in exchange. Once you have the token, send the token to your server.

const elements = recurly.Elements();

// construct and attach your Elements...

document.querySelector('#my-form').addEventListener('submit', function (event) {
  const form = this;
  event.preventDefault();
  recurly.token(elements, form, function (err, token) {
    if (err) {
      // handle error using err.code and err.fields
    } else {
      // recurly.js has filled in the 'token' field, so now we can submit the
      // form to your server
      form.submit();
    }
  });
});

Recurly.js works with tokens, which represent secure and temporary storage for your customer’s sensitive billing information. They are stored directly on Recurly servers to reduce your PCI exposure.

When your customers submit your billing form, you’ll need to interrupt the submit and ask Recurly.js to create a token from the form. You may have noticed an additional hidden field in the form above, token. When you ask Recurly.js for a token during submit, it will automatically populate this field for you. After you get the token, you will submit it to your servers and use it there to talk to any endpoint in our API that accepts a billing_info.

Reference

fn recurly.token

You must call recurly.token with your Elements instance, and your <form> reference.

recurly.token(elements, document.querySelector('form'), tokenHandler);

Using a handler function like this one:

function tokenHandler (err, token) {
  if (err) {
    // handle error using err.code and err.fields
  } else {
    // handle success using token.id
  }
}

Sends billing information to Recurly to store as a token, sending that token id back to you.

Arguments
Param Type Description
elements Elements An Elements instance referring to the elements group you wish to tokenize.
form HTMLFormElement Parent form containing data-recurly fields.
callback Function Callback function to accept the returned token.

A callback is always required

Callback Arguments
Param Type Description
err RecurlyError or null A RecurlyError if an error occurred; otherwise null.
token Object An object containing a token id.
token.type String ‘credit_card’
token.id String A token id.
Returns

Nothing.

Using a Token

Create a new purchase with a token using one of our client libraries or API v3

Ruby

Node.js

Python

Java

Dotnet

  purchase = {
    currency: "USD",
    account: {
      code: account_code,
      billing_info: {
        token_id: rjs_token_id
      },
    },
    subscriptions: [
      { plan_code: plan_code }
    ]
  }

  invoice_collection = @client.create_purchase(body: purchase)
  let purchaseReq = {
    currency: 'USD',
    account: {
      code: accountCode,
      billingInfo: {
        tokenId: rjsTokenId
      }
    },
    subscriptions: [
      { planCode: planCode },
    ]
  }

  let invoiceCollection = await client.createPurchase(purchaseReq)
  purchase = {
      "currency": "USD",
      "account": {
          "code": account_code,
          "billing_info": {"token_id": rjs_token_id},
      },
      "subscriptions": [{"plan_code": plan_code}],
  }
  invoice_collection = client.create_purchase(purchase)
  PurchaseCreate purchase = new PurchaseCreate();
  purchase.setCurrency("USD");

  AccountPurchase account = new AccountPurchase();
  account.setCode(accountCode);
  purchase.setAccount(account);

  BillingInfoCreate billing = new BillingInfoCreate();
  billing.setTokenId(rjsTokenId);
  account.setBillingInfo(billing);

  List<SubscriptionPurchase> subscriptions = new ArrayList<SubscriptionPurchase>();
  SubscriptionPurchase sub = new SubscriptionPurchase();
  sub.setPlanCode(planCode);
  subscriptions.add(sub);
  purchase.setSubscriptions(subscriptions);

  InvoiceCollection collection = client.createPurchase(purchase);
  const purchaseReq = new PurchaseCreate()
  {
      Currency = "USD",
      Account = new AccountPurchase()
      {
          Code = accountCode,
          BillingInfo = new BillingInfoCreate()
          {
              TokenId = rjsTokenId
          }
      },
      Subscriptions = new List<SubscriptionPurchase>()
      {
          new SubscriptionPurchase() { PlanCode = planCode }
      }
  };

  InvoiceCollection collection = client.CreatePurchase(purchaseReq);

Once Recurly.js has stored your customer’s sensitive data and given you a token reference, you will have 20 minutes to use it in our API. Expired tokens are permanently removed from the Recurly servers. Since tokens may be used to create charges in Recurly, be sure to keep them safe and only transmit them over a secure connection. Note that tokens do not expire after their first use. They can be reused as many times as you need during that 20 minute period.

Tokens expire after 20 minutes.

Tokens can be used to populate any account Billing Info data through our API. Simply assign it to the Billing Info’s token_id property and we’ll do the rest.

These endpoints accept tokens within Billing Info.


Events

Listen to events using the Emitter methods. Any object in this document that emits events may be listened to as follows.

const elements = recurly.Elements();
const card = elements.CardElement();

// Listen to the 'change' event
card.on('change', changeHandler);

// But we're feeling indecisive today. Let's detach this event
card.off('change', changeHandler);

function changeHandler (state) {
  // perform an action
}

Elements

Using Hosted Fields?

Previous versions of Recurly.js utilized a feature called Hosted Fields to render payment fields. This feature is now deprecated, and we recommend upgrading to Elements; however, Recurly.js v4 will maintain backward compatibility with Hosted Fields. See the v4.10.3 documentation for Hosted Fields documentation.

Elements allow sensitive customer payment information to be securely accepted via iframes. They are controlled in groups by an Elements instance.

To use Elements, you will first create an Elements instance.

const elements = recurly.Elements();

There are several types of Elements which you may wish to use. The most common is the CardElement.

const cardElement = elements.CardElement();

Recurly.js also provides individual card Elements.

const cardNumberElement = elements.CardNumberElement();
const cardMonthElement = elements.CardMonthElement();
const cardYearElement = elements.CardYearElement();
const cardCvvElement = elements.CardCvvElement();

The reference below details the common API for interacting with Elements and Element instances. While you may be working with different Element types, their API is the same.

Reference

fn recurly.Elements

Creates an Elements instance, which associates a group of Element instances for tokenization and control. You will use this to create individual Element instances.

const elements = recurly.Elements();

Returns

A new Elements instance

events Emits

See Events for usage.

Event name Payload Occurs When
submit None A user presses enter while using an Element created with the Elements instance.

fn elements.CardElement

fn elements.CardNumberElement

fn elements.CardMonthElement

fn elements.CardYearElement

fn elements.CardCvvElement

Create an Element instance of the type respective of its name.

const cardElement = elements.CardElement({
  style: {
    fontSize: '2em'
  }
});
Arguments
Param Type Description
options Object  
options.inputType String See Styling Elements
options.style Object See Styling Elements
Returns

A new Element instance.

events Emits

See Events for usage.

Event name Payload Occurs When
change ElementState the Element instance state changes.
focus None A user focuses on the Element.
blur None A user removes focus from the Element.
submit None A user presses enter while using the Element.
attach None The Element has completed attaching to the DOM.
remove None The Element has been removed from the DOM.
coBadge CoBadgeResults The user enters a valid card number

fn Element.attach

Attaches an Element to the DOM, as a child of the specified parent target.

element.attach('#my-element-container');
Arguments
Param Type Description
parent HTMLElement or String The HTMLElement to which this Element will be attached. This HTMLElement should NOT be a void HTMLElement. If a String is given, it must correspond to a valid selector on the document as you might pass to document.querySelector.
Returns

The Element instance.

fn Element.configure

Updates the configuration of the Element.

element.configure({
  style: {
    fontSize: '2em'
  }
});
Arguments
Param Type Description
options Object  
options.inputType String See Styling Elements
options.style Object See Styling Elements
Returns

The Element instance.

fn Element.focus

Moves the user’s focus to the Element.

Note: Safari on all devices will only allow focus to be moved to an Element when a user has already interacted with the Element.

Params

None

Returns

The Element instance.

fn Element.remove

If an Element has been attached, removes the Element from the DOM. If it is not attached, does nothing.

Params

None

Returns

The Element instance.


Apple Pay

Use Recurly.js to process Apple Pay transactions

Recurly.js supports Apple Pay out of the box. To get started, ensure your site is configured to accept Apple Pay transactions.

Setting up your Apple Pay integration in Recurly.js involves two parts: a) displaying the button, and b) invoking the purchase flow.

Displaying The Button

Your button styling needs to adhere to Apple’s specifications.

See Apple’s documentation on Displaying the Apple Pay Button for guidelines on display and styling the button.

Invoking The Purchase Flow

Configure a new instance of recurly.ApplePay as follows.

// Handle when the token has been generated to keep the payment sheet in the "Processing"
// state until the onPaymentAuthorized callback has completed
function onPaymentAuthorized({ payment }) {
  const { recurlyToken: token, billingContact, shippingContact } = payment;
  // Submit the token to your server
  console.log('Apple Pay succeeded.',
              'Token:', token.id,
              'billingContact:', billingContact,
              'shippingContact', shippingContact);
}

const applePay = recurly.ApplePay({
  country: 'US',
  currency: 'USD',
  label: 'My Subscription', // This text will be displayed on the Apple Pay payment sheet as "My Subscription"
  total: '29.00',
  callbacks: {
    onPaymentAuthorized,
  }
});

// When the ApplePay instance is ready, bind the Apple Pay button click
// to applePay.begin
applePay.ready(function () {
  $('#my-apple-pay-button').on('click', function () {
    applePay.begin();
  });
});

// Handle errors. These may occur at any point in the Apple Pay flow
applePay.on('error', function (err) {
  // err.code, err.message
  console.error('Apple Pay error', err);
});

ApplePay via Braintree

If you’re processing Apple Pay transactions with Braintree, you’ll pass a client authorization during instantiation:

const applePay = recurly.ApplePay({
  country: 'US',
  currency: 'USD',
  label: 'My Subscription', // This text will be displayed on the Apple Pay payment sheet as "My Subscription"
  total: '29.00',
  callbacks: {
    onPaymentAuthorized,
  }
  braintree: {
    clientAuthorization: MY_CLIENT_AUTHORIZATION
  }
});

Additional configuration

If you are using the recurly.Pricing.Checkout class to calculate checkout prices, you may pass your pricing instance instead of providing a total.

const pricing = recurly.Pricing.Checkout();

const applePay = recurly.ApplePay({
  // ...
  pricing: pricing
});

To provide additional customer data to tokens generated by recurly.ApplePay, you may pass a form reference. recurly.ApplePay will collect customer data from the form just as would occur during credit card tokenization. See Getting a Token for more information on building such a form.

const applePay = recurly.ApplePay({
  // ...
  form: document.querySelector('#my-payment-form')
});

Integration Notes

  • Recurly.js will automatically pull in the billing info from the customer’s Apple account if their Apple Pay setup is complete with full billing information in their Apple Wallet. If the user does NOT have a billing name or address attached to their card in their Apple Wallet, the Apple Pay flow will prompt the customer for a billing address.
  • If you choose to include a Recurly.js payment form, any billing name or address fields entered on that form will replace the billing address in the user’s Apple Wallet on the payment sheet. The user can always change their billing address once the payment sheet has loaded.
  • Integration examples

Reference

fn recurly.ApplePay

Arguments
Param Type Description
options Object  
[options.country] String Your ISO 3166 country code (ex: ‘US’). This is your country code as the merchant. Required if options.paymentRequest.countryCode is not provided.
[options.currency] String ISO 4217 purchase currency (ex: ‘USD’). Required if options.paymentRequest.currencyCode is not provided.
[options.label] String Purchase description to display in the Apple Pay payment sheet. Defaults to “Total”.
[options.total] String Total cost to display in the Apple Pay payment sheet. Defaults to ‘0.00’ if options.pricing and options.paymentRequest.total are not provided.
[options.recurring] Boolean Display the options.total and options.label as a monthly recurring line item in the Apple Pay payment sheet.
[options.pricing] CheckoutPricing If provided, will override options.total and provide the current total price and line items on the CheckoutPricing instance when the Apple Pay flow is initiated.
[options.form] HTMLElement If provided, the Apple Pay payment sheet billing address will be populated by the customer billing address from the form. See Getting a Token for all compatible fields.
[options.enforceVersion] Boolean Requires the user to have the minimum supported browser version for configured payment request features. Currently, this will force the minimum requirements of macOS 10.14.4 and iOS 12.2 if options.paymentRequest.requiredShippingContactFields is set.
[options.callbacks] Object Callbacks to handle the user selection events in the session.
[options.paymentRequest] Object The ApplePayPaymentRequest object. While all fields in the ApplePayPaymentRequest are supported, listed in this table are the overrides for the top level options.
[options.braintree] Object Optional. Braintree configuration.
[options.braintree.clientAuthorization] String If using Braintree to process Apple Pay transactions, provide your client authorization code here.
[options.braintree.displayName] String If using Braintree to process Apple Pay transactions, the name for the store, displayed on the transactions.
ApplePay options.callbacks Arguments
Param Type Description
[options.callbacks.onPaymentMethodSelected] Function Called with the ApplePayPaymentMethodSelectedEvent that should return the ApplePayPaymentMethodUpdate object, a Promise resolving with that update or rejecting with the appropriate error array. The total attribute is added for users that do not wish to support the native newTotal API to simplify the integration.
[options.callbacks.onShippingContactSelected] Function Called with the ApplePayShippingContactSelectedEvent that should return the ApplePayShippingContactUpdate object, a Promise resolving with that update or rejecting with the appropriate error array. The total attribute is added for users that do not wish to support the native newTotal API to simplify the integration.
[options.callbacks.onShippingMethodSelected] Function Called with the ApplePayShippingMethodSelectedEvent that should return the ApplePayShippingMethodUpdate object, a Promise resolving with that update or rejecting with the appropriate error array. The total attribute is added for users that do not wish to support the native newTotal API to simplify the integration.
[options.callbacks.onCouponCodeChanged] Function Called with the ApplePayCouponCodeChangedEvent that should return the ApplePayCouponCodeUpdate, a Promise resolving with that update or rejecting with the appropriate error array. The total attribute is added for users that do not wish to support the native newTotal API to simplify the integration.
[options.callbacks.onPaymentAuthorized] Function Called with the ApplePayPaymentAuthorizedEvent that includes the payment.recurlyToken as the token accepted by Recurly for checkout. Should return undefined, a resolving Promise or a rejecting Promise with the appropriate error array.
ApplePay options.paymentRequest Arguments
Param Type Description
[options.paymentRequest.countryCode] String The ISO 3166 country code. Overrides options.country.
[options.paymentRequest.currencyCode] String The ISO 4217 currency code. Overrides options.currency.
[options.paymentRequest.total] Object The ApplePayLineItem. Overrides the options.total and options.label options for the total line item on the payment sheet.
[options.paymentRequest.supportedNetworks] Array The list of Apple Pay supported networks to be available based on your gateway settings.
[options.paymentRequest.recurringPaymentRequest] Object The ApplePayRecurringPaymentRequest. Overrides the options.total and options.label options if options.recurring is true for the recurring line item on the payment sheet.
[options.paymentRequest.requiredBillingContactFields] Array The list of ApplePayContactField that must be provided in the billing contact. Will always include postalAddress by Recurly.js, regardless if overridden.
Returns

A new recurly.ApplePay instance

fn applePay.ready

Arguments
Param Type Description
callback Function Called when the ApplePay instance has completed initialization. Will immediately invoke if the instance is already initialized. The callback is called with no arguments.
Returns

Nothing.

events Emits
paymentAuthorized

This event is fired when the customer has authorized the payment presented on the Apple Pay payment sheet.

Payload
Param Type Description
event Object The ApplePayPaymentAuthorizedEvent object.
event.payment.recurlyToken.id String Token identifier to be sent to the API.
token

This event is fired when the customer has completed the Apple Pay payment sheet flow. Recurly has received the payment details, and generated this token to be used in our API.

Payload
Param Type Description
token Object  
token.id String Token identifier to be sent to the API
event Object The ApplePayPaymentAuthorizedEvent object.
error

This event is emitted when any error is encountered, whether during setup of the Apple Pay payment sheet, or during payment authorization. It will be useful to display errors to your customer if a problem occurs during the Apple Pay flow.

Payload
Param Type Description
error RecurlyError An error describing the issue that occurred.

Google Pay ™

Use Recurly.js to process Google Pay transactions.

To get started, ensure your Payment Gateway is configured to accept Google Pay transactions.

Invoking The Purchase Flow

Configure a new instance of recurly.GooglePay as follows.

// Handle when the token has been generated to keep the payment sheet in the "Processing"
// state until the onPaymentAuthorized callback has completed
function onPaymentAuthorized(paymentData) {
  const { recurlyToken: token } = paymentData;
  // Submit the token to your server
  console.log('Google Pay succeeded.',
              'Token:', token.id,
              'PaymentData:', paymentData);
}

const googlePay = recurly.GooglePay({
  currency: 'USD',
  country: 'US',
  total: '10',
  googleMerchantId: 'GOOGLE_MERCHANT_ID',
  billingAddressRequired: true,
  callbacks: {
    onPaymentAuthorized,
  },
});

// When the GooglePay instance is ready, attach the Google Pay Button to the DOM
googlePay.on('ready', function (googlePayButton) {
  $('#google-pay-button-container').appendChild(googlePayButton);
});

// Handle errors. These may occur at any point in the Google Pay flow
googlePay.on('error', function (err) {
  // err.code, err.message
  console.error('Google Pay error', err);
});

Additional configuration

To provide additional customer data to tokens generated by recurly.GooglePay, you may pass a form reference. recurly.GooglePay will collect customer data from the form just as would occur during credit card tokenization. See Getting a Token for more information on building such a form.

const googlePay = recurly.GooglePay({
  // ...
  form: document.querySelector('#my-payment-form')
});

If you choose to include a Recurly.js payment form, any billing name or address fields entered on that form will be used instead of the address in the user’s Google Pay info; the token request will contain the fields entered on the payment form. If the form is completely empty of name and address inputs, the token request will contain the name and address chosen by the user during the Google Pay flow.

Integration Examples

Reference

fn recurly.GooglePay

Arguments
Param Type Description
options Object  
[options.country] String Your ISO 3166 country code (ex: 'US'). This is your country code as the merchant. Required if options.paymentDataRequest.transactionInfo.countryCode is not provided.
[options.currency] String ISO 4217 purchase currency (ex: 'USD'). Required if options.paymentDataRequest.transactionInfo.currencyCode is not provided.
[options.total] String Total cost to display in the Google Pay payment sheet. Required if options.paymentDataRequest.transactionInfo.total is not provided.
[options.googleMerchantId] String Your Google Account Merchant ID. Required if options.paymentDataRequest.merchantInfo.merchantId is not provided.
[options.googleBusinessName] String Your Google Business name.
[options.environment] String The Google Pay Environment 'TEST' or 'PRODUCTION'. This value is automatically deduced from your Recurly Site mode, but you can always overwrite it.
[options.buttonOptions] Object The Google Pay Button Options.
[options.billingAddressRequired] Boolean Requires the User Billing Address in the Google Pay Payment. Not needed if options.form with the billing address is provided.
[options.existingPaymentMethodRequired] Boolean Requires the User to have a configured payment method in their wallet, otherwise will return a google-pay-not-available error.
[options.form] HTMLElement If provided, tokens generated will include customer billing address from the form, overriding any billing address gathered from Google Pay.
[options.gatewayCode] String Specify which Payment Gateway in Recurly must process the Payment.
[options.callbacks] Object Callbacks to handle the events in the session.
[options.paymentDataRequest] Object The PaymentDataRequest object. While all fields in the PaymentDataRquest are supported, listed in this table are the overrides for the top level options.
Google Pay options.callbacks Arguments
Param Type Description
[options.callbacks.onPaymentDataChanged] Function Pass through to the native callback
[options.callbacks.onPaymentAuthorized] Function Called with the PaymentData, including the recurlyToken. Should return a resolving Promise or a rejecting Promise with the appropriate error.
Google Pay options.paymentDataRequest Arguments
Param Type Description
[options.paymentDataRequest.merchantInfo] Object The MerchantInfo. Can override the options.googleMerchantId and options.googleBusinessName options.
[options.paymentDataRequest.transactionInfo] Object The TransactionInfo. Can override the options.total, options.currency and options.country options.

It is not required to set options.paymentDataRequest.callbackIntents. They are automatically configured based on the options.callbacks and required options.paymentDataRequest counterparts provided.

Returns

A new recurly.GooglePay instance

events Emits
ready

This event is fired when the GooglePay instance has completed initialization and the Customer is ready to Pay.

Payload
Param Type Description
button HTMLElement The Google Pay button already setup.
paymentAuthorized

This event is fired when the customer has authorized the payment presented on the Apple Pay payment sheet.

Payload
Param Type Description
paymentData Object The PaymentData object.
paymentData.recurlyToken.id String Token identifier to be sent to the API.
token

This event is fired when the customer has completed the Google Pay payment sheet flow. Recurly has received the payment details, and generated this token to be used in our API.

Payload
Param Type Description
token Object  
token.id String Token identifier to be sent to the API
error

This event is emitted when any error is encountered, whether during setup of the Google Pay payment sheet, or during payment authorization. It will be useful to display errors to your customer if a problem occurs during the Google Pay flow.

Payload
Param Type Description
error RecurlyError An error describing the issue that occurred.

US Bank Accounts

Tokenize your users’ bank account information

Just as with a card form, use the data-recurly attribute to identify fields to Recurly.js. Since Recurly.js does not need to inject fields for bank accounts, all fields may be displayed as inputs on your payment form.

<form>
  <input type="text" data-recurly="routing_number">
  <input type="text" data-recurly="account_number">
  <input type="text" data-recurly="account_number_confirmation">
  <input type="text" data-recurly="account_type">
  <input type="text" data-recurly="name_on_account">
  <input type="hidden" name="recurly-token" data-recurly="token">
  <button>submit</button>
</form>

US Bank Account inputs

Field Name Example Description
routing_number 123456789 Routing number. Required
account_number 987654321 Account number. Required
account_number_confirmation 987654321 Account number confirmation. Required
account_type checking or savings Account type. Required
name_on_account Pat Smith Full name on account. Required

Getting a Token

fn recurly.bankAccount.token

You may call recurly.bankAccount.token with a form element:

recurly.bankAccount.token(document.querySelector('form'), tokenHandler);

Or with an Object:

const billingInfo = {
  // required attributes
  routing_number: '123456780',
  account_number: '111111111',
  account_number_confirmation: '111111111',
  account_type: 'checking',
  name_on_account: 'Pat Smith',

  // optional attributes
  address1: '123 Main St.',
  address2: 'Unit 1',
  city: 'Hope',
  state: 'WA',
  postal_code: '98552',
  country: 'US',
  vat_number: 'SE0000'
};

recurly.bankAccount.token(billingInfo, tokenHandler);

Both methods require using a handler function like this one:

function tokenHandler (err, token) {
  if (err) {
    // handle error using err.code and err.fields
  } else {
    // handle success using token.id
  }
}

This sends bank account billing information to Recurly to store as a token, returning that token id back to you via callback.


International Bank Accounts (IBAN)

Tokenize your users’ International Bank Account (IBAN) information in order to process SEPA transactions.

Similar to configuring a card form, use the data-recurly attribute to identify IBAN specific inputs. Since Recurly.js does not need to inject fields for bank accounts, all fields may be displayed as inputs on your payment form.

<form>
  <input type="text" data-recurly="name_on_account">
  <input type="text" data-recurly="iban">
  <input type="text" data-recurly="country">
  <input type="hidden" name="recurly-token" data-recurly="token">
  <button>submit</button>
</form>

IBAN inputs

Field Name Example Description
name_on_account Pat Smith Full name on account. Required
iban GB33BUKB20201555555555 The International Bank Account Number, up to 34 alphanumeric characters comprising a country code, two check digits, and a number that includes the domestic bank account number, branch identifier, and potential routing information. (SEPA only) Required
country FR ISO 3166 two-letter country code. This code must match a country in the European Union (EU) Required

Getting a Token

fn recurly.bankAccount.token

You may call recurly.bankAccount.token with a form element:

recurly.bankAccount.token(document.querySelector('form'), tokenHandler);

Or with an Object:

const ibanBillingInfo = {
  name_on_account: 'Pat Smith',
  iban: 'GB33BUKB20201555555555',
  country: 'GB'
};

recurly.bankAccount.token(ibanBillingInfo, tokenHandler);

Both methods require using a handler function like this one:

function tokenHandler (err, token) {
  if (err) {
    // handle error using err.code and err.fields
  } else {
    // handle success using token.id
  }
}

This sends IBAN information to Recurly to store as a token, returning that token id back to you via callback.

UK Bank Accounts (Bacs)

Tokenize your users’ UK based Bank Account (Bacs) information in order to process Bacs transactions.

Similar to configuring a card form, use the data-recurly attribute to identify Bacs specific inputs. Since Recurly.js does not need to inject fields for bank accounts, all fields may be displayed as inputs on your payment form.

<form>
  <input type="text" data-recurly="sort_code">
  <input type="text" data-recurly="account_number">
  <input type="text" data-recurly="account_number_confirmation">
  <input type="hidden" name="type" value="bacs" data-recurly="type">
  <input type="text" data-recurly="name_on_account">
  <input type="hidden" name="recurly-token" data-recurly="token">
  <button>submit</button>
</form>

UK Bank Account (Bacs) inputs

Field Name Example Description
sort_code 200000 UK Sort Code. Required
account_number 55779911 Account number. Required
account_number_confirmation 55779911 Account number confirmation. Required
type bacs Account type. Required
name_on_account Charles George Full name on account. Required

Getting a Token

fn recurly.bankAccount.token

You may call recurly.bankAccount.token with a form element:

recurly.bankAccount.token(document.querySelector('form'), tokenHandler);

Or with an Object:

const bacsBillingInfo = {
  name_on_account: 'Charles George',
  account_number: '55779911',
  account_number_confirmation: '55779911',
  sort_code: '200000',
  type: 'bacs'
};

recurly.bankAccount.token(bacsBillingInfo, tokenHandler);

Both methods require using a handler function like this one:

function tokenHandler (err, token) {
  if (err) {
    // handle error using err.code and err.fields
  } else {
    // handle success using token.id
  }
}

This sends Bacs information to Recurly to store as a token, returning that token id back to you via callback.

Arguments (form)

Param Type Description
form HTMLFormElement Parent form containing data-recurly fields
callback Function Callback function to accept the returned token

Alternatively, you can call recurly.bankAccount.token with a plain JavaScript object. This allows a more direct interface to the payment flow, eliminating any need to use the DOM.

Arguments (object)

Param Type Description
options Object An object with billing information properties matching those [outlined above].
callback Function Callback function to accept the returned token

A callback is always required

Callback Arguments

Param Type Description
err RecurlyError or null A RecurlyError if an error occurred; otherwise null.
token Object An object containing a token id.
token.type String ‘bank_account’
token.id String A token id.

Returns

Nothing.


Australian Bank Accounts (Becs)

Tokenize your users’ Australian based Bank Account (Becs) information in order to process Becs transactions.

Similar to configuring a card form, use the data-recurly attribute to identify Becs specific inputs. Since Recurly.js does not need to inject fields for bank accounts, all fields may be displayed as inputs on your payment form.

<form>
  <input type="text" data-recurly="bsb_code">
  <input type="text" data-recurly="account_number">
  <input type="text" data-recurly="account_number_confirmation">
  <input type="hidden" name="type" value="becs" data-recurly="type">
  <input type="text" data-recurly="name_on_account">
  <input type="hidden" name="recurly-token" data-recurly="token">
  <button>submit</button>
</form>

Australian Bank Account (Becs) inputs

Field Name Example Description
bsb_code 082902 Australian BSB Code. Required
account_number 55779911 Account number. Required
account_number_confirmation 55779911 Account number confirmation. Required
type becs Account type. Required
name_on_account Charles George Full name on account. Required

Getting a Token

fn recurly.bankAccount.token

You may call recurly.bankAccount.token with a form element:

recurly.bankAccount.token(document.querySelector('form'), tokenHandler);

Or with an Object:

const becsBillingInfo = {
  name_on_account: 'Charles George',
  account_number: '55779911',
  account_number_confirmation: '55779911',
  bsb_code: '082902',
  type: 'becs'
};

recurly.bankAccount.token(becsBillingInfo, tokenHandler);

Both methods require using a handler function like this one:

function tokenHandler (err, token) {
  if (err) {
    // handle error using err.code and err.fields
  } else {
    // handle success using token.id
  }
}

This sends Becs information to Recurly to store as a token, returning that token id back to you via callback.

Arguments (form)

Param Type Description
form HTMLFormElement Parent form containing data-recurly fields
callback Function Callback function to accept the returned token

Alternatively, you can call recurly.bankAccount.token with a plain JavaScript object. This allows a more direct interface to the payment flow, eliminating any need to use the DOM.

Arguments (object)

Param Type Description
options Object An object with billing information properties matching those [outlined above].
callback Function Callback function to accept the returned token

A callback is always required

Callback Arguments

Param Type Description
err RecurlyError or null A RecurlyError if an error occurred; otherwise null.
token Object An object containing a token id.
token.type String ‘bank_account’
token.id String A token id.

Returns

Nothing.


Online Banking

Use Recurly.js to process Online Banking transactions.

Every Online Banking purchase requires an invoice uuid created from a Pending Purchase operation through the Recurly API.

Alternative payment methods

We accept three types of alternative payment methods: Boleto, iDEAL, and Sofort. Each of these payment methods share almost the same implementation, with some differences in the initial configuration and some other parameters.

Configuration

To start with any of these payment methods, you must first configure the Recurly.js client by passing recurly.AlternativePaymentMethods an object with the following parameters:

Param Type Description
allowedPaymentMethods Array An array containing the desired payment method.
blockedPaymentMethods Array An array containing the payment methods that will be blocked.
containerSelector String String containing the CSS selector of the container.
amount Integer The amount to be paid.
currency String The currency for the transaction.
locale String The locale for the transaction.
channel String The channel.
adyen Object An object containing adyen gateway configuration.
adyen.publicKey String The public key.
adyen.env String The environment.
adyen.showPayButton Boolean Whether to show or not the pay button.
componentConfig Object An object with the component configuration.
returnURL String Return URL (needed only for iDEAL and Sofort).

An example of the configuration object is shown below:

const paymentMethod = recurly.AlternativePaymentMethods({
  allowedPaymentMethods: [
    "boleto"
  ],
  blockedPaymentMethods: [],
  containerSelector: "#payment-methods-container",
  amount: 10,
  currency: "BRL",
  countryCode: "BR",
  locale: "en-US",
  channel: "Web",
  adyen: {
    publicKey: 'adyen_public_key',
    env: "test",
    showPayButton: false,
    componentConfig: {}
  },
  returnURL: 'https://return-url.com/success',
});

The differences in configuration for each payment method are shown below:

Boleto

Param Type Description
allowedPaymentMethods Array Array needs to contain boleto.
currency String String needs to be BRL.
countryCode String String needs to be BR

iDEAL

Param Type Description
allowedPaymentMethods Array Array needs to contain ideal.
currency String String needs to be EUR.
countryCode String String needs to be NL
returnURL String The return url is required for iDEAL.

Sofort

Param Type Description
allowedPaymentMethods Array Array needs to contain sofort.
currency String String should have one of the following currencies: EUR, CHF
countryCode String String should have one of the following values: AT, BE, DE, ES, CH, NL
returnURL String The return url is required for Sofort.

Generating a token

After configuring your recurly instance, a container will be shown within the element specified in the configuration. After filling the data and confirm, paymentMethod.submit() should be called so that the token event can be dispatched.

  document.querySelector('#payment-methods-pay').addEventListener('click', function () {
    paymentMethod.submit();
  });

After calling submit, the token will be emitted in the token event.

  paymentMethod.on('token', function (token) {
    document.querySelector('[data-recurly=token]').value = token.id;
    // ...
  });

Making a purchase

Having the token, a request must be sent to the server, which internally will call the Recurly API to make the purchase. The request must contain the fields from the previously filled in the element container. The response must then be handled to retrieve the action_result and pass it back to the browser. With the action result, paymentMethod.handleAction(action_result) can be called.

  const form = document.querySelector('form')

  fetch(form.action, {
    method: form.method,
    body: new FormData(form),
  })
    .then(response => response.json())
    .then(data => {
      console.log({ data })
      if (data.error) {
        alert(data.error);
      } else if (data.action_result) {
        paymentMethod.handleAction(data.action_result)
      }
    })
    .catch(err => {
      console.error(err);
      notifyErrors([err]);
    });

PayPal

Use Recurly to process PayPal transactions using PayPal Business, PayPal Complete or Braintree.

A PayPal transaction is handled entirely within the PayPal checkout flow in a new window. Your customer will authorize a transaction within PayPal. Recurly will then record the authorization and return a Recurly token to you as it does for other payment methods.

You will need to use the token within our API before it expires, and expired tokens cannot be retrieved.

First, place a button on your page specifically for checking out with PayPal.

<button>Checkout with PayPal</button>

Next, create a new recurly.PayPal instance

const paypal = recurly.PayPal({
  display: { displayName: ' My product ' }
});

If you’re processing PayPal transactions with Braintree, you’ll pass a client authorization during instantiation:

const paypal = recurly.PayPal({
  braintree: { clientAuthorization: MY_CLIENT_AUTHORIZATION }
});

If you’re processing PayPal transactions with PayPal Complete, you’ll need to pass a payPalComplete flag:

const paypal = recurly.PayPal({
  payPalComplete: true
});

Your instance must then be setup to handle error scenarios and start the checkout flow.

paypal.on('error', function (err) {
  // err.code
  // err.message
  // [err.cause] if there is an embedded error
});

Next we must bind a listener to a user action on the button and have it trigger the start function on your recurly.PayPal instance. This will open the PayPal checkout flow.

As with the rest of Recurly.js, there are no external dependencies. The example uses jQuery to demonstrate binding events, but this can be done any way you wish.

$('#paypal-button').on('click', function () {
  paypal.start();
});

The start function must be called within a user-initiated event like ‘click’ or ‘touchend’

Finally, add a function to receive the token once your customer completes the checkout flow. At this point you will send the token id to your server to be used in the Recurly API to create a billing info for an account.

For PayPal Business and Braintree the token also includes the email and payer_id of the billing agreement. For PayPal Complete the token contains only a id to be used in the Recurly API.

paypal.on('token', function (token) {
  // token.id
  // token.email
  // token.payer_id
});

Reference

fn recurly.PayPal

Arguments
Param Type Description
options Object Optional.
options.braintree Object Optional. Braintree configuration.
options.braintree.clientAuthorization String If using Braintree to process PayPal transactions, provide your client authorization code here.
options.payPalComplete Boolean Optional. If using PayPal Complete to process PayPal transactions, pass true here.
Returns

A new PayPal instance

fn payPal.start

Arguments
Param Type Description
options Object Optional.
options.description String Optional. In legacy PayPal flows, this description will be displayed during the checkout flow.
Returns

Nothing.

events Emits

error

This event is emitted when any error is encountered, whether during setup of the PayPal flow, or during the checkout process. It will be useful to display errors to your customer if a problem occurs during PayPal checkout.

Payload
Param Type Description
error RecurlyError An error describing the issue that occurred.
cancel

This event is emitted when the customer has canceled the PayPal checkout flow before completion. You may wish to reset parts of your checkout experience if this occurs.

Payload

None.

token

This event is fired when the customer has completed the PayPal checkout flow. Recurly has received the payment details, and generated this token to be used in our API.

Payload
Param Type Description
token Object  
token.type String ‘paypal’
token.id String Token identifier to be sent to the API
token.email String The email of the customer.
token.payer_id String The unique identifier of the customer PayPal account.

Venmo

Use Recurly to process Venmo transactions.

A Venmo transaction is handled entirely within the Venmo checkout flow in a new window. Your customer will authorize a transaction within Venmo. Recurly will then record the authorization and return a Recurly token to you as it does for other payment methods.

You will need to use the token within our API before it expires, and expired tokens cannot be retrieved.

If you wish to make the first and last name fields optional for Venmo tokens through our API, please contact Recurly support to have us enable this feature.

First, place a button on your page specifically for checking out with Venmo.

<button id="venmo-button">Pay with Venmo</button>

Next, create a new recurly.Venmo instance

const venmo = recurly.Venmo({
  display: {
      amount: '100.55',
      currency: 'USD',
      displayName: 'Display Name',
      locale: 'en_US',
    }
});

If you’re processing Venmo transactions with Braintree, you’ll pass a client authorization and a web authentication flag during instantiation:

const venmo = recurly.Venmo({
  braintree: { clientAuthorization: MY_CLIENT_AUTHORIZATION, webAuthentication: true }
});

Braintree strongly recommends enabling the web authentication flag as it offers a better customer experience and improves conversion rates.

Your instance must then be setup to handle error scenarios.

venmo.on('error', function (err) {
  // err.code
  // err.message
  // [err.cause] if there is an embedded error
});

Next we must bind a listener to a user action on the button and have it trigger the start function on your recurly.Venmo instance. This will open the Venmo checkout flow.

As with the rest of Recurly.js, there are no external dependencies. The example uses jQuery to demonstrate binding events, but this can be done any way you wish.

$('#venmo-button').on('click', function () {
  venmo.start();
});

The start function must be called within a user-initiated event like ‘click’ or ‘touchend’

Finally, add a function to receive the token once your customer completes the checkout flow. At this point you will send the token id to your server to be used in the Recurly API to create a billing info for an account.

venmo.on('token', function (token) {
  // token.id
});

Reference

fn recurly.Venmo

Arguments
Param Type Description
options Object Optional.
options.braintree Object Optional. Braintree configuration.
options.braintree.clientAuthorization String If using Braintree to process Venmo transactions, provide your client authorization code here.
Returns

A new Venmo instance

fn venmo.start

Arguments
Param Type Description
options Object Optional.
Returns

Nothing.

events Emits

error

This event is emitted when any error is encountered, whether during setup of the Venmo flow, or during the checkout process. It will be useful to display errors to your customer if a problem occurs during Venmo checkout.

Payload
Param Type Description
error RecurlyError An error describing the issue that occurred.
cancel

This event is emitted when the customer has canceled the Venmo checkout flow before completion. You may wish to reset parts of your checkout experience if this occurs.

Payload

None.

token

This event is fired when the customer has completed the Venmo checkout flow. Recurly has received the payment details, and generated this token to be used in our API.

Payload
Param Type Description
token Object  
token.type String ‘VenmoAccount’
token.id String Token identifier to be sent to the API

Amazon Pay v2

Use Recurly to process Amazon Pay v2 transactions

Recurly recommends the use of the renderButton function to display Amazon’s Amazon Pay button on your page. To do this you will need to place a div` element on your page where you intend to have the button rendered.

<div id="amazon-pay-button">Pay with Amazon Pay</div>

Next, create a new recurly.AmazonPay instance and pass the correct region for your Amazon Pay account. An options object param can be added to pass the account region. If not provided, it will default to ‘us’.

const amazonPay = recurly.AmazonPay();

If you are rendering the Amazon Pay button, add a listener for the ready event and call the renderButton function, passing the id of the element.

amazonPay.on('ready', () => {
  amazonPay.renderButton('amazon-pay-button')
});

Your instance must then be setup to handle error scenarios.

amazonPay.on('error', function (err) {
  // err.code
  // err.message
  // [err.cause] if there is an embedded error
});

Next, a listener must be bound to a user action on the button and have it trigger the attach function on your recurly.AmazonPay instance. This will open the Amazon Pay checkout flow in a new window.

As with the rest of Recurly.js, there are no external dependencies. The example uses jQuery to demonstrate binding events, but this can be done any way you wish.

$('#amazon-pay-container').on('click', function () {
  amazonPay.attach();
});

The attach function must be called within a user-initiated event like ‘click’ or ‘touchend’

Finally, add a function to receive the token once your customer completes the checkout flow. At this point you will send the token id to your server to be used in the Recurly API to create a billing info for an account.

amazonPay.on('token', function (token) {
  // token
});

Reference

fn recurly.AmazonPay

Arguments
Param Type Description
options Object Conditional
options.region String The region for the account. Can be ‘us’, ‘eu’ or ‘uk’. If is not provided, it will default to ‘us’
options.gatewayCode String If it is not provided, it will default to the inital Amazon Pay V2 gateway
Returns

A new AmazonPay instance

fn amazonPay.renderButton

Arguments
Param Type Description
element id string Required. The id of the amazon container
Returns

A promise.

fn amazonPay.attach

Returns

An error or a token.

events Emits

error

This event is emitted when any error is encountered, whether during setup of the Amazon Pay flow, or during the checkout process. It will be useful to display errors to your customer if a problem occurs during Amazon Pay checkout.

Payload
Param Type Description
error RecurlyError An error describing the issue that occurred.
closed

This event is emitted when the customer has closed the Amazon Pay checkout flow before completion. You may wish to reset parts of your checkout experience if this occurs.

Payload

None.

ready

This event is emitted when the Amazon Pay script has loaded onto your page. This script must load before you can call the renderButton function.

Payload

None.

token

This event is fired when the customer has completed the Amazon Pay checkout flow. Recurly has received the payment details, and generated this token to be used in our API.

Payload
Param Type Description
token Object  
token.type String ‘amazon_pay’
token.id String Token identifier to be sent to the API

Pricing

Recurly automates complicated subscriptions, with many factors influencing the total price at checkout. With this in mind, Recurly.js provides a robust recurly.Pricing.Checkout class designed to make determining the actual checkout costs as simple and flexible as possible.

A Recurly.js checkout pricing instance can be attached to the form we created above, or to any other section of your page meant to display pricing.

Reference

fn recurly.Pricing.Checkout

const checkoutPricing = recurly.Pricing.Checkout();

Creates a CheckoutPricing instance.

No Arguments
Returns

A new CheckoutPricing instance.

fn CheckoutPricing.attach

Given the following example HTML structure

<section id="my-checkout">
  <select data-recurly="plan">
    <option value="basic">Basic</option>
    <option value="notbasic">Not Basic</option>
  </select>
  <input type="text" data-recurly="coupon">
</section>

Use checkoutPricing.attach to bind the <section> to the checkout pricing calculator.

const checkoutPricing = recurly.Pricing.Checkout();

checkoutPricing.attach('#my-checkout');

This is the simplest way to use a CheckoutPricing instance. Simply pass a container element, and the CheckoutPricing instance will use all elements with a valid data-recurly attribute to determine price. When a value changes, the CheckoutPricing instance will automatically update its calculations. This allows your customers to manipulate your checkout form at will, and have your checkout page’s prices update automatically.

Arguments
Param Type Description
container HTMLElement or String Parent element containing all data-recurly elements. If a String is passed, it will be parsed with document.querySelector
Returns

Nothing.

HTMLElements

HTMLElements bound to a CheckoutPricing instance may be for either input or output.

Input HTMLElements

Input elements should be user-manipulable elements like input or select. If you want to input a value but not let a customer manipulate it, use an <input type="hidden">.

Subscriptions

CheckoutPricing instances can calculate a checkout containing one or more subscriptions. The table below lists all available input HTMLElement types.

data-recurly value Example Value Description
plan basic Plan code.
plan_quantity 1 Plan quantity. Defaults to 1 if not specified
addon 1 Addon quantity. To identify the addon being modified, use the data-recurly-addon attribute to set the addon code.
tax_code digital Product tax code.

If you would like to calculate multiple subscriptions on a single checkout, group the values for each subscription using the data-recurly-subscription attribute. Simply set them to a unique id to group them. Here’s an example:

<section id="my-checkout">
  Subscription 1
  <select data-recurly="plan" data-recurly-subscription="0">
    <option value="basic">Basic</option>
    <option value="notbasic">Not Basic</option>
  </select>

  Subscription 1 Add-ons
  <span data-recurly="addon_price" data-recurly-subscription="0" data-recurly-addon="my_addon_code_1"></span>
  <input type="text" data-recurly="addon" data-recurly-subscription="0" data-recurly-addon="my_addon_code_1" value="0">

  Subscription 2
  <select data-recurly="plan" data-recurly-subscription="1">
    <option value="basic">Basic</option>
    <option value="notbasic">Not Basic</option>
  </select>
  <input type="hidden" data-recurly="tax_code" data-recurly-subscription="1" value="my_tax_code_0">
</section>
Adjustments

As with subscriptions, CheckoutPricing instances can calculate a checkout containing one or more adjustments.

Using an item code

You may specify an item code from your Recurly catalog. This will automatically retrieve the pricing information for your item.

data-recurly value Example Value Description
adjustment 0, 1 Adjustment quantity.

Set a unique identifier using data-recurly-adjustment.

Set the item code using data-recurly-adjustment-item-code.

Example:

<section id="my-checkout">
  My product
  x
  <input type="text"
         data-recurly="adjustment"
         data-recurly-adjustment="my-adjustment-0"
         data-recurly-adjustment-item-code="my-item-code"
         value="0">
</section>


Specifying adjustment properties inline

It’s also possible to specify all adjustment values inline.

data-recurly value Example Value Description
adjustment 0, 1 Adjustment quantity.

Set a unique identifier using data-recurly-adjustment.

Set the amount using data-recurly-adjustment-amount,

currency with data-recurly-adjustment-currency,

tax code with data-recurly-adjustment-tax-code,

and tax exempt status with data-recurly-adjustment-tax-exempt.

Example:

<section id="my-checkout">
  $10 adjustment
  x
  <input type="text"
         data-recurly="adjustment"
         data-recurly-adjustment="my-adjustment-0"
         data-recurly-adjustment-amount="10"
         data-recurly-adjustment-currency="USD"
         data-recurly-adjustment-tax-code="my_tax_code_1"
         data-recurly-adjustment-tax-exempt="false"
         value="0">

  $2.99 adjustment
  <input type="checkbox"
         data-recurly="adjustment"
         data-recurly-adjustment="my-adjustment-1"
         data-recurly-adjustment-amount="2.99"
         data-recurly-adjustment-currency="USD"
         data-recurly-adjustment-tax-code="my_tax_code_2"
         data-recurly-adjustment-tax-exempt="true"
         value="1">
</section>
Other
data-recurly value Example Value Description
coupon 15_off Coupon code.
currency USD ISO-4217 currency code.
country US ISO 3166-1 alpha-2 country code.
postal_code 90210 Customer postal code. Used primarily to compute taxes.
vat_number SE0000 Customer VAT number. Used for VAT exclusion.
tax_amount.now ‘0.99’ Specific tax amount to apply to the amount due now. Supplying this value will disable automated tax calculations.
tax_amount.next ‘1.99’ Specific tax amount to apply to the next billing cycle cost. Supplying this value will disable automated tax calculations.
gift_card 518822D87268C142 Gift card’s redemption code.
Output HTMLElements

Output elements should be plain text elements like output, span, or div.

data-recurly value Example Value Description
total_now 100.00 Total subscription cost due now.
subtotal_now 90.00 Subtotal of the following pricing components.
subscriptions_now 80.00 Total cost of all subscriptions. This is part of the subtotal.
adjustments_now 10.00 Total cost of all adjustments. This is part of the subtotal.
discount_now 5.00 Amount discounted with coupon use.
taxes_now 15.00 Total subscription taxation.
gift_card_now 75.00 The gift card amount that will be applied to the purchase today.
gift_card_next 25.00 The remainder gift card amount that will be applied to the next renewal.
currency_code USD, EUR ISO-4217 currency code.
currency_symbol $, Symbolic representation of currency_code.

data-recurly values ending in _now like subtotal_now have counterparts ending in _next. As you might expect, these correspond to the next billing cycle cost. These values are especially useful for subscriptions with trial periods.

events Emits

CheckoutPricing instances emit events when various values are set or the price changes. See Events for usage.

Event name Payload Occurs When
change PricingState The price changes for any reason.
set.subscription Subscription object A subscription is added to the checkout.
set.plan Plan object A plan is set on any subscription.
set.addon Addon object An addon is set on any subscription.
set.adjustment Adjustment object An adjustment is added to the checkout.
set.address Address object The user’s address is changed on the checkout. This is limited to country, postalCode, and vatNumber.
set.shippingAddress Address object The user’s shipping address is changed on the checkout. This is limited to country, postalCode, and vatNumber.
set.tax Tax properties object Tax properties are changed on the checkout.
set.currency Currency code The currency is set on the checkout.
set.coupon Coupon object A valid coupon is set on the checkout.
unset.coupon Coupon object An existing valid coupon is removed from the checkout.
error.coupon RecurlyError A requested coupon code is invalid.
set.gift_card Gift card object A gift card is set on the checkout.
unset.gift_card Nothing A gift card is removed from the checkout.

CheckoutPricing API

A CheckoutPricing instance can be manipulated with a set of direct method calls. This is useful if you would like to set up a complex pricing schema for your customers, or would just like to use a more programmatic method of determining checkout price. Events fire just as they normally would when using CheckoutPricing.attach.

Note that Recurly.js’s DOM binding is one-way. Thus if you use the CheckoutPricing API on a pricing instance already attached to a container, the elements within will not update with your CheckoutPricing API calls. If you would like two-way DOM binding, we suggest using the CheckoutPricing API without attaching it to a container. If using React, consider using our react-recurly library, which contains a custom hook for interacting with the CheckoutPricing API.

The example below demonstrates all the ways that a CheckoutPricing instance can be manipulated directly.

const checkoutPricing = recurly.Pricing.Checkout();

// Add a $10 adjustment
checkoutPricing
  .adjustment({
    id: '0',
    itemCode: 'my-item-code',
    quantity: 1,
  })
  .adjustment({
    id: '1',
    amount: 10.0,
    quantity: 1,
    taxExempt: true,
    taxCode: 'my-tax-code'
  })
  .coupon('my-coupon-code')
  .giftCard('my-gift-card-code')
  .address({
    country: 'US',
    postal_code: '90210'
  })
  .tax({
    tax_code: 'digital',
    vat_number: '',
    amounts: {
      now: '0.99',
      next: '1.99'
    }
  })
  .subscription(recurly.Pricing.Subscription()
    .plan('basic', { quantity: 1 })
    .addon('addon1', { quantity: 2 })
    .catch(function (err) {
      // err.code
    })
    .done()
  )
  .catch(function (err) {
    // err.code
  })
  .done(function (price) {
    // price object as emitted by 'change' event
  });

PricingPromise

Each CheckoutPricing method will return a PricingPromise. This allows you to chain many asynchronous calls together without having to manage a complex series of callbacks.

You don’t need to worry much about the internals of a PricingPromise, as it is designed to stay out of your way and facilitate asynchronous calls for you.

The catch method, as shown in the example, is used to handle error scenarios, such as when an addon cannot be applied to the selected plan.

At the end of a chain of pricing method calls, be sure to call .done() as this tells the Pricing instance to begin calculating, and gives you the subscription price.

Example PricingState Object

emitted by the change event

{
  currency: {
    code: 'USD',
    symbol: '$'
  },
  now: {
    adjustments: '20.00',
    discount: '0.00',
    giftCard: '0.00',
    items: [
      {
        addons: '0.00',
        amount: '10.00',
        id: '0',
        plan: '10.00',
        setupFee: '0.00',
        type: 'subscription'
      },
      {
        amount: '20.00',
        id: 'adj-0',
        quantity: '2.00',
        type: 'adjustment',
        unitAmount: '10.00'
      }
    ],
    subscriptions: '10.00',
    subtotal: '30.00',
    taxes: '0.00',
    total: '30.00'
  },
  next: {
    adjustments: '0.00',
    discount: '0.00',
    giftCard: '0.00',
    items: [
      {
        addons: '0.00',
        amount: '10.00',
        id: '0',
        plan: '10.00',
        setupFee: '0.00',
        type: 'subscription'
      }
    ],
    subscriptions: '10.00',
    subtotal: '10.00',
    taxes: '0.00',
    total: '10.00'
  },
  taxes: []
}

3D-Secure

Strong customer authentication for your users.

Recurly.js provides a set of utilities that allow you to support 3-D Secure authentication on your checkout page seamlessly. For more information on 3-D Secure, see our Introduction to Strong Customer Authentication.

Recurly’s support for 3-D Secure utilizes both Recurly.js and our API. For a complete guide to this integration, start with our Strong Customer Authentication (SCA) Integration Guide.

Let’s take a look at an example implementation.

const risk = recurly.Risk();
const threeDSecure = risk.ThreeDSecure({
  actionTokenId: myActionTokenId
});

threeDSecure.on('token', function (token) {
  // handle passing the action result
  // token back to your server

  // token.type => 'three_d_secure_action_result'
  // token.id

  // optionally, you may call threeDSecure.remove() to remove the element
});

threeDSecure.on('error', function (error) {
  // handle error scenarios.

  // error.code
  // error.message

  // optionally, you may call threeDSecure.remove() to remove the element
});

threeDSecure.attach(document.querySelector('#my-auth-container'));

Additional Configuration

Some gateways such as World Pay and Cybersouce, have API calls as a part of their device fingerprinting required for 3DS2. By default if you have Cybersource or World Pay configured in Recurly to handle 3DS2 transactions Recurly.js will make this API calls by default to ensure your implementation is properly handling 3DS2 challenges.

Below is an example of disabling this preflight fingerprinting for said gateways above.

recurly.configure({
  // ...
  risk: {
    threeDSecure: {
      preflightDeviceDataCollector: false,
    }
  }
  // ..
});

You may want to use the config above, if you are handling a transaction you are confident will not be challenged. It is important to note, that if the issuing bank or gateway does request a challenge, you will not be able to handle the challengeit if this configuration is in use.

Reference

fn recurly.Risk

Arguments

None.

Returns

A new Risk instance

fn recurly.ThreeDSecure

Arguments
Param Type Description
options Object  
options.actionTokenId String three_d_secure_action_token_id returned by the Recurly API when 3-D Secure authentication is required for a transaction
Returns

A new ThreeDSecure instance.

fn threeDSecure.attach

Arguments
Param Type Description
container HTMLElement A DOM element to contain any UI elements necessary to fulfill the 3-D Secure authentication process. We recommend this element be a minimum size of 250px (W) x 400px (H), and contain an interstitial message to explain that 3-D Secure authentication will be required to complete the transaction.
Returns

Nothing

events Emits
token

This event is fired when your customer has completed the 3-D Secure flow. Recurly has received the authentication details, and generated this token to be used in our API.

Signature
Param Type Description
token Object  
token.type String ‘three_d_secure_action_result’
token.id String Token identifier to be sent to the API
error

This event is emitted when any error is encountered, whether during setup of the 3-D Secure flow, or during authentication. It will be useful to display errors to your customer if a problem occurs during the 3-D Secure flow.

Signature
Param Type Description  
error RecurlyError   An error describing the issue that occurred.

Fraud

Recurly.js provides a fraud protection suite with support for our Fraud Management toolkit, Kount integration, and Braintree gateway integration.

With fraud protection enabled, tokens created with Recurly.js will include device data we use to analyze fraud risk and flag subsequent transactions accordingly. Configuration is simple.

Configuring Fraud Protection

Once you have enabled fraud protection on your site, modify your Recurly.js configuration call according to your fraud protection setup.

Recurly Fraud Management & Kount Integration

If you are using Recurly Fraud Management or Kount, Recurly.js will handle all device data collection when configured as follows. Recurly Fraud Managment uses Kount’s device data collector under the hood. The form parameter should be your checkout form.

recurly.configure({
  // ...
  fraud: {
    kount: {
      dataCollector: true,
      form: document.querySelector('.my-checkout-form-selector')
    }
  }
  // ..
});

This will enable device data collection and automatically apply it to your tokens.

When using a Kount Enterprise Fraud Management plan you can provide your own User Defined Fields with the udf option.

recurly.configure({
  // ...
  fraud: {
    kount: {
      dataCollector: true,
      form: document.querySelector('.my-checkout-form-selector'),
      udf: {
        FREQUENCY: 107,
        COUPON: 'BUY11',
      }
    }
  }
  // ..
});

In order to add or remove User Defined Fields after configuring Recurly, you can assign a reference to an object that you can modify later.

Braintree Gateway Fraud Integration

First, you will need to collect device data using the Braintree JavaScript client. This is required by Braintree.

Once you have obtained deviceData, you’ll provide it to recurly.configure as follows. Note that we’re passing the complete deviceData string as exposed by the Braintree library.

// Collect device data using the Braintree client
// ...

const { deviceData } = braintreeInstance;

recurly.configure({
  // ...
  fraud: {
    braintree: { deviceData }
  }
  // ...
});

This will apply Braintree fraud data to your tokens generated by Recurly.js. Transactions created with those tokens will pass the fraud data to Braintree for fraud analysis.


Validation

Recurly.js bundles a few helpful methods for validating payment information prior to processing. These methods are used when generating tokens, but you can also use them to enhance your form validations and checkout flow.

Reference

recurly.bankAccount.bankInfo

Retrieves bank info based from a given routing number.

recurly.bankAccount.bankInfo({ routingNumber: '123456780' }, function (err, bankInfo) {
  if (err) {
    // err.code, err.message
  } else {
    // bankInfo.bank_name
  }
});

Arguments

Param Type Description
options Object  
options.routingNumber String The routing number for a bank (ex: ‘123456780’)
callback Function  

Callback signature

Param Type Description
err RecurlyError or undefined Error. Usually invalid-routing-number
bankInfo Object  
bankInfo.bank_name String Bank institution name (ex: Bank of Recurly)

Errors

Errors are encapsulated by a RecurlyError, which contains a few standard properties to help you diagnose error cases and inform your customers accordingly.

Errors will be thrown if the exception will prevent proper execution. If an error can be recovered, it will be passed to the proper error handling event listener, callback, or PricingPromise handler for you to inspect.

Best Practices

The message property contains diagnostic information intended to help you diagnose problems with the form, and we do not recommend displaying its contents to your customers.

To provide the best customer experience, we recommend that you provide your own error text to be displayed, based on the error code you receive.

Error Codes

Configuration

Code Description
not-configured This error appears when you try to perform an operation without first calling recurly.configure.
missing-public-key When you call recurly.configure, you must do so with a publicKey property.
invalid-public-key Check the publicKey to ensure it matches that of your admin app’s API Access section.

Tokenization

Code Description
validation A request validation error has occurred. This can indicate many possible issues, and you should check the fields property to determine which fields caused the error.
invalid-parameter Occurs when a tokenization parameter does not pass our internal validations. Check the fields property to determine which fields caused the error.
api-error A request to the Recurly API has encountered an issue. This too can indicate many possible issues, and we recommend inspecting the message and fields properties for more information.

Pricing

Code Description
not-found This happens when a nonexistent plan is requested.
missing-plan A Pricing instance will emit this if a plan has not been specified before trying to set a proeprty that depends on a plan, such as a coupon or addon.
invalid-addon Occurs when an addon is added to a Pricing instance but is not valid for the instance’s selected plan.
invalid-currency Similarly, if a currency is requested which is not valid for the selected plan.
gift-card-currency-mismatch Occurs when a gift card is redeemed with a currency that doesn’t match the instance’s configured currency.

Apple Pay

Code Description Additional Properties
apple-pay-init-error A configuration issue has prevented initialization err the originating RecurlyError.
apple-pay-not-configured Your site does not have a gateway which supports Apple Pay  
apple-pay-configuration-invalid There is an issue with your Apple Pay authentication information. Check your certificate and key values in your gateway configuration.  
apple-pay-merchant-validation-error Apple encountered an error validating your merchant credentials  
apple-pay-payment-failure An error has occurred during tokenization, preventing the payment authorization  

PayPal

Code Description
paypal-not-configured In order to perform a PayPal transaction, your site must be configured to accept PayPal reference
paypal-canceled The customer canceled the PayPal agreement flow.
paypal-error A generic PayPal error has occurred. Inspect message to learn more.
invalid-routing-number The bank routing number is not valid

3-D Secure

Code Description Additional Properties
3ds-auth-error 3-D Secure authentication has failed because the customer could not be authenticated. We recommend prompting the user to try a different payment method. cause the originating Error.
3ds-result-tokenization-error An error occurred while attempting to tokenize the 3-D Secure authentication result. cause the originating RecurlyError.
3ds-vendor-load-error A third-party dependency had an issue loading. Dependencies are utilized when required by your payment gateway. vendor the dependency provider.
3ds-auth-determination-error The authentication method necessary to fulfill 3-D Secure requirements could not be determined  

Example RecurlyError object

{
  name: 'validation',
  code: 'validation',
  message: 'There was an error validating your request.',
  fields: [
    'number',
    'year'
  ]
}

Examples

Integration examples

We’ve prepared a full suite of example integrations for Ruby, Node.js, Python, and PHP using popular web frameworks for each language. These examples demonstrate the simplest method of integration, with a no-frills UI.

Code on GitHub


React Support

Recurly maintains a React component library to simplify use of Recurly.js for your React applications.

For details on getting started, see our documentation on GitHub.

TypeScript Support

TypeScript types for Recurly.js can be found on DefinitelyTyped

To install with npm, run npm install --save-dev @types/recurly__recurly-js in your project’s root directory.

Upgrading

Upgrading from previous versions and deprecated features of Recurly.js

Upgrading from Hosted Fields to Elements

Recurly.js v4.11.0 introduced Elements, a new API for displaying and controlling UI components of Recurly.js. They fulfill all of the roles that Hosted Fields had – to display credit card inputs on your payment pages. Elements bring a more flexible API for interacting with objects that render to your page. So while their main use-case will be to render card inputs, in the future they will also be used to interact with other UI components, like 3-D Secure challenges, Apple Pay, PayPal flows, price information, and risk/fraud detection.

Hosted Fields had exposed their interface through recurly.configure. In migrating to Elements, you will move this configuration to Element constructors:

Setup changes

Old Hosted Field Setup

<div data-recurly="card"></div>
recurly.configure({
  publicKey: 'my-public-key',
  fields: {
    card: {
      inputType: 'mobileSelect',
      style: {
        fontColor: '#010101'
      }
    }
  }
});

New Setup with Elements

<div class="my-card-element"></div>
recurly.configure('my-public-key');

const elements = recurly.Elements();
const card = elements.CardElement({
  style: {
    inputType: 'mobileSelect',
    fontColor: '#010101'
  }
});
card.attach('.my-card-element');

Changes to Event Listeners

If you are listening for changes to Hosted Field using the 'change' event, you will now listen for these changes on an Element instance.

Old Hosted Field change listener

recurly.on('change', (state) => {
  if (state.fields.card.focus) {
    // Listen for focus on my card field
  }
});

recurly.on('field:submit', () => {
  // Listen for use pressing <enter> within a hosted field
});

New Elements event listeners

const elements = recurly.Elements();
const card = elements.CardElement();

card.on('change', (state) => {
  // Listen for any change to my Element
});

card.on('focus', (state) => {
  // Listen for user focus on my Element
});

card.on('blur', (state) => {
  // Listen for user blur on my Element
});

card.on('submit', () => {
  // Listen for use pressing <enter> within an Element
});

See Elements for details on all events emitted by an Element.

Changes to Getting a Token

When creating a token from Elements, it is necessary to pass your Elements instance to recurly.token along with the form containing your user’s billing information. This allows for the flexibility of creating many Elements on a single page, and improved specificity.

Old Hosted Field token creation

const form = document.querySelector('#my-form');
recurly.token(form, (err, token) => {
  // handle my new token
});

New token creation with Elements

const elements = recurly.Elements();
const form = document.querySelector('#my-form');

// create and attach my Element instances

recurly.token(elements, form, (err, token) => {
  // handle my new token
});

We are happy to assist further in your upgrade path. Feel free to reach out to us for Support.

Upgrading from v3

Recurly.js v4 introduced the concept of Elements. These are a more secure method of capturing customer card data, ensuring that their payment information is never exposed to your payment form. This is a huge benefit for security and reduced PCI compliance exposure.

First, you will need to update your payment form. The credit card fields number, month, year, and cvv will need to be removed and replaced with a container element in the form <div id="my-recurly-card-element"></div>. The id is entirely optional, and is simply added for ease of reference. We recommend using the card field since it incorporates validation and UX improvements, but it is also possible to use separate fields for the number, month, year, and cvv. This is explained more completely in the Getting Started section.

Your recurly.token call may also need to be updated. It is now necessary to pass a reference to your Elements instance and the checkout <form> that contains your user’s billing info. Your callback function requires no modification. More info is available in the Getting a Token section.

You’ll notice that the Elements won’t look like the rest of your payment form inputs. That is because they are in fact iframes, and will need to be styled in order to get them to look right. We provide a stylesheet that works as a good baseline for styling the Elements to your needs (See the Getting Started section). To tweak styles further, and to cover styles for when the Element is focused, etc, see the Styling Elements section.

We are happy to assist further in your upgrade path. Feel free to reach out to us for Support.

Upgrading from versions prior to v3

Since version 3, Recurly.js shifted to credit card tokenization as its method of billing info capture. Given the significant changes, upgrading from an earlier version of Recurly.js will require a full rewrite of your integration. Please see the Getting Started section to begin.


Support

Recurly.js supports Chrome, Firefox, Safari, Edge, iOS, and Android.

We’re also here to lend a hand on any Recurly.js integration questions! You can get help from us in a handful of ways:

  • Take a look at the code on GitHub. We welcome bug reports through Issues and contributions through Pull Requests.
  • Browse and post questions on Stackoverflow. We check these regularly.

For other Recurly related questions, please contact support@recurly.com for help with your account or other general questions.