Subscriptions
SubscriptionsAPI allow you to charge customers on a recurring basis. A successful subscription flow follows this sequence:
- The subscription is created with a status of
pending
- On the
billing_cycle_anchor
date, a Payment Intent is created and confirmed - The subscription status is then updated to
active
- The subscription remains in the
active
status indefinitely or until it reaches the specifiedcancel_at
date, at which point its status changes tocanceled
Set Up a Subscription
To set up a new subscription, you need an existing customer and their associated payment method.
Create a customer
To Create a CustomerAPI, specify the customer’s details such as name, email address, and phone number. While you can't change the customer associated with a subscription, you can update the payment method as needed.
Create a Customer sample request
curl -L '{{PRODUCTION_API_URL}}/v1/customers' \
-H '{{ACCOUNT_HEADER}}-account: {{MERCHANT_ACCOUNT_ID}}' \
-H 'Content-Type: application/json' \
-H '{{ACCOUNT_HEADER}}-api-key: {{SECRET_KEY}}' \
-d '{
"email": "[email protected]",
"first_name": "Jane",
"middle_name": "Andrea",
"last_name": "Doe",
"metadata": {
"order_id": "100123",
"internal_customer_id": "7cb1159d-875e-47ae-a309-319fa7ff395b"
},
"phone": "1234567890"
}'
Attach a Payment Method
To Attach a Payment Method to a CustomerAPI, specify the customer_id
. If you have not yet made a payment method then you will need to Create a Payment MethodAPI.
Create a Payment Method sample request
curl -L '{{PRODUCTION_API_URL}}/v1/payment-methods' \
-H '{{ACCOUNT_HEADER}}-account: {{MERCHANT_ACCOUNT_ID}}' \
-H 'Content-Type: application/json' \
-H '{{ACCOUNT_HEADER}}-api-key: {{SECRET_KEY}}' \
-d '{
"type": "card",
"card": {
"number": "4111111111111111",
"exp_month": 12,
"exp_year": 2031,
"cvc": "123"
},
"billing_details": {
"address": {
"zip": "33139"
}
}
}'
Attach a Payment Method sample request
curl -L -X PUT '{{PRODUCTION_API_URL}}/v1/payment-methods/{{PAYMENT_METHOD_ID}}/attach' \
-H '{{ACCOUNT_HEADER}}-account: {{MERCHANT_ACCOUNT_ID}}' \
-H 'Content-Type: application/json' \
-H '{{ACCOUNT_HEADER}}-api-key: {{SECRET_KEY}}' \
-d '{
"customer_id": "{{CUSTOMER_ID}}"
}'
Create a subscription
To Create a SubscriptionAPI, specify the customer_id
, payment_method_id
, price
, billing_cycle_anchor
, interval_unit
, and interval_count
. Billing cycles cannot be edited after a subscription is created.
Create a Subscription sample request
curl -L '{{PRODUCTION_API_URL}}/v1/subscriptions' \
-H '{{ACCOUNT_HEADER}}-account: {{MERCHANT_ACCOUNT_ID}}' \
-H 'Content-Type: application/json' \
-H '{{ACCOUNT_HEADER}}-api-key: {{SECRET_KEY}}' \
-d '{
"billing_cycle_anchor": "2024-07-04",
"currency": "usd",
"customer_id": “{{CUSTOMER_ID}}”,
"interval_count": 1,
"interval_unit": "week",
"metadata": {
"order_id": "100123",
"internal_customer_id": "7cb1159d-875e-47ae-a309-319fa7ff395b"
},
"payment_method_id": "{{PAYMENT_METHOD_ID}}",
"platform_fee_amount": 500,
"price": 10000
}'
Process the subscription payment
When a payment is due, automatically generates a Payment Intent to handle the transaction. If the payment succeeds, the subscription remains active. If the payment fails, the subscription status changes to past_due
and no further payments are attempted until you Update the Payment MethodAPI and Retry the SubscriptionAPI manually.
SUBSCRIPTION OUTCOME | PAYMENT INTENT STATUS | SUBSCRIPTION STATUS |
---|---|---|
success | succeeded | active |
failure | requires_payment_method | past_due |
To retrieve all the payment attempts associated with a subscription, use the Payment IntentsAPI endpoint and pass the subscription_id
query parameter.
Manage a Subscription
Although you can't change the customer or billing cycle associated with a subscription, you can update the payment method as needed. Subscriptions can also be paused, resumed, and canceled.
Define billing cycle
Billing cycles are calculated using a combination of billing_cycle_anchor
, interval_unit
, and interval_count
. The billing_cycle_anchor
sets the first payment date and determines the schedule for subsequent payments — whether they occur weekly, monthly, or yearly.
If the scheduled payment day does not exist in a given month, the payment will default to the last day of that month. For instance, a subscription that starts on January 31 would next be billed on February 28 (or 29 in a leap year), then on March 31 and so on. The interval_count
specifies how many intervals, as defined by the interval_unit
, will pass between billings.
BILLING CYCLE ANCHOR | INTERVAL UNIT | INTERVAL COUNT | FIRST 5 PAYMENT DATES | DESCRIPTION |
---|---|---|---|---|
01/01/21 | month | 1 | 01/01/21, 02/01/21, 03/01/21, 04/01/21, 05/01/21 | The first of every month. |
01/01/21 | month | 3 | 01/01/21, 04/01/21, 07/01/21, 10/01/21, 01/01/22 | The first of every third month. |
01/31/21 | month | 1 | 01/31/21, 02/28/21, 03/31/21, 04/30/21, 05/31/21 | The last day of every month. |
01/01/21 (Fri) | week | 2 | 01/01/21 (Fri), 01/15/21 (Fri), 01/29/21 (Fri), 02/12/21 (Fri), 02/26/21 (Fri) | Every other Friday. |
01/01/21 | year | 1 | 01/01/21, 01/01/22, 01/01/23, 01/01/24, 01/01/25 | The first of every year. |
Pause a subscription
Pausing a subscription temporarily stops all payment attempts, giving you flexibility in managing customer accounts.
- Pause immediately: Pause a subscription immediately using the Pause a SubscriptionAPI endpoint.
- Pause on a future date: Set the
pause_at
attribute to define a future date for when the subscription should be paused. This can be done when you Create a SubscriptionAPI or Update a SubscriptionAPI.
Resume a subscription
Resuming a subscription reactivates the billing cycle and continues the regular payment schedule.
- Resume immediately: Resume a subscription immediately using the Resume a SubscriptionAPI endpoint.
- Resume on a future date: Set the
resume_at
attribute to define a future date for when the subscription should resume. This can be done when you Create a SubscriptionAPI or Update a SubscriptionAPI.
Cancel a subscription
Canceling a subscription permanently stops all future payments.
- Cancel immediately: Cancel a subscription immediately using the Cancel a SubscriptionAPI endpoint.
- Cancel on a future date: Set the
cancel_at
attribute to define a future date for the subscription cancellation. This can be done when you Create a SubscriptionAPI or Update a SubscriptionAPI.
Subscription States
STATUS | DESCRIPTION |
---|---|
pending | The subscription has been created and is awaiting the initial payment processing at the billing_cycle_anchor . |
active | The subscription is current, and the most recent payment was successful. |
past_due | The latest payment has failed or was not attempted. Further payment attempts will wait until a retryAPI is initiated. |
paused | The subscription is on hold, and no payments will be processed until it is resumedAPI. |
canceled | The subscription has been canceled, and no future payments will be made. |
Subscription Events
Subscriptions trigger three specific types of events:
subscription.created
subscription.updated
subscription.canceled
Events related to Payment Intents are also generated and will include the subscription_id
in the event payload.
When you create a customer with a valid payment method and associate them with a subscription, the following events will be triggered, although their exact order may vary:
customer.created
: Indicates that a customer record has been successfully created.payment_method.attached
: Indicates that a payment method has been successfully attached to the customer.subscription.created
: Indicates that the subscription has been created.payment_intent.created
,payment_intent.succeeded
, andcharge.succeeded
: These events indicate that the customer's payment method was successfully charged.subscription.updated
: This event is sent when the subscription status changes to active, and the payload includes thenext_payment_at
date, which is when the next automatic payment attempt will occur.
Using Subscriptions to Schedule One-Time Payments
While SubscriptionsAPI are primarily designed for recurring payments, they can also be adapted to schedule a one-time future payment. To implement this, first Create a CustomerAPI, Attach a Payment Method to a CustomerAPI, then you can Create a SubscriptionAPI and set the cancel_at
attribute to the day after the billing_cycle_anchor
date.
Create a Subscription sample request
curl -L '{{PRODUCTION_API_URL}}/v1/subscriptions' \
-H '{{ACCOUNT_HEADER}}-account: {{MERCHANT_ACCOUNT_ID}}' \
-H 'Content-Type: application/json' \
-H '{{ACCOUNT_HEADER}}-api-key: {{SECRET_KEY}}' \
-d '{
"billing_cycle_anchor": "2024-07-04",
"cancel_at": "2025-07-05",
"currency": "usd",
"customer_id": “{{CUSTOMER_ID}}”,
"interval_count": 1,
"interval_unit": "week",
"metadata": {
"order_id": "100123",
"internal_customer_id": "7cb1159d-875e-47ae-a309-319fa7ff395b"
},
"payment_method_id": "{{PAYMENT_METHOD_ID}}",
"platform_fee_amount": 500,
"price": 10000
}'
FAQ
How do I change the due date for a subscription?
Thebilling_cycle_anchor
is fixed throughout the subscription's lifecycle and cannot be modified. calculates all future payments based on the initial date following the first payment. If you need to change the billing anchor, you will need to cancel the existing subscription and create a new one with the updated anchor.Can I update a subscription’s payment intent directly?
Yes. However, updating the payment intent will not affect the subscription’s status. If the subscription has a status ofpast_due
, users should Update a SubscriptionAPI with a valid payment method and Retry a SubscriptionAPI.How do I link a payment intent back to the subscription?
There are two approaches to linking a payment intent back to the subscription:1. Include metadata in your subscription request to query when retrieving a payment intent. The id will be listed in the
subscription_id
object.2. Configure webhooks for the
payment_intent.succeeded
event, which includes the payment_intent_id
and subscription_id
.