Docs
Payments
Collect a Payment
Subscriptions

Subscriptions

SubscriptionsAPI allow you to charge customers on a recurring basis. A successful subscription flow follows this sequence:

  1. The subscription is created with a status of pending
  2. On the billing_cycle_anchor date, a Payment Intent is created and confirmed
  3. The subscription status is then updated to active
  4. The subscription remains in the active status indefinitely or until it reaches the specified cancel_at date, at which point its status changes to canceled

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 OUTCOMEPAYMENT INTENT STATUSSUBSCRIPTION STATUS
successsucceededactive
failurerequires_payment_methodpast_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 ANCHORINTERVAL UNITINTERVAL COUNTFIRST 5 PAYMENT DATESDESCRIPTION
01/01/21month101/01/21, 02/01/21, 03/01/21, 04/01/21, 05/01/21The first of every month.
01/01/21month301/01/21, 04/01/21, 07/01/21, 10/01/21, 01/01/22The first of every third month.
01/31/21month101/31/21, 02/28/21, 03/31/21, 04/30/21, 05/31/21The last day of every month.
01/01/21 (Fri)week201/01/21 (Fri), 01/15/21 (Fri), 01/29/21 (Fri), 02/12/21 (Fri), 02/26/21 (Fri)Every other Friday.
01/01/21year101/01/21, 01/01/22, 01/01/23, 01/01/24, 01/01/25The first of every year.

Pause a subscription

Pausing a subscription temporarily stops all payment attempts, giving you flexibility in managing customer accounts.

Resume a subscription

Resuming a subscription reactivates the billing cycle and continues the regular payment schedule.

Cancel a subscription

Canceling a subscription permanently stops all future payments.

Subscription States

STATUSDESCRIPTION
pendingThe subscription has been created and is awaiting the initial payment processing at the billing_cycle_anchor.
activeThe subscription is current, and the most recent payment was successful.
past_dueThe latest payment has failed or was not attempted. Further payment attempts will wait until a retryAPI is initiated.
pausedThe subscription is on hold, and no payments will be processed until it is resumedAPI.
canceledThe 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, and charge.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 the next_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?The billing_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 of past_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.