• Content

Managing Subscriptions with Recurly API

Overview

In this guide we’ll walk through various methods for managing existing subscriptions programmatically via Recurly API. The following use cases will be covered:

  • Upgrading and Downgrading Subscriptions
  • Postponing Subscriptions
  • Pausing Subscriptions
  • Expiring Subscriptions

To get the most out of this guide, it’s recommended that you take a look at our product documentation for Subscription Changes, and also review the Quickstart Guide and the Purchases Guide.

Estimated Completion time

1 Hour

Upgrading and Downgrading

Subscription upgrades and downgrades involve modifications to the subscriptions’ plan, quantity, price, or included add-ons.

The Create Subscription Change endpoint is used to complete all of the upgrade and downgrade actions. You can specify the timeframe that you’d like the upgrade or downgrade to take place. You can opt for the change to occur immediately, when the subscription is next billed, or when the subscription term ends.

Change the subscription plan

To change the subscription plan, pass in the plan_id or plan_code of the new plan. In the example below, we’ll upgrade a customer’s existing subscription to a better plan, effective immediately:

Ruby

Node.js

Python

Java

Dotnet

change = @client.create_subscription_change(
  subscription_id: subscription_id,
  body: {
    timeframe: "now",
    plan_code: new_plan_code
  }
)
const subscriptionChangeCreate = {
  planCode: newPlanCode,
  timeframe: 'now'
}

const change = await client.createSubscriptionChange(subscriptionId, subscriptionChangeCreate)
console.log('Created subscription change: ', change.id)
sub_change_create = {plan_code: new_plan_code, timeframe: "now"}
change = client.create_subscription_change(subscription_id, sub_change_create)
print("Created SubscriptionChange %s" % change)
SubscriptionChangeCreate changeCreate = new SubscriptionChangeCreate();

changeCreate.setPlanCode(newPlanCode);
changeCreate.setTimeframe("now");

SubscriptionChange change = client.createSubscriptionChange(subscriptionId, changeCreate);
System.out.println("Created subscription " + change.getId());
var changeReq = new SubscriptionChangeCreate()
{
    PlanCode = newPlanCode,
    Timeframe = "now"
};
SubscriptionChange change = client.CreateSubscriptionChange(subscriptionId, changeReq);
Console.WriteLine($"Created subscription change {change.Id}");
}


Change the subscription price

To change the subscription price, pass in a new unit_amount for the subscription. This will override the plan’s default unit amount. In the example below, we’ll increase the cost of the subscription to $20 once the current subscription term reaches its end (trimeframe=term_end):

Ruby

Node.js

Python

Java

Dotnet

change = @client.create_subscription_change(
  subscription_id: subscription_id,
  body: {
    timeframe: "term_end",
    unit_amount: 20
  }
)
const subscriptionChangeCreate = {
  timeframe: 'term_end',
  unit_amount: 20
}

const change = await client.createSubscriptionChange(subscriptionId, subscriptionChangeCreate)
console.log('Created subscription change: ', change.id)
sub_change_create = {unit_amount: 20, timeframe: "term_end"}
change = client.create_subscription_change(subscription_id, sub_change_create)
print("Created SubscriptionChange %s" % change)
SubscriptionChangeCreate changeCreate = new SubscriptionChangeCreate();

changeCreate.setUnitAmount(20);
changeCreate.setTimeframe("term_end");

SubscriptionChange change = client.createSubscriptionChange(subscriptionId, changeCreate);
System.out.println("Created subscription " + change.getId());
var changeReq = new SubscriptionChangeCreate()
{
    Timeframe = "term_end",
    UnitAmount = 20
};
SubscriptionChange change = client.CreateSubscriptionChange(subscriptionId, changeReq);
Console.WriteLine($"Created subscription change {change.Id}");
}


Add / Remove Add-ons

You can modify the add-ons that are included with the subscription by passing in a list of add-on IDs. In the example below, we’ll update an existing subscription with add-on "abc123" to include an additional add-on with ID "def456":

If you provide a value for the add_ons field it will overwrite any existing add-ons so you must ensure that it represents the full list of add-on ID’s that you want to associate with the subscription, including any that previously existed. Just including the add-on’s id field will associate to the existing add-on. See the reference documentation for more detailed information.

Ruby

Node.js

Python

Java

Dotnet

change = @client.create_subscription_change(
  subscription_id: subscription_id,
  body: {
    timeframe: "now",
    add_ons: [{id: "abc123"}, {id: "def456"}]
  }
)
const subscriptionChangeCreate = {
  timeframe: 'now',
  add_ons: [{id: "abc123"}, {id: "def456"}]
}

const change = await client.createSubscriptionChange(subscriptionId, subscriptionChangeCreate)
console.log('Created subscription change: ', change.id)
sub_change_create = {add_ons: [{id: "abc123"}, {id: "def456"}], timeframe: "now"}
change = client.create_subscription_change(subscription_id, sub_change_create)
print("Created SubscriptionChange %s" % change)
SubscriptionChangeCreate changeCreate = new SubscriptionChangeCreate();

List<SubscriptionAddOnUpdate> addOns = new ArrayList<>();
addOnA = new SubscriptionAddOnUpdate()
addOnA.setId("abc123")
addOns.add(addOnA)

addOnB = new SubscriptionAddOnUpdate()
addOnB.setId("def456")
addOns.add(addOnB)

changeCreate.setAddOns(addOns)
changeCreate.setTimeframe("now");

SubscriptionChange change = client.createSubscriptionChange(subscriptionId, changeCreate);
System.out.println("Created subscription " + change.getId());
var changeReq = new SubscriptionChangeCreate()
{
  Timeframe = "now",
  AddOns = new List<SubscriptionAddOnUpdate>() {
    new SubscriptionAddOnUpdate() {
      Id = "abc123"
    },
    new SubscriptionAddOnUpdate() {
      Id = "def456"
    }
  }
};
SubscriptionChange change = client.CreateSubscriptionChange(subscriptionId, changeReq);
Console.WriteLine($"Created subscription change {change.Id}");

Postponing

Subscription postponement involves changes to your customer’s billing cycle (e.g. changing the date when your customer is next billed). Take a look at the product documentaton to learn more about this feature.

To postpone a subscription with Recurly API, use the Modify Subscription endpoint. In the example below, we’ll modify the date when the next billing period will start. This is particularly useful if you want to modify a subscription in a trial period (e.g. extend, or shorten the trial):

Ruby

Node.js

Python

Java

Dotnet

subscription = @client.modify_subscription(
  subscription_id: subscription_id,
  body: {
    next_bill_date: "2025-12-05"
  }
)
puts "Postponed Subscription #{subscription}"
const subscriptionChangeCreate = {
  timeframe: 'term_end',
  next_bill_date: '2025-12-05'
}

const change = await client.modifySubscription(subscriptionId, subscriptionChangeCreate)
console.log('Created subscription change: ', change.id)
sub_change_create = {next_bill_date: "2025-12-05", timeframe: "term_end"}
change = client.modify_subscription(subscription_id, sub_change_create)
print("Created SubscriptionChange %s" % change)
final SubscriptionUpdate subUpdate = new SubscriptionUpdate();
subUpdate.setNextBillDate("2025-12-05");
final Subscription subscription = client.modifySubscription(subscriptionId, subUpdate);
System.out.println("Modified Subscription: " + subscription.getUuid());
var updateReq = new SubscriptionUpdate()
{
    NextBillDate = "2025-12-05"
};
Subscription subscription = client.ModifySubscription(subscriptionId, updateReq);
Console.WriteLine($"Modified Subscription {subscription.Uuid}");

There are several other modification options available to you with this endpoint (e.g. changing the number of remaining billing cycles in the current term, or modifying the number of renewal billing cycles). Take a look at the reference documentation for more information.

Pausing

With Recurly API, pausing a subscription is easy and it’s a great way to give your customers an alternative to outright cancellation. Take a look at our product docs for more info on this feature.

To pause a subscription, you’ll use the Pause Subscription endpoint which provides the ability to freeze billing for a specified number of cycles at the next renewal date. Take a look at the example below where we pause a subscription for ten billing cycles:

Ruby

Node.js

Python

Java

Dotnet

subscription = @client.pause_subscription(
  subscription_id: subscription_id,
  body: {
    remaining_pause_cycles: 10
  }
)
puts "Paused Subscription #{subscription}"
const subscriptionPause = {
  remaining_pause_cycles: 10
}

const pause = await client.pauseSubscription(subscriptionId, subscriptionPause)
console.log('Created subscription pause: ', pause.id)
sub_pause = {remaining_pause_cycles: 10}
subscription = client.pause_subscription(subscription_id, sub_pause)
print("Paused Subscription %s" % subscription)
final SubscriptionPause subPause = new SubscriptionPause();
subPause.setRemainingPauseCycles(10);

final Subscription subscription = client.pauseSubscription(subscriptionId, subPause);
System.out.println("Paused Subscription: " + subscription.getUuid());
var pauseSubReq = new SubscriptionPause()
{
    RemainingPauseCycles = 10
};
Subscription subscription = client.PauseSubscription(subscriptionId, pauseSubReq);
Console.WriteLine($"Modified Subscription {subscription.Uuid}");

Expired, cancelled, or failed subscriptions cannot be paused.

Expiring

A subscription is marked as expired as a result of a cancellation (e.g. customer ends their subscription at the next bill date or term) or termination (e.g. the subscription is ended in the middle of the billing cycle). Check out our product documentation for more details.

Termination

To terminate a subscription, call the Terminate Subscription endpoint and pass in the ID of the subscription to terminate. You may also specify a type of refund (full, partial, or none). In the example below, we’ll terminate a subscription and provide a partial refund to the customer:

Ruby

Node.js

Python

Java

Dotnet

subscription = @client.terminate_subscription(
  subscription_id: subscription_id,
  body: {
    refund: "partial"
  }
)
puts "Terminated Subscription #{subscription}"
const subscription = await client.terminateSubscription(subscriptionId, {refund: 'partial'})
console.log('Terminated subscription: ', subscription.uuid)
subscription = client.terminate_subscription(subscription_id, {refund: "partial"})
print("Terminated Subscription %s" % subscription)
QueryParams queryParams = new QueryParams();
queryParams.setRefund("partial");
client.terminateSubscription(subscriptionId, queryParams);
System.out.println("Terminated Subscription: " + subscriptionId);
Subscription subscription = client.TerminateSubscription(subscriptionId, "partial");
Console.WriteLine($"Terminated Subscription {subscription.Uuid}");

A terminated subscription is immediately expired and cannot be reactivated.

Cancellation

To cancel a subscription, use the Cancel Subscription endpoint. Similar to termination, you’ll specify the ID of the subscription to cancel, but you’ll also specify if the subscription should end at the next billing date, or at the end of the term. In the example below, we’ll cancel a subscription at the end of the term:

Ruby

Node.js

Python

Java

Dotnet

subscription = @client.cancel_subscription(
  subscription_id: subscription_id
  body: {
    timeframe: "term_end"
  }
)
puts "Canceled Subscription #{subscription}"
let expiredSub = await client.cancelSubscription(subscriptionId, {timeframe: "term_end"})
console.log('Canceled Subscription: ', expiredSub.uuid)
subscription = client.cancel_subscription(subscription_id, {timeframe: "term_end"})
print("Canceled Subscription %s" % subscription)
subscriptionCancel = new SubscriptionCancel()
subscriptionCancel.setTimeFrame("term_end")
final Subscription subscription = client.cancelSubscription(subscriptionId, subscriptionCancel);
System.out.println("Canceled Subscription: " + subscription.getUuid());
var cancelSubReq = new SubscriptionCancel()
{
    Timeframe = "term_end"
};
Subscription subscription = client.CancelSubscription(subscriptionId, cancelSubReq);
Console.WriteLine($"Canceled Subscription {subscription.Uuid}");

At the end of the specified timeframe, the subscription will move to an expired state. However, it is possible to reactivate the subscription before that time using the Reactivate Subscription endpoint, which will restore the subscription back to it’s previous state. This is useful if your customer changes their mind and wants to continue with the service.

Next Steps

The examples presented in this guide are only the tip of the iceberg when it comes to managing subscriptions via Recurly API. Take a look at the full reference documentation, and never hesitate to reach out to our support team.