Subscriptions
Bill buyers on a schedule: create a plan, offer it to a buyer, let them subscribe, and follow every billing cycle, retry, cancellation and refund.
A subscription charges a buyer the same amount on a fixed schedule until it is cancelled. You define what you sell as a plan, offer one or more plans to a buyer, and the buyer subscribes. Payment Labs then charges the saved payment method each cycle and retries failed charges.
Before you start
- Get a token with Create Access Token, the same login payors use, from a credential with a payin role. Creating and cancelling plans, creating, editing and deleting offers, and cancelling subscriptions need the Merchant User Config permission (the Administrator role); editing a plan needs Merchant Approver. See Permissions.
- Read the Payins Overview.
| Object | ID prefix | What it is |
|---|---|---|
| Subscription plan | RD- | What you sell: an amount, a currency and a schedule, with an optional free trial. |
| Plan offer | RO- | A link for one buyer, listing one or more plans they can choose from. |
| Subscription | R- | One buyer subscribed to one plan. |
| Subscription payment | RP- | One billing cycle of a subscription. |
You cannot create a subscription for a buyer through the API. The buyer always subscribes themselves, through the offer, so that they agree to the recurring charge and authenticate the payment method.
Step 1: Create a plan
Call Create Subscription Plan:
curl -X POST https://api-sandbox.paymentlabs.io/subscription/plans \
-H "Authorization: Bearer $PAYMENT_LABS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Monthly",
"description": "Pro plan, billed every month",
"amount": 19.00,
"currency": "USD",
"schedule": { "interval": "monthly", "intervalCount": 1 },
"trialPeriod": { "interval": "daily", "intervalCount": 14 },
"termsOfServiceUrl": "https://shop.example.com/terms",
"privacyPolicyUrl": "https://shop.example.com/privacy"
}'| Field | Required | Notes |
|---|---|---|
amount | Yes | The amount charged each cycle, as a JSON number in currency. |
currency | Yes | ISO 4217 code enabled on your account. |
schedule | Yes | interval is daily, weekly, monthly or yearly; intervalCount (1 or more) is how many intervals pass between charges. monthly with 2 bills every two months. |
termsOfServiceUrl, privacyPolicyUrl | Yes | Shown to the buyer when they subscribe. |
name | No | 3 to 100 characters. The buyer sees it. |
description | No | Up to 500 characters. |
sort | No | Up to 100 characters. Use it to order plans in your own lists. |
trialPeriod | No | A free period before the first charge, in the same shape as schedule. |
The body is strict: any other field returns 400. The plan is created ACTIVE.
Step 2: Offer plans to a buyer
Call Create Plan Offer with the plans the buyer can choose from:
curl -X POST https://api-sandbox.paymentlabs.io/subscription/plans/offers \
-H "Authorization: Bearer $PAYMENT_LABS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"subscriptionPlanIds": ["RD-01JBXE2B4D6F8H0K2M4P6R8T0V", "RD-01JBXE3C5E7G9J1L3N5Q7S9U1W"],
"buyer": { "email": "[email protected]", "referenceId": "customer-7731" },
"description": "Pick monthly or yearly billing",
"expiresAt": "2026-12-31"
}'buyer.emailis required. Payment Labs reuses the buyer with that email on your account, or creates one. Only that buyer can subscribe through the offer.expiresAtaccepts a date or date-time. The offer works until 23:59:59 of that day inuserTimezone(UTC when omitted), and defaults to one year.- The response includes
links.self, a page you send to the buyer, andlinks.embeddable, the same page for an iframe. Payment Labs does not email the link; send it yourself.
To change an offer, call Update Plan Offer. subscriptionPlanIds is required on every update and replaces the whole list. To withdraw it, call Delete Plan Offer.
Step 3: Let the buyer subscribe
Show the offer in one of three ways:
- Send the buyer to
links.self. - Load
links.embeddablein an iframe withallow="payment", as described for checkouts in Hosted Checkout Page and Iframe. The frame posts the samePL_APP_CHECKOUT_*messages. - Render it with the Payin SDK:
sdk.createElement("subscription", offerId, …). See Subscriptions in the Payin SDK.
The buyer signs in or creates an account, picks a plan, and enters or chooses a payment method. Payment Labs then:
- Creates the subscription with status
CREATING, and a first checkout for the plan amount. If the plan has a trial, that checkout is for zero: the payment method is verified and saved, and nothing is charged. - When the first checkout is paid, sets the subscription to
ACTIVE, or toTRIALfor a plan with a trial, and setsnextPaymentDate. - If the first checkout fails or expires, sets the subscription to
FAILED. The buyer can open the offer again and subscribe again.
A buyer can hold only one live subscription per plan. A second attempt while one is ACTIVE or TRIAL is refused.
Step 4: Billing cycles and retries
On each nextPaymentDate, Payment Labs creates a subscription payment and charges the subscription's saved payment method. You do not call anything.
- Charge succeeds. The payment becomes
COMPLETEDandnextPaymentDatemoves forward by one cycle. When a trial ends, the first charge moves the subscription fromTRIALtoACTIVE. - Charge fails. The payment shows
FAILED, and Payment Labs retries it automatically. Payment Labs charges each cycle at most three times in total — the first attempt and two retries, at least 24 hours apart. A payment that showsFAILEDcan still succeed on a retry while the subscription isACTIVE. - All retries fail. The subscription becomes
OVERDUEand is not charged again. To resume billing, send the buyer an offer so they can subscribe again with a working payment method.
Read the cycles with List Subscription Payments. It lists charged cycles only, not zero-amount trial sign-ups, and returns 404 until the first one exists. Each payment carries the checkoutId that billed it.
Step 5: Cancel a subscription
Call Cancel Subscription. The status becomes CANCELLED and no further cycles are charged. Cycles already charged are not refunded; refund them separately.
If the buyer is still completing the first payment (status CREATING), cancelling also expires that checkout. If the payment is being processed at that moment, the cancel fails; wait until the subscription leaves CREATING and cancel again.
Buyers can also cancel from their Payment Labs buyer account.
Step 6: Refund a billing cycle
Refund the checkout that charged the cycle: take the payment's checkoutId, read succeededTransactionId with Get Checkout, and call Refund Checkout Transaction. The rules are the same as for any checkout refund. You can also use Refund Subscription Payment, which finds the charge for you but does not stop a second refund while one is in progress; see Refunds.
Find plans, offers and subscriptions
| You want | Call |
|---|---|
| One plan or offer | Get Subscription Plan, Get Plan Offer |
| One subscription | Get Subscription |
| Many, filtered and sorted | Search Subscription Plans, Search Plan Offers, Search Subscriptions. See Search, Exports and Pagination. |
| The billing cycles of a subscription | List Subscription Payments |
| Every charge attempt of one cycle, including failed retries | List Checkout Transactions on the payment's checkoutId. For a payment without a checkoutId, List Subscription Payment Transactions |
Statuses
Subscription
| Status | Meaning |
|---|---|
CREATING | The buyer is completing the first payment. |
TRIAL | In the free trial. The first charge is on nextPaymentDate. |
ACTIVE | Billing on schedule. The next charge is on nextPaymentDate. |
OVERDUE | A cycle failed every retry. Billing has stopped. |
CANCELLED | Cancelled by you or the buyer. Billing has stopped. |
FAILED | The first payment failed or expired, so the subscription never started. |
Subscription payment
| Status | Meaning |
|---|---|
PENDING | The charge for this cycle is in progress. |
COMPLETED | The cycle was paid. |
FAILED | The last attempt failed. Payment Labs keeps retrying until the subscription becomes OVERDUE. |
Plan
| Status | Meaning |
|---|---|
ACTIVE | Buyers can subscribe. |
CANCELED | Deleted with Cancel Subscription Plan. New buyers cannot subscribe; existing subscriptions keep billing. |
Plans use the spelling CANCELED and subscriptions use CANCELLED. Match both exactly.
Webhooks
| Event | Fires when |
|---|---|
subscription-status-changed | A subscription changes status, for example CREATING to ACTIVE, or ACTIVE to OVERDUE. |
subscription-payment-status-changed | A billing cycle changes status. |
refund-status-changed | A refund of a cycle changes status. |
Checkouts that Payment Labs creates for subscriptions do not send checkout-status-changed and are not returned by Search Checkouts. Use the subscription events and Get Subscription instead.
Errors and edge cases
| Response | Cause | What to do |
|---|---|---|
400 VALIDATION_ERROR | A field is missing, malformed or unknown. | Fix the fields listed in details. |
400 CURRENCY_NOT_ALLOWED, 400 MAXIMUM_AMOUNT_EXCEEDED | The plan's currency or amount is not allowed on your account. | Change the plan, or ask Payment Labs to raise the limit. |
400 EXPIRED_PLAN_OFFER | The offer's expiresAt is in the past. | Send a future date. |
400 INVALID_PLAN_OFFER | None of the subscriptionPlanIds exist on your account. | Check the plan IDs. |
404 NOT_FOUND | The plan, offer or subscription does not exist. | Check the ID. |
- Updating a plan with Update Subscription Plan changes only
name,descriptionandsort. Empty values are ignored, so you cannot clear a field. To change the price or schedule, create a new plan and offer it. - Path prefixes differ: plans, offers and subscriptions live under
/subscription, while List Subscription Payment Refunds lives under/subscriptions.
Next steps
Updated 5 days ago
What’s Next
Next: POS Terminals.
