RapidCents Developer Documentation
Recurring Payments & Subscriptions Guide
v1.0 · REST API

Recurring Payments

Subscriptions & installments · Automated billing · Card on file · Retry logic

Summary

Recurring Payments (Subscriptions) allow merchants to set up automated billing cycles for customers. Merchants can create open-ended subscriptions or fixed installment plans with configurable frequencies ranging from weekly to annual. The card can be entered by the merchant or by the customer via a hosted payment page.

🔁

RapidCents automatically charges stored cards on the scheduled billing date, sends success/decline notifications to both parties, and retries failed payments on a configurable schedule.

Subscription Lifecycle

  1. Create — Merchant creates a subscription with amount, customer, frequency, start date, and optionally a card. If the merchant enters the card, the subscription is active immediately.
  2. Customer Activation — If the customer enters the card, they receive an email with a link to the hosted page. The customer enters card details and the subscription becomes active.
  3. Scheduled Billing — The billing engine runs daily, identifies subscriptions due for charging, and adds them to the payment queue.
  4. Charge — The payment queue processor charges the stored card. On success, the bill count increments and notifications are sent. On decline, a retry is scheduled.
  5. Completion / Cancellation — Installment plans complete after the specified number of bills. Subscriptions continue until manually cancelled.

Subscription Statuses

INACTIVE (Awaiting Card)

Customer-entered card flow: subscription is created but waiting for the customer to provide card details.

ACTIVE

Subscription is active and will be charged on the next billing date. Card is on file.

CANCELLED

Subscription has been cancelled. No further charges will be made.

Processing Flow

Merchant-Entered Card

MerchantCreates & Enters Card
RapidCentsStores Card & Schedules
Billing EngineDaily Scheduler
Visa · Mastercard · Discover · Amex

Customer-Entered Card

MerchantCreates Subscription
RapidCentsSends Email
CustomerEnters Card Details
Billing EngineDaily Scheduler
Visa · MastercardDiscover · Amex

Authentication

Merchant API (Private)

Authorization: Bearer {access_token}
Content-Type: application/json

Base URL pattern: /api/{business_id}/recurring_payments

Customer API (Public)

Public endpoints do not require authentication:

GET  /api/recurring_payments/{subscription_id}/subscribe
POST /api/recurring_payments/{subscription_id}/subscribe
PUT  /api/recurring/cancel

Create Subscription

POST /api/{business}/recurring_payments

Request Body

FieldTypeRequiredDescription
amountnumberYesCharge amount per billing cycle
customerIdstring (UUID)YesCustomer who will be billed
startDatedateYesFirst charge date
sequenceintegerYesBilling frequency (1–6, see Frequency Options)
cardEntryByMerchantbooleanYestrue = merchant enters card, false = customer enters card
isInstallmentbooleanNotrue = installment plan with fixed number of payments
numberOfBillsintegerIf installmentTotal number of payments in the installment plan
endDatedateNoEnd date for the subscription
merchant_descriptionstringNoDescription visible to merchant and customer
threeDSecurebooleanNoEnable 3D Secure for customer card entry. Default: true
cardDataobjectIf merchant & new cardCard details (see below)
selectedCardIdstring (UUID)If merchant & saved cardID of a previously stored card

Card Data (when merchant enters a new card)

FieldTypeRequiredDescription
cardData.cardNumberstringYesFull card number
cardData.nameOnCardstringYesCardholder name
cardData.monthstringYesExpiry month (01–12)
cardData.yearstringYesExpiry year
cardData.cvvstringYesSecurity code
Request — Customer-Entered Card
POST /api/{business}/recurring_payments
Content-Type: application/json
Authorization: Bearer {token}

{
  "amount": 99.99,
  "customerId": "customer-uuid",
  "startDate": "2026-03-01",
  "sequence": 3,
  "cardEntryByMerchant": false,
  "merchant_description": "Monthly membership",
  "threeDSecure": true
}
Response — 200 OK
{
  "ok": true,
  "message": "Subscription created successfully",
  "subscription": {
    "id": "subscription-uuid",
    "amount": 99.99,
    "is_active": 0,
    "sequence": 3,
    "start_date": "2026-03-01"
  }
}

List Subscriptions

GET /api/{business}/recurring_payments

Returns a paginated list of all subscriptions for the business.

Response — 200 OK
{
  "ok": true,
  "recurring_payments": { /* paginated collection */ },
  "filters": {
    "fromDate": "2026-01-01",
    "toDate": "2026-02-19",
    "perPage": 10
  }
}

Get Subscription Details

GET /api/{business}/recurring_payments/{subscription}

Update Subscription

PUT /api/{business}/recurring_payments/{subscription}

Updates subscription details such as amount, frequency, or description.

Delete Subscription

DELETE /api/{business}/recurring_payments/{subscription}

Resend Notification

POST /api/{business}/recurring_payments/{subscription}/resend

Re-sends the subscription activation email to the customer.

Export Subscriptions

GET /api/{business}/recurring_payments/export

Returns all subscriptions matching the filter criteria for export purposes.

View Subscription (Public)

GET /api/recurring_payments/{subscription}/subscribe

Loads the subscription details for the customer to view and activate by entering card details.

Response — 200 OK
{
  "ok": true,
  "payload": {
    "reoccurringPayment": {
      "id": "subscription-uuid",
      "amount": 99.99,
      "sequence": 3,
      "start_date": "2026-03-01"
    },
    "invoice": null,
    "business": {
      "dbaName": "Acme Corp",
      "address": { /* ... */ }
    },
    "customerEmail": "[email protected]",
    "logo": "https://s3.amazonaws.com/..."
  }
}

Activate Subscription (Public)

POST /api/recurring_payments/{subscription}/subscribe

Customer submits card details to activate the subscription. The card is stored securely and the subscription becomes active.

Request Body

FieldTypeRequiredDescription
cardData.cardNumberstringYesFull card number
cardData.nameOnCardstringYesCardholder name
cardData.monthstringYesExpiry month (01–12)
cardData.yearstringYesExpiry year
cardData.cvvstringYesSecurity code
Response — 200 OK
{
  "ok": true,
  "payload": {
    "subscription": {
      "id": "subscription-uuid",
      "is_active": 1,
      "card_id": "stored-card-uuid"
    }
  }
}

Cancel Subscription (Public)

PUT /api/recurring/cancel

Request Body

FieldTypeRequiredDescription
idstring (UUID)YesSubscription ID to cancel
Response — 200 OK
{
  "ok": true,
  "message": "Subscription cancelled successfully"
}

Frequency Options

Sequence ValueLabelInterval
1WeeklyEvery 1 week
2Bi-WeeklyEvery 2 weeks
3MonthlyEvery 1 month
4QuarterlyEvery 3 months
5Twice a YearEvery 6 months
6AnnualEvery 12 months

Scheduling & Payment Queue

RapidCents uses a two-stage billing engine to process recurring payments:

Stage 1 — Subscription Scheduler

The handle:subscriptions command runs daily and evaluates all active subscriptions. For each subscription:

  • Calculates the next billing date from last_transaction_date (or start_date) and sequence
  • If today is the billing date and no queue entry exists, creates a PaymentQueue record with status PENDING
  • Skips subscriptions that have reached their installment limit

Stage 2 — Payment Queue Processor

The app:handle-payment-queue command processes all pending queue items:

  • Charges the stored card via Visa, Mastercard, Discover, or Amex
  • On success: marks the queue item as FULFILLED, increments number_of_paid_bills, sends success notification
  • On decline: increments the retry counter, updates last_failed_attempt_at, sends decline notification

Retry Logic

When a payment is declined, the system automatically retries based on a configurable strategy.

AttemptDelayDescription
1st attemptDay 0Initial charge on the billing date
2nd attempt+3 daysFirst retry after 3 days
3rd attempt+3 daysSecond retry after 6 days total
4th attempt+3 daysFinal retry after 9 days total

The retry strategy is encoded as "0 3 3 3" where each number represents the number of days before the next attempt. Both merchant and customer receive email notifications for each failed attempt.

Card on File

Recurring payments use securely stored card tokens. The card can be stored in two ways:

  • Merchant-entered card: The card is tokenized at subscription creation time and linked to the subscription.
  • Customer-entered card: The customer enters card details via the hosted page, which are tokenized and stored.
  • Existing saved card: The merchant can select a previously stored card using selectedCardId.

All subsequent charges use the stored card token — the raw card data is never stored or re-transmitted.

All Endpoints

Merchant Endpoints (Authenticated)

MethodEndpointDescription
GET/api/{business}/recurring_paymentsList subscriptions
POST/api/{business}/recurring_paymentsCreate subscription
GET/api/{business}/recurring_payments/{id}Get details
PUT/api/{business}/recurring_payments/{id}Update subscription
DELETE/api/{business}/recurring_payments/{id}Delete subscription
POST/api/{business}/recurring_payments/{id}/resendResend notification
GET/api/{business}/recurring_payments/exportExport subscriptions

Public Endpoints (No Authentication)

MethodEndpointDescription
GET/api/recurring_payments/{id}/subscribeView subscription page
POST/api/recurring_payments/{id}/subscribeActivate subscription
PUT/api/recurring/cancelCancel subscription

Notifications

EventRecipientSubjectContent
Subscription created (customer card)CustomerYour Recurring payment is ReadyAmount, frequency, “Pay Now” link
Subscription created (merchant card)CustomerYour Upcoming Recurring Payment & InvoiceAmount, frequency, PDF invoice attachment
Payment successCustomerYour Subscription Payment Was SuccessfulAmount, card, installment info, transaction date
Payment successMerchantSubscription Payment Received from {customer}Amount, card, installment info, transaction date
Payment declinedCustomerYour Subscription Payment Was DeclinedDecline reason, attempt count
Payment declinedMerchantSubscription Payment Failed for {customer}Decline reason, attempt count

Error Handling

HTTP CodeScenarioDescription
422Validation errorMissing or invalid required fields
404Not foundSubscription does not exist
403Contract unsignedLinked contract must be signed before activation
500Server errorUnexpected processing error