API v1: Subscriptions
Recurly is designed so an account (your customer) has at most one active subscription. An account can be
in one of three states: non-subscriber (free account), subscriber, and past-due (subscriber with an
outstanding balance).
Create a new Subscription
POST/accounts/:account_code/subscription
Parameters
- plan_code
- Unique subscription plan code
- coupon_code
- Optional coupon code to apply to the new subscription. Please note, the subscription request will fail if the coupon is invalid.
- unit_amount_in_cents
- Override the unit amount of the subscription plan by setting this value in cents. If not provided, the subscription will inherit the price from the subscription plan.
- quantity
- Optionally override the default quantity of 1
- trial_ends_at
- If set, overrides the default trial behavior for the subscription. This must be a date and time, preferably in UTC. The date must be in the future. PHP uses trial_period_ends_at.
Account Parameters
At a minimum, account_code must be specified. If the account does not exist, Recurly will automatically create the account if the transaction is successful.
- account_code
- Unique ID for the Account. This parameter is required.
Please see the Account API for a list of valid account attributes.
Billing Info Parameters
If billing information is not provided, Recurly will use the account's billing information on file. If billing information is provided and the transaction is successful, Recurly will update the account's stored billing information with the new information.
Please see the Billing Info API for a list of valid attributes. Recurly strongly recommends providing an IP address when capturing new or updated billing information.
Add Ons
A list of add ons can be provided in the create request. Providing unit_amount_in_cents and quantity in an add on will override the subscription plan's default values for the add on.
Add-on Parameters
- add_on_code
- Unique add on code to identify the add-on
- quantity
- Optionally override the default quantity of 1
- unit_amount_in_cents
- Optionally override the default price of the add-on
Overriding the Subscription Start Date
If you would like the subscription to start on a specified date, please set the `trial_ends_at` parameter in your API request. Recurly will ignore any trial period currently specified on the plan and begin charging the subscription on the date specified. This is useful for creating your own, custom trial intervals and for importing existing subscriptions from an external system.
Address Verification
At a minimum, your implementation should submit the account's billing street address and zip code for the Address Verification Service (AVS). The other address fields are helpful but do little to aid verification. These additional fields may be required depending on your "Address Requirements" setting in the Configuration for your site.
When accepting international payments, it is critical to accept payments that match street address OR zip code. Zip code validation fails when international zip codes contain letters -- the street address matches will still work. If you only accept payments within the United States, then set AVS to match on street address and zip code (5-digit). Alternatively, you may set AVS to only require zip code.
Request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?xml version="1.0"?> <subscription> <plan_code>bronze</plan_code> <quantity>1</quantity> <account> <account_code>123</account_code> <username>verena</username> <email>verena@test.com</email> <first_name>Verena</first_name> <last_name>Test</last_name> <company_name></company_name> <billing_info> <first_name>Verena</first_name> <last_name>Test</last_name> <address1>123 Test St</address1> <address2></address2> <city>San Francisco</city> <state>CA</state> <zip>94105</zip> <country>US</country> <ip_address>127.0.0.1</ip_address> <credit_card> <number>4111-1111-1111-1111</number> <verification_value>123</verification_value> <year>2010</year> <month>11</month> </credit_card> </billing_info> </account> <add_ons> <add_on> <add_on_code>extra</add_on_code> </add_on> <add_on> <add_on_code>special</add_on_code> <quantity>3</quantity> <unit_amount_in_cents>499</unit_amount_in_cents> </add_on> </add_ons> </subscription>
|
Code examples
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | $acct = new RecurlyAccount( $user->id, $user->username, $user->email, $user->first_name, $user->last_name, $user->company_name);
$subscription = new RecurlySubscription(); $subscription->plan_code = PLAN_CODE; $subscription->account = $acct; $subscription->billing_info = new RecurlyBillingInfo($subscription->account->account_code);
$add_on1 = new RecurlyAddOn(); $add_on1->add_on_code = ADD_ON_CODE1; $add_on1 = new RecurlyAddOn(); $add_on2->add_on_code = ADD_ON_CODE2; $add_on2->unit_price_in_cents = 450; $subscription->add_ons = array($add_on1, $add_on2_);
$billing_info = $subscription->billing_info; $billing_info->first_name = $subscription->account->first_name; $billing_info->last_name = $subscription->account->last_name; $billing_info->address1 = '123 Test St'; $billing_info->city = 'San Francisco'; $billing_info->state = 'CA'; $billing_info->country = 'US'; $billing_info->zip = '94105'; $billing_info->credit_card->number = '4111-1111-1111-1111'; $billing_info->credit_card->year = intval(date('Y')) + 1; $billing_info->credit_card->month = date('n'); $billing_info->credit_card->verification_value = '123';
$sub_response = $subscription->create();
|
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | account = Recurly::Account.new( :account_code => user.id.to_s, :first_name => user.first_name, :last_name => user.last_name, :email => user.email, :company_name => user.company_name)
account.billing_info = Recurly::BillingInfo.new( :first_name => account.first_name, :last_name => account.last_name, :address1 => '123 Test St', :city => 'San Francisco', :state => 'CA', :country => 'US', :zip => '94103', :credit_card => { :number => '4111-1111-1111-1111', :year => Time.now.year + 1, :month => Time.now.month, :verification_value => '123' }, :ip_address => '127.0.0.1' )
sub = Recurly::Subscription.create( :account_code => account.account_code, :plan_code => PLAN_CODE, :quantity => 1, :account => account )
|
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | create_account_data = { 'account_code': user.id.to_s, 'username': 'verena', 'email': 'verena@test.com', 'first_name': 'Verena', 'last_name': 'Test', 'company_name': 'Company, LLC.', }
create_subscription_data = { 'plan_code': PLAN_CODE, 'quantity': 1, 'account': { 'account_code': self.account_code, 'username': 'verena', 'email': 'verena@test.com', 'first_name': create_account_data['first_name'], 'last_name': create_account_data['last_name'], 'company_name': 'Company, LLC.', 'billing_info': { 'first_name': create_account_data['first_name'], 'last_name': create_account_data['last_name'], 'address1': '123 Test St', 'city': 'San Francisco', 'state': 'CA', 'country': 'US', 'zip': '94105', 'credit_card': { 'number': '1', 'year': '2018', 'month': '12', 'verification_value': '123', }, }, }, } create_subscription_result = recurly.accounts.subscription.create( account_code=self.account_code, data=create_subscription_data )
|
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | RecurlyAccount acct = Factories.NewAccount("Create Account"); acct.Create();
RecurlyAccount account = new RecurlyAccount("user123"); account.FirstName = "Verena"; account.LastName = "Test"; account.Email = emailAddress;
RecurlyBillingInfo billingInfo = new RecurlyBillingInfo(account); billingInfo.FirstName = account.FirstName; billingInfo.LastName = account.LastName; billingInfo.State = "CA"; billingInfo.Country = "US"; billingInfo.CreditCard.Number = "4111-1111-1111-1111"; billingInfo.CreditCard.VerificationValue = "123"; billingInfo.CreditCard.ExpirationMonth = DateTime.Now.Month; billingInfo.CreditCard.ExpirationYear = DateTime.Now.Year + 1; account.BillingInfo = billingInfo;
RecurlySubscription subscription = new RecurlySubscription(account); subscription.PlanCode = "gold"; subscription.Quantity = 1;
subscription.Create();
|
Look up a Subscription
GET/accounts/:account_code/subscription
This endpoint will return the active subscription and basic plan information if the user has an active subscription. If the user does not have a subscription, or it has expired, this will return 404 (or NULL from the client libraries). Please note, a 404 will also be returned if Recurly does not know about the account.
An active subscription can either be in the active or canceled state. The canceled state means the subscription is still valid but will not renew once the current period ends.
Response
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?xml version="1.0"?> <subscription> <account_code>verena</account_code> <plan> <plan_code>gold</plan_code> <name>Gold Plan</name> <version type="integer">1</version> </plan> <state>active</state> <quantity type="integer">1</quantity> <total_amount_in_cents type="integer">999</total_amount_in_cents> <activated_at type="datetime">2009-11-01T17:21:15-08:00</activated_at> <canceled_at type="datetime"></canceled_at> <expires_at type="datetime"></expires_at> <current_period_started_at type="datetime">2009-11-01T17:21:15-08:00</current_period_started_at> <current_period_ends_at type="datetime">2009-12-01T17:21:15-08:00</current_period_ends_at> <trial_started_at type="datetime"></trial_started_at> <trial_ends_at type="datetime"></trial_ends_at> </subscription>
|
Code examples
PHP
| $subscription = RecurlySubscription::getSubscription($acct->account_code);
|
Ruby
| subscription = Recurly::Subscription.find(acct.account_code)
|
Python
| subscription = recurly.accounts.subscription(account_code=acct.account_code)
|
C#
| RecurlySubscription subscription = RecurlySubscription.Get(accountCode);
|
Add ons
If the subscription has any add ons associated with it, they will be included in the XML as:
| <subscription> <!-- ... --> <add_ons> <add_on> <add_on_code>special</add_on_code> <quantity>1</quantity> <unit_amount_in_cents>499</unit_amount_in_cents> </add_on> <add_on><!-- ... --></add_on> </add_ons> </subscription>
|
Pending changes
If the user has a pending upgrade/downgrade to their subscription, it will be included in the XML as:
| <subscription> <!-- ... --> <pending_subscription> <plan_code>new plan_code</plan_code> <quantity type="integer">new quantity</quantity> <activates_at type="datetime">activation date</activates_at> </pending_subscription> </subscription>
|
Cancel a Subscription
DELETE/accounts/:account_code/subscription
Canceling a subscription turns off the subscription's auto-renewal. The subscription will continue through the current, invoiced term. When the subscription is up for renewal, the account will transition to a free account and the subscription will no longer be active.
When a subscription is canceled, Recurly will send a cancelation push notification. Recurly will send an additional subscription expired push notification once the subscription is no longer active.
Code examples
PHP
| RecurlySubscription::cancelSubscription($acct->account_code);
|
Ruby
| Recurly::Subscription.delete(acct.account_code) # or subscription.cancel(account.account_code)
|
Python
| cancel_result = recurly.accounts.subscription.delete(account_code=acct.account_code)
|
C#
| RecurlySubscription.CancelSubscription(accountCode);
|
Reactivating a canceled subscription
POST/accounts/:account_code/subscription/reactivate
When a subscription is canceled, it will not renew. It is considered active until the end of the current billing period. Then, the subscription will end. Any modification to the subscription (upgrade/downgrade) will cause the subscription to move back to an active, renewing state. To renew the subscription without modifying it, simply send a reactivation request to this end point.
Modifying an existing Subscription
PUT/accounts/:account_code/subscription
Changing a subscription can update the subscription's plan, price, quantity, or add ons.
Please see the Upgrades and Downgrades information for more about the logic we use to modify an account's current subscription.
- timeframe
- Required. Please specify "now" or "renewal" to delay the change until the subscription renews.
- plan_code
- If specified, change the subscription plan
- quantity
- Optionally changes the quantity on the subscription
- unit_amount_in_cents
- Optionally override the unit amount in cents of the subscription plan
- add_ons
- If provided, explicitly define all the add-ons for the subscription.
Add-on Parameters
- add_on_code
- Unique add on code to identify the add-on
- quantity
- Optionally override the default quantity of 1
- unit_amount_in_cents
- Optionally override the default price of the add-on
Request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0"?> <subscription> <timeframe>now</timeframe> <plan_code>silver</plan_code> <quantity>2</quantity> <add_ons> <add_on> <add_on_code>extra</add_on_code> <quantity>10</quantity> <unit_amount_in_cents>123</unit_amount_in_cents> </add_on> <add_on> <add_on_code>special</add_on_code> </add_on> </add_ons> </subscription>
|
Code examples
PHP
| RecurlySubscription::changeSubscription($acct->account_code, 'now', 'silver', 2);
|
Ruby
| subscription = Recurly::Subscription.find(acct.account_code) subscription.change('now', :plan_code => 'silver', _:quantity => 2)
|
Python
| update_data = { 'timeframe': 'now', 'plan_code': 'silver', 'quantity': '2', } update_result = recurly.accounts.subscription.update(account_code=acct.account_code, data=update_data)
|
C#
| RecurlySubscription subscription = RecurlySubscription.Get(accountCode); subscription.Quantity = 2; subscription.ChangeSubscription(RecurlySubscription.ChangeTimeframe.Now);
|
Timeframe
The timeframe parameter controls when the upgrade or downgrade takes place. The subscription chance can occur now or when the subscription renews. Generally, if you're performing an upgrade, you will want the change to occur immediately (now). If you're performing a downgrade, you should set the timeframe to renewal so the change takes affect at the end of the current billing cycle.
Please see the Upgrades and Downgrades information for more about the logic we use to modify an account's current subscription.
Plan Code, Quantity, and Unit Amount
Values not specified will be not be changed.
If the subscription plan changes, the unit amount will default to the new plan's unit amount. Of course, you are welcome to override the plan's unit amount by specifying it in the change request. If you change the subscription plan but do not specify a quantity, the new subscription will use the same quantity as the previous subscription.
Add Ons
Any add ons included in the subscription change request will be applied to the new subscription. The original subscription's add ons will not be carried over to the new subscription automatically.
Refund a Subscription
Refunding a subscription reverses part or all of the most recent subscription charge. The subscription is then terminated immediately and the account transitions back to a free account (non-subscriber). If the account is past-due, no refund is performed and the subscription is terminated.
Refunding a subscription is provided as a convenience. If you need to refund a specific amount, please use the Transactions API to refund a specific transaction.
Prorated Refund
DELETE/accounts/:account_code/subscription?refund=partial
Performs a partial refund. This amount is calculated using the time remaining on the last subscription charge and the amount invoiced.
Code examples
PHP
| $response = RecurlySubscription::refundSubscription($acct->account_code, 'partial');
|
Ruby
| subscription = Recurly::Subscription.find(acct.account_code) subscription.refund(:partial)
|
Python
| cancel_result = recurly.accounts.subscription.delete(account_code=acct.account_code, refund='partial')
|
C#
| RecurlySubscription.RefundSubscription(accountCode, RefundType.Partial);
|
Full refund of last charge
DELETE/accounts/:account_code/subscription?refund=full
Performs a full refund of the last charge for the current subscription term and then cancels the subscription, effective immediately.
Code examples
PHP
| $response = RecurlySubscription::refundSubscription($acct->account_code, 'full');
|
Ruby
| subscription = Recurly::Subscription.find(acct.account_code) subscription.refund(:full)
|
Python
| cancel_result = recurly.accounts.subscription.delete(account_code=acct.account_code, refund='full')
|
C#
| RecurlySubscription.RefundSubscription(accountCode, RefundType.Full);
|
Terminate a Subscription without a Refund
DELETE/accounts/:account_code/subscription?refund=none
To end a subscription immediately without issuing a refund, you may set the refund amount to none.
Code examples
PHP
| $response = RecurlySubscription::terminateSubscription($acct->account_code);
|
Ruby
| subscription = Recurly::Subscription.find(acct.account_code) subscription.refund(:none)
|
Python
| cancel_result = recurly.accounts.subscription.delete(account_code=acct.account_code, refund='none')
|
C#
| RecurlySubscription.TerminateSubscription(accountCode);
|