Documentation You are here: start » v » 2.0 » products » subscriptions

Subscription and Recurring Billing with FoxyCart

How Subscriptions Work in FoxyCart

FoxyCart allows merchants to process subscription and recurring-billing types products in a secure and flexible way, without relying on gateway-specific solutions with are often costly and less flexible for the merchant and the customer. To do this, FoxyCart securely stores the customer's payment information, and provides access to subscriptions to the merchant through the FoxyCart admin, to the developer through the API, and to the customer through a variety of link possibilities (included in the email receipts by default).

Recurring revenue streams can be a game-changing business decision, but it is important to understand a few things.

  1. Recurring billing will fail with some regularity. Credit cards methods expire, become overdrafted, are canceled due to fraud or identity theft, and more. If you have 100 customers on a monthly billing arrangement, it is completely natural for at least a handful to error in any given month. If you want to get paid, you will need to monitor errors and followup with customers. Often times customers simply need a reminder to update their payment information.
  2. FoxyCart does not send customers emails by default, though this functionality (“dunning”) can be configured in the advanced settings page of your store admin. You may also perform more advanced customizations and integrations using the Subscription XML Datafeed and something like PHP Subscription XML Datafeed Processor. If you have questions please post in our forum.
  3. Some gateways may have additional steps to allow FoxyCart to process subscriptions. Please see the notes below for explanation, and always test, test, test before going live.

Custom shipping snippets do not work for subscriptions. The reason for this is because the snippets are done as Javascript modifications and run in the browser, while subscriptions run completely on the server side and never touch the browser. Subscriptions will always calculate on the server side based on how the category is configured.

When Do Subscriptions Process?

Subscriptions process daily between 0400-0500 Pacific Time (America/Los_Angeles, US), with backup runs scheduled between 0800-0900 (same timezone). Different FoxyCart versions process subscriptions at different times, but they are all scheduled near those windows.

We Eat Our Own Dog Food FoxyCart uses FoxyCart's subscription processing functionality to bill for FoxyCart services, and we have from day 1. So if you're wondering how robust it is, you can take comfort in the fact that if it messes up, we lose money ourselves.

Will It Work With Your Gateway?

Required Reading! Handling subscriptions through FoxyCart may not work with all gateways, particularly with your default settings. READ THIS SECTION if you're using subscriptions.

By default, most gateways require the CSC (card security code, also called the CVV2, CVC2, or CCID) to be sent with the payment details. Because storing the CSC is prohibited per PCI DSS, FoxyCart sends the subscription transactions without the CSC. If your gateway is set to require the CSC, the transaction will fail, effectively rendering FoxyCart's subscription functionality useless.

Depending on your gateway provider and account settings you may be able to configure this yourself, or you may need to ask your gateway's support to change your account for you. Please review the notes for your gateway. Even if there are no notes specific to subscription handling on our wiki, you should still dig into the CSC settings on your gateway. And test to ensure recurring payments process correctly.

Worth noting is that for all regular transactions through FoxyCart the CSC is required on checkout. The only way the CSC will not be sent to your gateway by FoxyCart is for a subscription transaction.

Testing

Testing is a REQUIRED STEP when using subscriptions with FoxyCart. Check the testing page for more details.

Important to note is that while your FoxyCart store is in test mode, any subscriptions you process will be set to “active”, and will be processed once you switch over to the Live Servers.

Before you switch over to the Live Servers, make sure that you set all the subs you have created while on the Test Servers to inactive. You can do that by using the API or by changing them individually. To change them individually, go to the Manage Subscriptions section in the FoxyCart admin, click on the Edit link of the desired subscription, deactivate the sub by unchecking the Active? checkbox and then update the subscription.

It's recommended to create a separate store for testing and one for production so that you wouldn't need to deactivate all the test subs when you switch over to a Live Store.

Subscription Billing & Cancellation Management (Dunning)

An Overview of Subscription Management with FoxyCart

As mentioned above, FoxyCart does not send automatic emails to customers when their payments fail by default, though this can be configured. Currently, FoxyCart doesn't send emails when a customer's payment method is soon to expire. Nor does FoxyCart (currently) provide a “customer portal” where they can view active subscriptions, update billing info, or cancel subscriptions. Instead, FoxyCart provides the tools to build similar functionality as desired.

What FoxyCart does provide, however, is a variety of methods for both the merchant and the customer to update subscriptions.

Using FoxyCart's Native Dunning Functionality

In your store's advanced settings page, there is a section named “Recurring Billing Settings”. In this section are options to re-attempt failed transactions, send email reminders about subscriptions in an error state, and cancel a subscription after a period of time.

All of the following options are on the “advanced settings” page in your FoxyCart admin.

Charge past due amounts

On the Advanced settings page, you can toggle whether to charge past due amounts or not. This can be very helpful when working with recurring donations. By turning this off, donors will not be charged a past due amount if their last donation did not process successfully.

Failed Transactions Reattempt Schedule

This field accepts a comma separated list of numbers. Each number represents the number of days after the initial failure that a reattempt should be made. For example, a setting of 1, 3, 5, 15, 30 would direct FoxyCart to attempt to collect the past-due amount on the 1st, 3rd, 5th, and 15th days after the initial transaction.

Reattempt Bypass Logic & Strings

These two fields work in conjunction with the reattempt schedule, and limit when a transaction should be reattempted. The “strings” field accepts a comma separated list of strings containing text strings that should prevent or allow (based on the above setting) a rebilling attempt. For example, setting the logic to “skip if the string is present” with a value for the “strings” field of Code: 8, Code: 37 would instruct FoxyCart to not initiate the rebilling process if the last error contained either Code: 8 or Code: 37, but to attempt the rebilling in all other cases.

Reminder Email Schedule

Similar to the “transactions reattempt schedule”, this field accepts a comma separated list of numbers. Each number represents the number of days after the initial failure that an email notification to the customer should be sent. This only happens for active subscriptions which still have a past due amount. If a reattempt is successful, no additional reminder email will be sent.

Emails are sent using the normal email template. Take a look at the default template (search for the is_subscription_dunning_reminder, is_subscription_dunning_cancellation, or other bits with dunning in them) to see how the logic is structured, and where to inject your own messaging to your users.

You can also look at the days_since_first_failed_transaction value, which will allow you to change the message depending on how long it's been since the error.

Cancellation Schedule

This field accepts a single number representing the number of days after the initial failure that a subscription should be set to cancel (assuming a successful payment hasn't been made in the meantime). For example, if a subscription is set to process on the 1st of the month and this value is 35, on the 5th of the next month (which is 35 days later, assuming the first month had 30 days), the subscription will be cancelled. (The end date will be set to that day, and it will be set to inactive.) As before, look at the default email template to see what will be sent to your customers when this triggers.

Example Email Customization

If you wanted to change the text of your email based on the number of days since the failed payment (to increase the urgency and warn of impending cancellation, for example), it'd look something like this (replacing the if sub block of the default plain text email template):

{% set sub = subscriptions|first %}
{% if sub %}
    {% if days_since_first_failed_transaction < 15 %}
This email is a reminder that your subscription is currently {{ days_since_first_failed_transaction }} days past due. To bring your subscription up to date, use the link below and complete your transaction:
{{ sub_token_url }}&empty=true&cart=checkout
    {% elseif days_since_first_failed_transaction > 15 and days_since_first_failed_transaction < 28 %}
This email is a reminder that your subscription is currently {{ days_since_first_failed_transaction }} days past due. **Your subscription will be cancelled automatically, and access removed, in {{ 30 - days_since_first_failed_transaction }} days.**

To bring your subscription up to date, use the link below and complete your transaction:
{{ sub_token_url }}&empty=true&cart=checkout
    {% elseif days_since_first_failed_transaction == 29 %}
This email is a reminder that your subscription is currently {{ days_since_first_failed_transaction }} days past due. **Your subscription will be cancelled TOMORROW unless you click the link below to update your payment information.**
{{ sub_token_url }}&empty=true&cart=checkout
    {% endif %}
{% endif %}

Managing Subscriptions

Customer Subscription Management by Email

The easiest way for most stores to provide customers with the means to update or cancel their subscriptions is to provide links in each and every receipt email sent to the customer. At left is an example of what we ourselves use, which is provided by default in FoxyCart's default email templates. Notice that links are provided to update the customer's billing information, to transfer the subscription to a new billing contact, and to cancel the subscription. Because these links are included in each and every receipt sent for a given subscription, it is an easy and effective way for customers to manage their own subscriptions. Also, because of the flexibility FoxyCart provides, these links can be customized as desired, removed, or extended to provide additional functionality.

Administrator Subscription Management

If you need to modify a subscription on behalf of a customer you can accomplish this in one of three ways:

  1. By using Unified Order Entry (aka “the superpassword”) to act as a customer without knowing their password.
  2. Through the FoxyCart admin, by editing the subscription. (For advanced edits you can edit the raw XML.)
  3. Through the API.

The Unified Order Entry method allows you to take advantage of the sub_token methods outlined below, as if you were the customer. See Unified Order Entry for details, but the basic idea is to use the sub_token to modify the subscription as necessary, then use the UOE superpassword to process the subscription on behalf of the customer.

You can modify the subscription product and customer information by following these steps:

  1. Login to your store admin
  2. Take note of the Unified Order Entry Password from the FoxyCart admin on the “Advanced” page: https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures
  3. Go to the Manage Product Subscriptions page and click on [+] (plus sign) next to desired subscription and click the Sub Token URL link
  4. In the same window (or tab), go to your website and add the donation campaign you want to replace the current one with. You should see a message in the cart that says “You are currently modifying a subscription.”
  5. Remove the previous subscription, then proceed to the checkout page
  6. The customer’s email address will be pre-loaded. For the password, input the Unified Order Entry Password from Step 2 to auto-populate the Customer Billing, Shipping, and Payment information
  7. Select the new credit card information (other than the Use saved card option) and fill in the updated credit card information
  8. Complete order and the customer will receive a receipt via email

The ''sub_token'': What It Is and How To Use It

Every subscription in a FoxyCart store has a unique sub_token, which is used both to identify the subscription (independent of customer or transaction) and to load the subscription into a customer's cart (to modify or cancel). This token is available in the Subscription XML Datafeed, from the API, and also in your FoxyCart admin subscriptions page, within the expanded details of a given subscription (right-click and copy the URL from the “Sub Token URL” link), or from the edit page of a subscription.

When the sub_token parameter is passed to the cart, it will blow away any previous cart data and load in a “template” of what the subscription is. There are a few common use cases for this:

Changing Billing Information or Paying Past Due Amounts

The sub_token can be combined with a cart=checkout directive to send the customer straight to the checkout screen (bypassing the cart), and indeed this is how the default receipt email includes the sub_tokens. When the customer lands on checkout the email address will be pre-filled with the current billing email address. At that point the customer can enter their password and complete the payment or information update as normal, or the customer can enter a new email address and take over the subscription from the previous billing contact.

It's worth noting that customers may update their billing information without the sub_token by using the cart parameter updateinfo, but for the purposes of this discussion it's likely more useful to include the sub_token. That said, if you need to allow customers to update their payment information and you don't have the sub_token available, you can use cart=updateinfo. More info is available at the cheat sheet and the documentation here.

If you're using PayPal Express, we do not support modifying subscriptions via the sub_token. We are working to implement a new PayPal integration which should avoid many of the challenges we see with PayPal's Express Checkout system.

Automating Subscription Billing Reattempts on Errors

NOTE: The best way to automate this now is by using the native dunning functionality, described above.

If a subscription has had a billing error and has a past due amount, you can tell FoxyCart to attempt to collect the past due amount by passing in the sub_token to the process_past_due_subscription endpoint at your store's domain, like this: https://example.foxycart.com/process_past_due_subscription&sub_token=foobar

The response is JSON like this:

{
    "result": "OK", // "OK" if successful. "ERROR" if unsuccessful.
    "transaction_id": "", // int
    "processor_response": "", // string
    "processor_response_details": "", // string
    "receipt_url": "", // URL
}

Manually Reattempting / Charging a Failed Subscription

If a subscription failed to process but you'd like to reattempt it, these are the steps.

  1. If UOE isn't already enabled, go to your store's Advanced settings and enable it. Use something like Passphra.se to generate a random but memorable and secure password.
  2. Load up the subscriptions in the FoxyCart admin and expand the subscription in question.
  3. Find the “Sub Token URL” link, as noted in the image to the right. Control+Click that to open it in a new tab.
  4. The cart will load with that subscription present. Click to continue to the checkout.
  5. The customer's email will be loaded already. Enter the UOE password, and the checkout will complete with their payment info. Modify if necessary. Notice that the past due amount is set to be charged.
  6. Complete the transaction. If it succeeds, the customer will receive an email receipt. If it isn't successful, you'll see the error describing the reason why. (For more on interpreting errors, see this page.)

Loading the Subscription to be Modified

If a customer desires to change his or her subscription, you could pair the sub_token with a redirect parameter to redirect the customer to a page on your website with links or forms for new subscriptions, or to view their cart. The customer could then add or remove items from their subscription, change quantities, or etc. Once the customer is satisfied with their new subscription they can proceed through checkout to update their subscription. Visual indication is provided to the customer on the cart and checkout page if a sub_token is active, as shown in the image at right.

Note that any new subscriptions added to the cart will automatically have the sub_startdate set to the next scheduled date for the subscription to run on, which will prevent a user from modifying a subscription that ran yesterday (for example) and being charged again for today. For example, if you have a subscription for “Chocolate of the Month” set to run on the 15th of each month, and you load the sub_token on the 25th and add a “Wine of the Month” subscription product to your cart, the sub_startdate will be set to the 15th of the next month (unless manually overridden).

Once a user completes the checkout from the sub_token that new transaction will replace the previous subscription.

Canceling a Subscription

Similar to the modification approach above, a subscription can be loaded to be canceled if the sub_token is passed in with a sub_cancel=true. This will change the notification to something like “You are about to set this subscription to end on 2010-10-01”, and upon checkout the subscription will be set to end. It is generally a good idea to include the cart=checkout parameter to ensure the cancellation goes straight to checkout.

When a subscription is set to cancel, it effectively sets the sub_enddate to tomorrow, at which point the subscription will not be processed (even if the sub_enddate falls on a normal billing date), and the cancellation will be included in the Subscription XML Datafeed.

FoxyCart's current implementation requires that customers attempting to cancel subscriptions pay any past due amount before they can cancel their account. If a customer needs to cancel a subscription with a past due balance you will have to do this for them through the subscription page in the FoxyCart admin.

Please see the cheat sheet for the complete list of product options. Subscription-specific options are included below for your reference.

sub_frequency
Description: The frequency of billing (every month, every 3 months, every year, etc.).
Default: None. If this value is empty, the product will not be considered to be a subscription by FoxyCart.
Accepts: An integer followed by a single character denoting the unit of time. For example,
  • 60d = every 60 days.
  • 2w = every two weeks. For date calculations, 1w = 7d.
  • 1m = every month. When you use the m unit, FoxyCart will assign billing to the current (or assigned) day of the month, to be repeated every x months. The date will be moved up when necessary; if set to the 31st, it will process on the 30th of months with 30 days (or 28th/29th of February).
  • 1y = every year.
  • .5m = twice a month. IMPORTANT: The .5 value only works with m (months). This value will setup bi-monthly subscriptions, once on the start date, and again 15 days later. Example: if you set it to start on the 3rd, it will run on the 3rd and the 18th of each month.

Notes: A sub_frequency is required for a product to be treated as a subscription by FoxyCart.
sub_startdate
Description: Subscription start date. Useful if you'd like to offer a free trial period, or to force subscriptions to process on specific dates (the 1st, 15th, 18th, etc.).
Default: “Today”, or “immediately”.
Accepts: You can pass through a full date in the YYYYMMDD format or just pass in the day of this month in the DD or D format. If you pass through a day that has already past, it will start on that day next month. For a relative date from today, you can also specify an integer followed by a single character denoting the unit of time.

  • YYYYMMDD = Example: 20150131 = January, 31 2015.
  • DD = Example: 10 = will run on the 10th of this month or the 10th of next month if today's date is after the 10th.
  • D = Same as DD.
  • 60d = 60 days from today.
  • 2w = 2 weeks from today. For date calculations, 1w = 7d.
  • 1m = 1 month from today.
  • 1y = 1 year from today.

Notes:

  • This is an optional field. Not indicating a “sub_startdate” would automatically assign it its default value.
  • Subscription start and end dates are not currently tied to a store's timezone settings. Test your start and end dates thoroughly or ask in the forum if you have questions about them.
  • The day of the sub_startdate will generally be used for all subsequent billing attempts when used with a monthly frequency, but in cases where the date doesn't exist in a month, it will be moved ahead for that month. So if you have a subscription with a start date on Jan-31, it will run on the Feb-28, Mar-31, Apr-30, and etc.

sub_enddate
Description: The date a subscription should end.
Accepts: YYYYMMDD formatted date value in the future. For a relative date from today, you can also specify an integer followed by a single character denoting the unit of time.

  • YYYYMMDD = Example: 20150131 = January, 31 2015.
  • 60d = 60 days from today.
  • 2w = 2 weeks from today. For date calculations, 1w = 7d.
  • 1m = 1 month from today.
  • 1y = 1 year from today.

Notes:

  • This is an optional field. Not indicating a “sub_enddate” would make the subscription run indefinitely.
  • If a subscription is scheduled to run on the 4th, and the sub_enddate is the 4th, the subscription will end before it is billed to the customer. So, this parameter should be set to a date after the date you want the last transaction in the subscription to run. For example, if you have a monthly subscription starting on January 1st, 2015 that is supposed to run for six months and then stop, set sub_endate to 20150602 (June 2nd, 2015) so that the transaction on June 1st is not cancelled by the end date.

sub_token
Description: Unique URL per subscription for loading your subscription up into a cart and modifying its contents. Very useful when used in conjunction with the redirect feature as you can load up a customer's subscription and then redirect them back to your product page so they can add something to it.
Accepts: A valid sub_token (retrieved from the API, XML datafeeds, or admin).
Notes: When a sub_token is loaded by the customer, the customer's cart is emptied and replaced by the content of the subscription represented by the sub_token.
sub_cancel
Description: A flag indicated the subscription in question (as retrieved from the sub_token) should be cancelled. By “canceling”, the subscription gets a sub_enddate of “tomorrow” (whatever date that may be).
Accepts: true
Notes: Requires a sub_token to function. Otherwise there will not be any subscription to cancel.

Site Tools