Subscriptions
Subscriptions are the core of recurring billing in PaymentKit. They allow you to charge customers on a repeating schedule for your products and services. This guide covers how to manage the entire subscription lifecycle, from creation and listing to updates, cancellations, and reporting metered usage.
Before managing subscriptions, you should be familiar with how to set up your offerings. For more details, see the Products & Prices guide.
Subscription Lifecycle Flow#
A subscription progresses through several states from its creation to its eventual completion or cancellation. Understanding this flow is key to managing your recurring revenue.
List Subscriptions#
Retrieve a paginated list of all subscriptions. You can filter the list based on various criteria such as customer ID or status.
Parameters
Name | Type | Description |
|---|---|---|
|
| Filter subscriptions by status. Options include |
|
| Filter subscriptions by the customer's unique ID. |
|
| Filter subscriptions by the customer's DID. |
|
| Filter by custom metadata fields. |
|
| Sort order for the results, e.g., |
|
| If |
|
| The page number for pagination. Defaults to |
|
| The number of items per page. Defaults to |
Returns
Returns a paginated object containing a list of subscription objects.
Name | Type | Description |
|---|---|---|
|
| The total number of subscriptions matching the query. |
|
| An array of subscription objects. |
Example
import payment from '@blocklet/payment-js';
async function listActiveSubscriptions() {
try {
const subscriptions = await payment.subscriptions.list({
order: 'updated_at:ASC', // Sort by update time
activeFirst: true, // Show active subscriptions first
pageSize: 10,
});
console.log(`Found ${subscriptions.count} subscriptions.`);
subscriptions.list.forEach(sub => {
console.log(`- ID: ${sub.id}, Status: ${sub.status}`);
});
} catch (error) {
console.error('Error listing subscriptions:', error.message);
}
}
listActiveSubscriptions();Example Response
{
"count": 1,
"list": [
{
"id": "sub_xxx",
"livemode": false,
"currency_id": "pc_xxx",
"customer_id": "cus_xxx",
"current_period_end": 1731888000,
"current_period_start": 1729209600,
"status": "active",
"billing_cycle_anchor": 1729209600,
"collection_method": "charge_automatically",
"start_date": 1729209600,
"metadata": {}
}
]
}Retrieve a Subscription#
Fetch the details of a specific subscription using its unique ID.
Parameters
Name | Type | Description |
|---|---|---|
|
| The unique identifier of the subscription to retrieve. |
Returns
Returns a full subscription object if found.
Example
import payment from '@blocklet/payment-js';
async function getSubscription(subscriptionId) {
try {
const subscription = await payment.subscriptions.retrieve(subscriptionId);
console.log('Subscription retrieved:', subscription);
} catch (error) {
console.error('An error occurred:', error.message);
}
}
getSubscription('sub_xxx');Example Response
{
"id": "sub_xxx",
"livemode": false,
"currency_id": "pc_xxx",
"customer_id": "cus_xxx",
"current_period_end": 1731888000,
"current_period_start": 1729209600,
"status": "active",
"cancel_at_period_end": false,
"billing_cycle_anchor": 1729209600,
"collection_method": "charge_automatically",
"start_date": 1729209600,
"items": [
{
"id": "si_xxx",
"price_id": "price_xxx",
"quantity": 1
}
]
}Cancel a Subscription#
You can cancel a subscription either immediately or at the end of the current billing period.
Parameters
Name | Type | Description |
|---|---|---|
|
| The ID of the subscription to cancel. |
|
| An object containing cancellation options. See details below. |
Cancellation Options (body)
Name | Type | Description |
|---|---|---|
|
| When to perform the cancellation. Can be |
|
| Required if |
|
| The reason for cancellation (e.g., |
|
| Customer feedback (e.g., |
Example
import payment from '@blocklet/payment-js';
async function cancelSubscription(subscriptionId) {
try {
const subscription = await payment.subscriptions.cancel(subscriptionId, {
at: 'current_period_end', // The subscription will remain active until the billing period ends
reason: 'cancellation_requested'
});
console.log('Subscription scheduled for cancellation:', subscription.id);
console.log('Cancel at period end:', subscription.cancel_at_period_end);
} catch (error) {
console.error('Error canceling subscription:', error.message);
}
}
cancelSubscription('sub_xxx');Report Usage for Metered Billing#
For subscriptions with metered prices, you must report usage to bill your customers correctly. Usage is reported against a specific subscription_item_id.
Usage Reporting Flow#
Parameters
Name | Type | Description |
|---|---|---|
|
| Required. The ID of the subscription item to report usage for. |
|
| Required. The amount of usage to report. |
|
| The reporting action. Use |
|
| A Unix timestamp for when the usage occurred. Defaults to the current time. |
Example
import payment from '@blocklet/payment-js';
async function reportUsage(subscriptionItemId) {
try {
const usageRecord = await payment.subscriptionItems.createUsageRecord({
subscription_item_id: subscriptionItemId,
quantity: 100, // Report 100 units of usage (e.g., API calls)
action: 'increment',
timestamp: Math.floor(Date.now() / 1000)
});
console.log('Usage reported successfully:', usageRecord);
} catch (error) {
console.error('Error reporting usage:', error.message);
}
}
// Replace 'si_xxx' with a real subscription item ID
reportUsage('si_xxx');Example Response
{
"id": "ur_xxx",
"livemode": false,
"quantity": 100,
"subscription_item_id": "si_xxx",
"timestamp": 1729243800
}This guide has provided an overview of managing subscriptions. With these tools, you can handle recurring payments and metered billing effectively.
For a complete list of all subscription-related methods and their parameters, please see the Subscriptions API Reference and the Subscription Items API Reference.
Next, you might want to learn how to implement credit-based systems by reading the Credit Billing guide.