Subscriptions
Subscriptions are the foundation of recurring billing, enabling you to charge customers on a consistent schedule for your products or services. This guide covers the complete subscription lifecycle, from creation and management to usage reporting for metered billing.
Subscriptions are typically initiated through a Checkout Session. Before proceeding, ensure you have configured your Products and Prices.
The Subscription Lifecycle#
A subscription progresses through various states based on payment outcomes, trial periods, and cancellation actions. Understanding this lifecycle is essential for managing your recurring revenue effectively.
Subscription Statuses#
Status | Description |
---|---|
| The subscription is in good standing and payments are current. |
| The customer is in a free trial period. No payments are collected. |
| The latest renewal payment failed, and the system is retrying collection. |
| The subscription has been terminated and will not renew. |
| The initial payment for the subscription failed. |
| The initial payment failed, and the allowed time to complete it has passed. |
| The subscription is temporarily inactive and will not generate invoices. |
Creating a Subscription#
The standard method for creating a subscription is to set up a Checkout Session with mode
set to 'subscription'
. The customer completes the purchase through a secure, hosted payment page.
const session = await payment.checkout.sessions.create({
success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://example.com/cancel',
mode: 'subscription',
line_items: [
{
price_id: 'price_xxx', // ID of a recurring price
quantity: 1
}
],
});
// Redirect your customer to session.url to complete the purchase.
Once the customer successfully completes the payment, a new subscription is created and becomes active.
Managing Subscriptions#
You can retrieve, list, and update subscriptions programmatically to handle various customer service and business logic scenarios.
Retrieve a Subscription#
Fetch the details of a single subscription using its unique ID.
const subscription = await payment.subscriptions.retrieve('sub_xxx');
console.log(subscription);
List Subscriptions#
Retrieve a paginated list of subscriptions, with options for filtering and sorting.
Parameters
Name | Type | Description |
---|---|---|
|
| Filter by subscription status (e.g., |
|
| Filter by a specific customer ID. |
|
| Filter by a specific customer DID. |
|
| Sort order (e.g., |
|
| If |
|
| The page number for pagination. Defaults to |
|
| The number of items per page. Defaults to |
Example
// List all active subscriptions for a customer, sorted by the most recently created
const subscriptions = await payment.subscriptions.list({
customer_id: 'cus_xxx',
status: 'active',
order: 'created_at:DESC',
});
console.log(`Found ${subscriptions.total} active subscriptions.`);
Pausing and Resuming#
You can temporarily halt a subscription, stopping payments and service access, and resume it later.
// Pause a subscription
const pausedSubscription = await payment.subscriptions.pause('sub_xxx');
console.log(`Subscription status: ${pausedSubscription.status}`);
// Resume a paused subscription
const resumedSubscription = await payment.subscriptions.resume('sub_xxx');
console.log(`Subscription status: ${resumedSubscription.status}`);
Canceling a Subscription#
To terminate a subscription, use the cancel
method. This action is typically irreversible once the cancellation takes effect.
Parameters
Name | Type | Description |
---|---|---|
|
| Required. The ID of the subscription to cancel. |
|
| Defines when the cancellation occurs. |
|
| Specifies if and how a refund should be issued. |
|
| The reason for cancellation (e.g., |
Example: Cancel at Period End
This approach allows the customer to retain service access until the end of the paid billing period.
const subscription = await payment.subscriptions.cancel('sub_xxx', {
at: 'current_period_end',
reason: 'cancellation_requested',
feedback: 'The user found the service too complex.',
});
console.log(`Subscription will be canceled on: ${new Date(subscription.cancel_at * 1000)}`);
Recovering a Subscription#
If a subscription is scheduled to be canceled at the end of the period but has not yet been terminated, you can reactivate it using the recover
method.
const subscription = await payment.subscriptions.recover('sub_xxx');
// The subscription is now active again and will renew at the next period end.
console.log(`Subscription status: ${subscription.status}`);
Reporting Usage for Metered Billing#
For subscriptions based on consumption (e.g., API calls, data storage), you must report usage against a subscription_item
. Each subscription contains one or more subscription_item
objects, each corresponding to a price on the subscription.
1. Find the Subscription Item
First, list the items for the subscription to find the ID of the metered item.
const items = await payment.subscriptionItems.list({ subscription_id: 'sub_xxx' });
const meteredItem = items.data.find(item => item.price.recurring.usage_type === 'metered');
if (!meteredItem) {
throw new Error('No metered subscription item found.');
}
2. Create a Usage Record
Next, report the quantity of usage consumed for that subscription item.
Parameters
Name | Type | Description |
---|---|---|
|
| Required. The ID of the subscription item to report usage for. |
|
| Required. The amount of usage to report. |
|
|
|
|
| The time the usage occurred, as a Unix timestamp. Defaults to now. |
const usageRecord = await payment.subscriptionItems.createUsageRecord({
subscription_item_id: meteredItem.id,
quantity: 100,
action: 'increment',
timestamp: Math.floor(Date.now() / 1000),
});
console.log(`Reported usage record: ${usageRecord.id}`);
Reported usage is aggregated and billed automatically at the end of each billing period.
Now that you can manage the subscription lifecycle, learn how to handle asynchronous events like customer.subscription.created
by configuring Webhooks.