Subscriptions
Ecart Pay’s Subscriptions API allows you to create and manage recurring payments for your users.
Ecart Pay's Subscriptions API allows you to create and manage recurring payments for your users. Whether you're billing daily, weekly, monthly, quarterly, semiannually, or yearly, our flexible system supports direct subscriptions, reusable subscription templates, pro-rata billing, trial periods, and automatic payment processing.
Overview
You can create a subscription for a user in three ways:
- Using a Subscription Template: Ideal when you need to apply the same subscription logic to multiple customers (e.g., gym memberships, SaaS plans).
- Creating a Subscription Directly: When you want to create a unique subscription for a specific user without saving the configuration for reuse.
- Creating Subscriptions with Advanced Features: Including pro-rata billing, specific billing cycles, trial periods, and end dates for temporary subscriptions.
Key Features
- Multiple Billing Intervals: Daily, weekly, monthly, quarterly, semiannual, and yearly
- Pro-rata Billing: Proportional charges based on specific billing cycle dates
- Trial Periods: Free trial days before the first charge
- Automatic Payment Processing: Smart payment logic when customers add payment methods
- End Date Support: Temporary subscriptions with automatic termination
- Customer Dashboard: Secure portal for customers to manage their subscriptions
- Notification System: Automatic email notification throughout the subscription lifecycle
1. Create a Subscription Template
Use a template when you want to define a reusable subscription model with parameters like billing frequency and trial period.
Endpoint
POST /api/subscriptions-template
Request Body
Field | Type | Description |
---|---|---|
amount | number | Amount to charge per interval (e.g., 100 = $100.00) |
currency | string | ISO 4217 currency code (MXN or USD ) |
interval | string | Billing interval: daily , weekly , monthly , quarterly , semiannual , or yearly |
frequency | number | Frequency multiplier (default: 1) |
service | string | Name or label for the subscription service |
trial_period_days | number | (Optional) Number of days before the first charge |
benefits | array | (Optional) List of benefits included in the subscription |
billing_cycle | object | (Optional) Specific billing cycle configuration |
end_date | string | (Optional) ISO date string for subscription termination |
Example Request
{
"amount": 299,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"service": "Premium Plan",
"trial_period_days": 14,
"billing_cycle": {
"day": 5,
"month": 1
},
"benefits": [
"Unlimited access to premium content",
"24/7 priority support",
"Exclusive 15% discounts",
"Up to 3 additional users"
]
}
Example Response
{
"account_id": "6851ef3dd0b39474707f960d",
"amount": 299,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"service": "Premium Plan",
"trial_period_days": 14,
"billing_cycle": {
"day": 5,
"month": 1
},
"benefits": [
"Unlimited access to premium content",
"24/7 priority support",
"Exclusive 15% discounts",
"Up to 3 additional users"
],
"id": "687e8679e0ceebb93d273d8f",
"created_at": "2025-01-21T18:27:05.053Z",
"updated_at": "2025-01-21T18:27:05.053Z"
}
2. Create a Subscription from a Template
Once a template is created, use it to subscribe users.
Endpoint
POST /api/subscriptions
Request Body
Field | Type | Description |
---|---|---|
template_id | string | ID of the subscription template used |
customer_id | string | ID of the customer the subscription was created for |
card_ids | array | (Optional) List of card IDs associated with the subscription |
Example Request
{
"template_id": "687e8679e0ceebb93d273d8f",
"customer_id": "6854346910775959c2173b48"
}
Example Response
{
"account_id": "6851ef3dd0b39474707f960d",
"customer_id": "6854346910775959c2173b48",
"status": "active",
"service": "Premium Plan",
"amount": 299,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"trial_period_days": 14,
"billing_cycle": {
"day": 5,
"month": 1
},
"attempts": 0,
"benefits": [
"Unlimited access to premium content",
"24/7 priority support",
"Exclusive 15% discounts",
"Up to 3 additional users"
],
"errors": [],
"card_ids": [],
"id": "687e87d3e0ceebb93d273da9",
"created_at": "2025-01-21T18:32:51.952Z",
"updated_at": "2025-01-21T18:32:51.952Z"
}
3. Create a Direct Subscription (Without Template)
Create a subscription directly without saving a reusable template. This supports all advanced features including pro-rata billing, specific billing cycles, trial periods, and end dates.
Endpoint
POST /api/subscriptions
Request Body
Field | Type | Description |
---|---|---|
customer_id | string | ID of the customer to subscribe |
amount | number | Amount to charge per interval (e.g., 299 = $299.00) |
currency | string | ISO 4217 currency code (MXN or USD ) |
interval | string | Billing interval: daily , weekly , monthly , quarterly , semiannual , or yearly |
frequency | number | Frequency multiplier (default: 1) |
service | string | Name or label for the subscription service |
trial_period_days | number | (Optional) Number of days before the first charge |
billing_cycle | object | (Optional) Specific billing cycle for pro-rata billing |
end_date | string | (Optional) ISO date string for subscription termination |
benefits | array | (Optional) List of benefits included in the subscription |
notify_url | string | (Optional) Webhook URL for payment notifications |
Example Request (Standard Subscription)
{
"customer_id": "6854346910775959c2173b48",
"amount": 599,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"service": "Business Plan",
"benefits": [
"Advanced analytics dashboard",
"Priority customer support",
"Custom integrations",
"Team collaboration tools"
]
}
Example Request (Pro-rata with Billing Cycle)
{
"customer_id": "6854346910775959c2173b48",
"amount": 1299,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"service": "Enterprise Plan",
"billing_cycle": {
"day": 15,
"month": 1
},
"trial_period_days": 7,
"end_date": "2025-12-31",
"benefits": [
"Unlimited everything",
"Dedicated account manager",
"White-label solution",
"99.9% SLA guarantee"
]
}
Example Response
{
"account_id": "6851ef3dd0b39474707f960d",
"customer_id": "6854346910775959c2173b48",
"status": "active",
"service": "Enterprise Plan",
"amount": 1299,
"currency": "MXN",
"interval": "monthly",
"frequency": 1,
"trial_period_days": 7,
"billing_cycle": {
"day": 15,
"month": 1
},
"end_date": "2025-12-31",
"attempts": 0,
"benefits": [
"Unlimited everything",
"Dedicated account manager",
"White-label solution",
"99.9% SLA guarantee"
],
"errors": [],
"card_ids": [],
"id": "687e87d3e0ceebb93d273da9",
"created_at": "2025-01-21T18:32:51.952Z",
"updated_at": "2025-01-21T18:32:51.952Z"
}
4. Subscription Management Endpoints
Get All Subscriptions
Endpoint: GET /api/subscriptions
Authorization: Bearer JWT with read_subscriptions
or write_subscriptions
scope
Query parameters for filtering:
status
: Filter by subscription status (active
,pause
,cancelled
)currency
: Filter by currency (MXN
,USD
)interval
: Filter by billing intervalcustomer_id
: Filter by customer IDcreated_from
: Filter by creation date (from)created_to
: Filter by creation date (to)
Get Single Subscription
Endpoint: GET /api/subscriptions/:id
Authorization: Bearer JWT with read_subscriptions
, write_subscriptions
, or read_single_subscription
scope
Update Subscription (Add Payment Methods)
Endpoint: PUT /api/subscriptions/:id
Authorization: Bearer JWT with write_subscriptions
scope
This is the critical endpoint where payment methods are added to a subscription. When card_ids
are added, the system automatically evaluates if payment processing should occur based on trial periods, billing cycles, and payment dates.
Request Body:
{
"card_ids": ["card_id_1", "card_id_2"]
}
Automatic Payment Logic:
- First card added triggers
shouldProcessAutomaticPayment()
evaluation - If trial period active: No charge, sets trial end date
- If billing cycle configured: Charges pro-rata amount
- If standard subscription: Charges full amount immediately
Customer Update Subscription
Endpoint: PUT /api/subscriptions/from-customer/:id
Authorization: Bearer JWT with update_single_subscription
scope
Allows customers to update their own subscriptions from the customer dashboard. This is the endpoint used by the customer portal when they add payment methods.
Request Body:
{
"card_ids": ["card_id_1"]
}
Customer Dashboard Process:
- Customer accesses subscription via email link or customer subscriptions dashboard
- Customer adds credit card in secure form
- Frontend calls this endpoint with new card_ids
- Automatic payment processing triggers based on subscription configuration
Important: The customer must have previously accessed the subscription invitation for it to appear in their subscriptions dashboard.
Resend Invitation Link
Endpoint: POST /api/subscriptions/:id/resend-invitation-link
Authorization: Bearer JWT with write_subscriptions
scope
Resends the subscription invitation email to the customer. Limited to 5 invitations per subscription with 24-hour cooldown.
Generate Session Link
Endpoint: POST /api/subscriptions/generate-session-link
Authorization: Bearer JWT with generate_subscription_session_link
scope
{
"subscription_id": "687e87d3e0ceebb93d273da9"
}
Purpose: Generates a secure link for customers to access a specific subscription dashboard. This endpoint is used internally after OTP verification to create session links.
Response:
{
"session_link": "https://sandbox.ecartpay.com/subscriptions/687e87d3e0ceebb93d273da9?_v=auth_token"
}
Note: The generated session link is identical to the one sent in invitation emails. Used by the customer portal after OTP authentication.
5. How Subscription Processing Works
Automatic Payment Flow
-
Subscription Created:
- POST
/api/subscriptions
creates subscription WITHOUT card_ids - Customer receives email invitation with secure link
- Subscription status:
active
but no payment methods
- POST
-
Customer Dashboard Access:
- Option A: Customer clicks email link for direct access
- Option B: Customer visits sandbox.ecartpay.com/subscriptions/login for OTP login
- Customer sees subscription details and payment form
-
Payment Method Addition:
- Customer adds credit card through secure form
- Frontend calls PUT
/api/subscriptions/from-customer/:id
withcard_ids
- This triggers automatic payment processing evaluation
-
Smart Processing (triggered by card_ids update):
- Trial Period: No immediate charge, sets trial dates
- Pro-rata: Charges proportional amount to next billing date
- Standard: Charges full amount immediately
- Failed Payment: Subscription continues with retry logic
Pro-rata Billing
When a subscription has a billing_cycle
, the first payment is calculated proportionally:
Formula: (total_amount / days_in_cycle) * days_until_next_billing_date
Example: Monthly subscription with billing_cycle.day = 5
created on January 15th:
- Charges proportional amount from January 15th to February 5th
- Sets
next_payment_date = February 5th
- Future payments charge full amount every 5th of the month
Trial Periods
- With Trial: No immediate charge, establishes trial end date
- Trial + Pro-rata: After trial, first charge is proportional to billing cycle
- Trial End: Automatic charge processing when trial period expires
Recurring Payments
- Worker Process: Automatically processes payments for subscriptions with
next_payment_date <= today
- Error Handling: Multiple retry attempts with notifications
- End Date Support: Automatic termination for temporary subscriptions
6. Billing Cycle Configuration
Weekly Billing Cycle
{
"billing_cycle": {
"day": 1, // 1=Monday, 2=Tuesday, ..., 7=Sunday
"month": 1 // Not used but required
}
}
Monthly/Quarterly/Semiannual/Yearly Billing Cycle
{
"billing_cycle": {
"day": 15, // Day of month (1-31)
"month": 3 // Month of year (1-12)
}
}
Important Notes
billing_cycle
is immutable after creation- System automatically handles short months (e.g., day 31 in February becomes day 28/29)
billing_cycle
is optional - subscriptions without it work as before- Not supported for
daily
interval
7. Notification System
Automatic Notifications
Events:
create
: Subscription invitation sent to customersuccess
: First successful paymentretry_success
: Payment successful after previous failuresfailure
: Payment failure (attempt 2)final_failure
: Multiple failures, subscription paused
Channels:
- Email: Always sent if customer has email
Limits:
- Maximum 5 invitation emails per subscription
- 24-hour cooldown between resend attempts
Customer Access Methods
Method 1: Direct Email Link (Invitation)
- Customer receives invitation email after subscription creation
- Email contains direct link to specific subscription dashboard
- Immediate access to that subscription without additional verification
Method 2: Customer Portal Login
- Customer visits
app.ecartpay.com/subscriptions/login
- Enters email address for OTP verification
- Uses OTP endpoints to access all their subscriptions
- Note: Only subscriptions whose invitations have been previously accessed will be visible
Customer Dashboard Features
- Secure Access: Two-method authentication system
- Subscription Details: Plan information, benefits, status, pricing
- Payment Management: Add credit cards (triggers automatic payment processing)
- Billing History: View past and upcoming payments
- Cancellation: Self-service subscription cancellation
OTP Authentication Flow
Endpoints for Customer Login:
POST /api/notifications/otp-send
- Send OTP code to customer emailPOST /api/notifications/otp-verification
- Verify OTP code
Process:
- Customer visits
/subscriptions/login
- Enters email address
- System sends OTP via
otp-send
endpoint - Customer enters OTP code
- System verifies via
otp-verification
endpoint - Customer gets authenticated token for session management
8. Error Handling & Status Management
Subscription States
- Active: Subscription is functioning normally
- Pause: Temporarily paused due to payment failures (≥5 attempts)
- Cancelled: Permanently terminated
Payment Retry Logic
- Attempt 1: Continue normally
- Attempt 2: Send failure notification
- Attempts 3-4: Continue retrying
- Attempt 5: Pause subscription, send final notification
Validation Rules
customer_id
must exist and belong to the accountamount
must be positive numbercurrency
must beMXN
orUSD
end_date
must be future datebilling_cycle.day
must be 1-31billing_cycle.month
must be 1-12 (except weekly)card_ids
maximum 5 cards per subscription
9. Complete Implementation Example
Step-by-Step: Creating a Standard Monthly Subscription
Let's walk through a complete example of implementing a monthly subscription for a "Premium Plan" at $29.99/month:
Step 1: Create the Subscription
POST https://api.ecartpay.com/api/subscriptions
Authorization: Bearer your_jwt_token
Content-Type: application/json
{
"customer_id": "cust_abc123",
"amount": 29.99,
"currency": "USD",
"interval": "monthly",
"frequency": 1,
"service": "Premium Plan",
"benefits": [
"Unlimited access",
"Priority support",
"Advanced features"
]
}
What happens:
- ✅ Subscription created with status "active"
- ✅ Customer receives invitation email automatically
- ✅ No payment methods yet, so no charges
- ✅ Response includes subscription ID
Step 2: Customer Receives Email
The customer gets an email with:
- Subject: "Subscription Invitation - Premium Plan"
- Secure link:
https://sandbox.ecartpay.com/subscriptions/sub_xyz789?_v=secure_token
- Instructions to complete setup
Step 3: Customer Accesses Dashboard
Customer clicks email link and sees:
- Subscription details (Premium Plan, $29.99/month)
- List of benefits
- Secure payment form to add credit card
- Terms and conditions
Step 4: Customer Adds Payment Method
Customer fills out credit card form. Frontend calls:
PUT https://api.ecartpay.com/api/subscriptions/from-customer/sub_xyz789
Authorization: Bearer customer_token
Content-Type: application/json
{
"card_ids": ["card_def456"]
}
What happens automatically:
- ✅ System evaluates
shouldProcessAutomaticPayment()
- ✅ Since no trial period: charges $29.99 immediately
- ✅ Sets
next_payment_date
= today + 1 month - ✅ Customer receives "Payment Successful" notification
- ✅ Subscription is now fully active with payment method
Step 5: Recurring Payments (Automatic)
Every month on the billing date:
- ✅ Worker finds subscription with
next_payment_date <= today
- ✅ Charges $29.99 to stored card
- ✅ Updates
next_payment_date
= next month - ✅ If successful: customer gets receipt
- ✅ If failed: retry logic starts
Alternative: Customer Login Flow
If customer loses the email, they can:
-
Visit login page:
https://app.ecartpay.com/subscriptions/login
-
Request OTP:
POST https://api.ecartpay.com/api/notifications/otp-send Content-Type: application/json { "email": "[email protected]" }
-
Verify OTP:
POST https://api.ecartpay.com/api/notifications/otp-verification Content-Type: application/json { "email": "[email protected]", "otp": "123456" }
-
Generate session link:
POST https://api.ecartpay.com/api/subscriptions/generate-session-link Authorization: Bearer otp_verified_token { "subscription_id": "sub_xyz789" }
-
Access subscription dashboard with generated link
Pro-rata Example
For a subscription with billing cycle on the 15th of each month, created on January 10th:
-
Same creation process but with:
{ "billing_cycle": { "day": 15, "month": 1 } }
-
When customer adds payment method:
- Charges:
($29.99 / 31 days) * 5 days
= $4.84 (Jan 10-15) - Sets
next_payment_date
= January 15th - Future payments: Full $29.99 every 15th
- Charges:
This complete flow ensures customers can successfully subscribe and manage their payments through either email invitation or the customer portal.
Updated about 1 month ago