Subscriptions
Subscriptions allow you to link customers to your existing plans. With this API, you can integrate a subscription system into your platform, facilitating customer enrollment, renewal, and cancellation in different subscription plans.
Subscription Lifecycle
The following diagram illustrates the different states a subscription can go through and the transitions between them, based on events like successful or failed payments, or administrative actions.
| # | Action | Transition |
|---|---|---|
| 1 | A subscription was successfully created. | Start → Active |
| 2 | Successful recurring payment execution. | Active/Pending → Active |
| 3 | The administrator blocked the subscription. | Active → Blocked |
| 4 | The administrator unblocked the subscription. | Blocked → Active |
| 5 | The buyer deactivated their subscription. | Active → Inactive |
| 6 | Recurring payment error (daily/weekly) - attempts = 1. | Active → Inactive |
| 7 | The subscription link is invalid (expired, inactive, or deleted). | Active/Blocked/Pending → Inactive |
| 8 | Recurring payment error (monthly/annual) - attempts <= 2. | Active → Pending |
| 9 | Recurring payment error (monthly/annual) - attempts = 3. | Pending → Inactive |
| 10 | Error creating a subscription. | Start → Error |
Features
To access the API, it is necessary to authenticate each request with a token, see Authentication.
📌 Create subscriptions for a customer to a specific plan.
- Base URL:
https://api-sandbox.n1co.shop - Method:
POST - Endpoint:
/api/v3/Subscriptions - Description: Create subscription.
- Required Headers:
Content-Type: application/jsonAuthorization: Bearer {your_token}- Example:
- Request
- Response
{
"planId": 1544,
"customer": {
"id": "Customer001",
"name": "Carlos Dúran",
"email": "[email protected]",
"phoneNumber": "+50364331900"
},
"paymentMethod": {
"id": "689f93049b36afba505e7bc8"
},
"backupPaymentMethod": {
"id": "689f69319b36afba505e7bc0"
},
"authenticationId": null,
"billingInfo": {
"countryCode": "string",
"stateCode": "string",
"zipCode": "string"
},
"locationCode": "N1C0CD001"
}
{
"status": "SUCCEEDED",
"message": "The payment was made successfully",
"error": null,
"authentication": null,
"subscription": {
"subscriptionId": 481,
"planId": 1544,
"name": "ePay Plan",
"description": "ePay subscription description",
"created": "2025-10-24T21:22:47.7452894Z",
"amount": 45.9900,
"amountFormatted": "$45.99",
"billingCycle": 1,
"billingCycleType": "Month",
"currencyCode": "USD",
"locale": "es-SV",
"currentPeriodStart": "2025-10-24T21:22:47.4571820Z",
"currentPeriodEnd": "2025-10-25T21:22:47.4571820Z",
"timezone": "America/El_Salvador",
"subscriptionStatus": "Active",
"customer": {
"name": "Carlos Dúran",
"email": "[email protected]",
"phone": "+50364331900",
"paymentMethodName": "TEST 001",
"paymentMethodCardBrand": "visa",
"paymentMethodBin": "400000",
"paymentMethodLastDigits": "2701",
"backupPaymentMethodName": "TEST 002",
"backupPaymentMethodCardBrand": "visa",
"backupPaymentMethodBin": "424242",
"backupPaymentMethodLastDigits": "4242"
}
},
"payment": {
"chargeId": "676a97bb-f19e-4311-aac7-b9c6911c3a1d",
"authorizationCode": "831000"
}
}
You will need test card data →, this documentation guides you through valid test scenarios for the sandbox environment.
Before making a charge, you must create a payment method →. After creating the payment method, the ID must be used in the paymentMethod→id (Required) field or the backupPaymentMethod→id (Optional) field, these must be different.
- Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
planId | integer | ✅ | Subscription plan ID |
customer | object | ✅ | Customer information |
customer.id | string | ❌ | Unique customer identifier |
customer.name | string | ✅ | Customer's full name |
customer.email | string | ✅ | Customer's email |
customer.phoneNumber | string | ❌ | Phone number with country code |
paymentMethod | object | ✅ | Primary payment method |
paymentMethod.id | string | ✅ | ID of the token returned in tokenization |
backupPaymentMethod | object | ❌ | Backup payment method |
backupPaymentMethod.id | string | Conditional* | Token ID (must be different from the primary). Required only if backupPaymentMethod is provided |
authenticationId | string | ❌ | 3DS authentication ID (null on first request) |
billingInfo | object | Conditional* | Billing information, can be null |
billingInfo.countryCode | string | Conditional* | Country code |
billingInfo.stateCode | string | Conditional* | State code |
billingInfo.zipCode | string | Conditional* | Zip code |
locationCode | string | ✅ | Branch code, obtained from Portal → Settings → Branches → Edit → below the Phone field |
The billingInfo object is required only when the card's issuing country is USA or CAN. You can determine this from the BIN's country code of the payment method.
You can find the locationCode in the portal when editing your branch, right below the phone number. Do not confuse with locationId.
- Response Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | Charge status (FAILED, SUCCEEDED, AUTHENTICATION_REQUIRED) |
message | string | Result description |
error | object | Error code and message (when applicable) |
authentication | object | 3DS authentication URL and ID (when applicable) |
subscription | object | Information of the created subscription |
payment | object | Information of the payment made |
- Subscription Statuses
1. FAILED
The payment process has failed. The error node will contain the details.
Details
View response example
{
"status": "FAILED",
"message": "The payment could not be processed: We need more validations, please contact customer service at +50324086126. Id: 1b44231a-1cfc-424d-9573-0a3a3ff756bd",
"error": {
"code": "FRAUD_PREVENT",
"message": "We need more validations, please contact customer service at +50324086126",
"title": "Transaction Error",
"detail": "We need more validations, please contact customer service at +50324086126"
},
"authentication": null,
"subscription": null,
"payment": null
}
2. SUCCEEDED
The payment process was completed successfully.
Details
View response example
{
"status": "SUCCEEDED",
"message": "The payment was made successfully",
"error": null,
"authentication": null,
"subscription": {
"subscriptionId": 481,
"planId": 1544,
"name": "ePay Plan",
"description": "ePay subscription description",
"created": "2025-10-24T21:22:47.7452894Z",
"amount": 45.9900,
"amountFormatted": "$45.99",
"billingCycle": 1,
"billingCycleType": "Month",
"currencyCode": "USD",
"locale": "es-SV",
"currentPeriodStart": "2025-10-24T21:22:47.4571820Z",
"currentPeriodEnd": "2025-10-25T21:22:47.4571820Z",
"timezone": "America/El_Salvador",
"subscriptionStatus": "Active",
"customer": {
"name": "Carlos Dúran",
"email": "[email protected]",
"phone": "+50364331900",
"paymentMethodName": "TEST 001",
"paymentMethodCardBrand": "visa",
"paymentMethodBin": "400000",
"paymentMethodLastDigits": "2701",
"backupPaymentMethodName": "TEST 002",
"backupPaymentMethodCardBrand": "visa",
"backupPaymentMethodBin": "424242",
"backupPaymentMethodLastDigits": "4242"
}
},
"payment": {
"chargeId": "676a97bb-f19e-4311-aac7-b9c6911c3a1d",
"authorizationCode": "831000"
}
}
3. AUTHENTICATION_REQUIRED
If the status is AUTHENTICATION_REQUIRED, the API will return an authentication URL. You must guide the user through this flow (in this case, using an iframe is necessary).
For a detailed guide on how to implement the iframe and handle the 3DS flow, see our 3D Secure Authentication documentation.
Details
View response example
{
"status": "AUTHENTICATION_REQUIRED",
"message": "Payment requires 3DS authentication",
"error": null,
"authentication": {
"url": "https://front-3ds.h4b.dev/authentication/9b77e558-7d5d-4fdd-b84c-f295225ba2e1?showBranding=True&lang=es",
"id": "9b77e558-7d5d-4fdd-b84c-f295225ba2e1"
},
"subscription": null,
"payment": {
"chargeId": null,
"authorizationCode": null
}
}
📌 Query the details of a subscription
- Base URL:
https://api-sandbox.n1co.shop - Method:
GET - Endpoint:
/api/v3/Subscriptions/{subscriptionId} - Description: Gets the information of a subscription.
- Required Headers:
Authorization: Bearer {your_token}- Response Example:
- Response
{
"subscriptionId": 480,
"planId": 1544,
"name": "ePay Plan",
"description": "ePay subscription description",
"created": "2025-10-15T21:36:26.9682946Z",
"amount": 45.9900,
"amountFormatted": "$45.99",
"billingCycle": 1,
"billingCycleType": "Month",
"currencyCode": "USD",
"locale": "es-SV",
"currentPeriodStart": "2025-10-16T21:36:26.7660968Z",
"currentPeriodEnd": "2025-11-16T21:36:26.7660968Z",
"timezone": "America/El_Salvador",
"subscriptionStatus": "Active",
"customer": {
"name": "Carlos Dúran",
"email": "[email protected]",
"phone": "+50364331900",
"paymentMethodName": "TEST 001",
"paymentMethodCardBrand": "visa",
"paymentMethodBin": "400000",
"paymentMethodLastDigits": "2701",
"backupPaymentMethodName": "TEST 002",
"backupPaymentMethodCardBrand": "visa",
"backupPaymentMethodBin": "424242",
"backupPaymentMethodLastDigits": "4242"
}
}
📌 Query the orders of a subscription.
- Base URL:
https://api-sandbox.n1co.shop - Method:
GET - Endpoint:
/api/v3/Subscriptions/{subscriptionId}/orders - Description: Gets the details of the orders made in a subscription.
- Required Headers:
Authorization: Bearer {your_token}- Response Example:
- Response
[
{
"subscriptionId": 475,
"planId": 576,
"orderId": 49068,
"orderName": "ePay Plan",
"total": 10.9900,
"orderStatus": "Finalized",
"createdDate": "2025-08-27T02:00:52.8551023Z",
"createdBy": "c8573b9a-88ea-45b6-aef4-4817440f2cc9"
},
{
"subscriptionId": 475,
"planId": 576,
"orderId": 49096,
"orderName": "ePay Plan",
"total": 10.9900,
"orderStatus": "Finalized",
"createdDate": "2025-09-27T02:00:52.8551023Z",
"createdBy": "c8573b9a-88ea-45b6-aef4-4817440f2cc9"
}
]
📌 Manage subscription cancellations.
- Base URL:
https://api-sandbox.n1co.shop - Method:
POST - Endpoint:
/api/v3/Subscriptions/{subscriptionId}/cancel - Description: Cancel a subscription.
- Required Headers:
Content-Type: application/jsonAuthorization: Bearer {your_token}- Example:
- Request
- Response
{
"reason": "Customer no longer wants the service"
}
468 //subscriptionId that was canceled