Create Subscription
Subscriptions are scheduled payments for products or services that recur over time. For example, a customer paying automatically for a monthly software plan, membership, or service package.
Create a subscription to enable recurring billing for your customers. When a customer subscribes to a plan, billing follows the plan interval. Card subscriptions can be charged automatically, while manual payment methods such as mobile money or bank transfer require checkout/payment authorization for each billing cycle.
Subscriptions support both Local Currency and Settlement Currency plans. For Settlement Currency plans, the system handles currency conversion at charge time.
Payment Methods
| Payment Method | Behavior | Use Case |
|---|---|---|
| card (default) | Auto-recurring. Charges happen automatically each cycle after card authorization. | SaaS subscriptions, memberships |
| mobile_money | Manual. Customer must pay via checkout each cycle. Merchant triggers POST /v1/subscriptions/charge. | Mobile money users in Africa (GHS, KES. XOF) |
| bank_transfer | Manual. Same as mobile_money. | Bank transfer customers |
| bank | Manual. Same as mobile_money. | Bank account payments |
Subscription Details
| Field | Data type | Required | Description |
|---|---|---|---|
| planCode | string | Yes | The plan code. Get this from the plan creation response |
| customer | string | Yes | Customer's email address. A new customer will be created if they don't exist |
| card | string | No | Specific card authorization code to use. If not provided, the customer's most recent active card is used |
| startDate | date | No | Manually set the first billing date. ISO 8601 format (e.g., 2024-01-15T00:00:00Z). If not provided, defaults to current date. Use this when you want to start charge on a particular date |
| paymentMethod | string | No | Payment collection method. Values: card (default), mobile_money, bank_transfer, bank |
| redirectUrl | string | No | Custom URL for redirection |
| invoiceLimit | number | No | Maximum number of successful billing cycles. If omitted, billing continues until cancelled. |
| maxRetryCount | number | No | Maximum retry attempts for failed card renewals. Defaults to 3. |
| gracePeriodDays | number | No | Number of days before a failed renewal is cancelled. Defaults to 3. |
After collecting the necessary subscription details. Make a POST request to our subscription endpoint.
Note : Before making a post request, the secret key should be specified in the header.
-H "x-api-key: your_secret_key".
{{host}}/v1/subscriptions
You can make API calls using this sample request. once all parameters are meet you would also get the response below;
{
"planCode": "PLN_xxx",
"customer": "[email protected]",
"paymentMethod": "card",
"redirectUrl": "https://merchant.com/thank-you",
"invoiceLimit": 12,
"maxRetryCount": 3,
"gracePeriodDays": 3
}
{
"data": {
"customer": {
"email": "[email protected]",
"currency": "GHS",
"currencyCode": "GHS",
"mode": "test",
"firstName": null,
"lastName": null,
"phoneNumber": null,
"customerCode": null,
"bvn": null,
"id": "9e8964a8-6133-46bc-aef2-984a85d97442",
"customerType": "INDIVIDUAL",
"active": true,
"createdAt": "2026-05-02T10:47:38.627Z",
"updatedAt": "2026-05-02T10:47:38.627Z",
"version": 1
},
"plan": {
"id": "9a8c940c-7d51-4ed2-b626-c41160bb9ec6",
"name": "Mini V8",
"description": "Full access to all features",
"interval": "daily",
"amount": "0.0000000000",
"settlementAmount": "1000.0000000000",
"settlementCurrency": "USD",
"code": "PLN_AVJWk-DkmsN779g",
"mode": "test",
"sendSms": false,
"sendInvoices": false,
"limit": "0.0000000000",
"hostedPage": false,
"isActive": true,
"createdAt": "2026-05-02T10:44:49.813Z",
"updatedAt": "2026-05-02T10:44:49.813Z",
"deletedAt": null,
"version": 1
},
"code": "SUB_ujQW_XPtNO0loYu",
"startDate": "2026-05-02T10:47:38.664Z",
"nextPaymentDate": "2026-05-03T10:47:38.664Z",
"isActive": false,
"status": "PENDING",
"invoiceLimit": null,
"maxRetryCount": 3,
"gracePeriodDays": 3,
"mode": "test",
"previousPaymentDate": null,
"cronExpression": null,
"cronJobId": null,
"pastDueAt": null,
"nextRetryAt": null,
"cancelledAt": null,
"cancelReason": null,
"currentPeriodStart": null,
"currentPeriodEnd": null,
"id": "89b4f03e-e2b2-40d7-bdac-ec5f99189366",
"retryCount": 0,
"invoicesPaid": 0,
"createdAt": "2026-05-02T10:47:38.627Z",
"updatedAt": "2026-05-02T10:47:38.627Z",
"deletedAt": null,
"version": 1,
"authorizationUrl": "https://checkout.paystack.com/r194e8rq81zydua",
"accessCode": "r194e8rq81zydua",
"reference": "KYSHI-1777718858674"
},
"status": true,
"message": "Success",
"code": 201
}
Card Subscription Flow
If the customer has a reusable card authorization
- The subscription is created.
- If the subscription starts immediately, the first charge is attempted.
- If payment succeeds, the subscription becomes ACTIVE.
- Future charges are attempted automatically according to the plan interval.
If the customer does not have a reusable card authorization
- An
authorizationUrlmay be returned. - Redirect the customer to complete card authorization.
- After successful authorization/payment, the subscription can become ACTIVE.
If the card charge fails
- The subscription becomes PAST_DUE.
isActivebecomesfalse.- The system retries according to
maxRetryCountandgracePeriodDays. - If retries fail after the grace period, the subscription becomes CANCELLED.
Manual Payment Flow
Supported channels
mobile_moneybank_transferbank
Flow
- The subscription is created.
- A checkout/payment URL may be returned when payment is due.
- The customer must complete payment manually.
- The subscription becomes ACTIVE only after successful payment confirmation.
- Future cycles require a new payment attempt through the charge flow.
Error Responses
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body |
| 422 | UNPROCESSABLE_ENTITY | Plan not found |
| 422 | UNPROCESSABLE_ENTITY | Customer already has an active subscription to this plan |
| 422 | UNPROCESSABLE_ENTITY | No card attached (card payment method) |
| 422 | UNPROCESSABLE_ENTITY | No FX rate found for settlement currency conversion |
Access Rule
Use both status and isActive to decide whether the customer should have access.
Grant Access When
status = ACTIVEandisActive = true
Do NOT Grant Access When the Subscription Is
PAST_DUECANCELLEDCOMPLETED
Statuses
| Status | Meaning |
|---|---|
| ACTIVE | Subscription is active and customer should have access. |
| PAST_DUE | A renewal payment failed. Customer should not have access until payment succeeds. |
| NON_RENEWING | Subscription remains active for the current paid period but will not renew. |
| COMPLETED | Subscription has completed all billing cycles. |
| CANCELLED | Subscription has been cancelled and will not be charged again. |
Updated 1 day ago
