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

FieldTypeDescription
amountnumberAmount to charge per interval (e.g., 100 = $100.00)
currencystringISO 4217 currency code (MXN or USD)
intervalstringBilling interval: daily, weekly, monthly, quarterly, semiannual, or yearly
frequencynumberFrequency multiplier (default: 1)
servicestringName or label for the subscription service
trial_period_daysnumber(Optional) Number of days before the first charge
benefitsarray(Optional) List of benefits included in the subscription
billing_cycleobject(Optional) Specific billing cycle configuration
end_datestring(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

FieldTypeDescription
template_idstringID of the subscription template used
customer_idstringID of the customer the subscription was created for
card_idsarray(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

FieldTypeDescription
customer_idstringID of the customer to subscribe
amountnumberAmount to charge per interval (e.g., 299 = $299.00)
currencystringISO 4217 currency code (MXN or USD)
intervalstringBilling interval: daily, weekly, monthly, quarterly, semiannual, or yearly
frequencynumberFrequency multiplier (default: 1)
servicestringName or label for the subscription service
trial_period_daysnumber(Optional) Number of days before the first charge
billing_cycleobject(Optional) Specific billing cycle for pro-rata billing
end_datestring(Optional) ISO date string for subscription termination
benefitsarray(Optional) List of benefits included in the subscription
notify_urlstring(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 interval
  • customer_id: Filter by customer ID
  • created_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:

  1. Customer accesses subscription via email link or customer subscriptions dashboard
  2. Customer adds credit card in secure form
  3. Frontend calls this endpoint with new card_ids
  4. 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

  1. Subscription Created:

    • POST /api/subscriptions creates subscription WITHOUT card_ids
    • Customer receives email invitation with secure link
    • Subscription status: active but no payment methods
  2. 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
  3. Payment Method Addition:

    • Customer adds credit card through secure form
    • Frontend calls PUT /api/subscriptions/from-customer/:id with card_ids
    • This triggers automatic payment processing evaluation
  4. 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 customer
  • success: First successful payment
  • retry_success: Payment successful after previous failures
  • failure: 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 email
  • POST /api/notifications/otp-verification - Verify OTP code

Process:

  1. Customer visits /subscriptions/login
  2. Enters email address
  3. System sends OTP via otp-send endpoint
  4. Customer enters OTP code
  5. System verifies via otp-verification endpoint
  6. 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

  1. Attempt 1: Continue normally
  2. Attempt 2: Send failure notification
  3. Attempts 3-4: Continue retrying
  4. Attempt 5: Pause subscription, send final notification

Validation Rules

  • customer_id must exist and belong to the account
  • amount must be positive number
  • currency must be MXN or USD
  • end_date must be future date
  • billing_cycle.day must be 1-31
  • billing_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:

  1. Visit login page:

    https://app.ecartpay.com/subscriptions/login
  2. Request OTP:

    POST https://api.ecartpay.com/api/notifications/otp-send
    Content-Type: application/json
    
    {
        "email": "[email protected]"
    }
  3. Verify OTP:

    POST https://api.ecartpay.com/api/notifications/otp-verification
    Content-Type: application/json
    
    {
        "email": "[email protected]",
        "otp": "123456"
    }
  4. Generate session link:

    POST https://api.ecartpay.com/api/subscriptions/generate-session-link
    Authorization: Bearer otp_verified_token
    
    {
        "subscription_id": "sub_xyz789"
    }
  5. 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:

  1. Same creation process but with:

    {
        "billing_cycle": {
            "day": 15,
            "month": 1
        }
    }
  2. 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

This complete flow ensures customers can successfully subscribe and manage their payments through either email invitation or the customer portal.