Recurring Payments
Create and manage subscription billing with a saved card token
Recurring payments let you charge a customer on a fixed schedule using a saved card token. Once a subscription is created, Exirom handles scheduling and automatically charges on each cycle date. You receive a webhook for every charge attempt.
#How It Works
- Tokenize the card — get a
cardTokenfrom the tokenize endpoint - Create a subscription — pass the token with a
plandefining the billing schedule - First charge — happens immediately on creation (or is deferred for free trials)
- Subsequent charges — automatic on each cycle date; you receive a webhook per charge
- Manage — retrieve, update, pause, or cancel via the subscription ID
#The Plan Object
The plan defines the billing schedule:
| Field | Description |
|---|---|
amount | Decimal amount per billing cycle |
currency | ISO 4217 code (e.g. EUR) |
frequency | DAILY, WEEKLY, MONTHLY, or CUSTOM |
interval | Multiplier for frequency (e.g. MONTHLY + 3 = quarterly, CUSTOM + 45 = every 45 days) |
startDate | ISO 8601 date when billing begins |
endDate | Optional end date; omit for open-ended subscriptions |
#Deferred Start (Free Trials)
Set skipFirstCharge: true to create the subscription without an immediate charge. The subscription starts in TRIALING status and the first charge fires on plan.startDate. Use this for:
- Free trials
- Card-on-file capture before a service starts
- Future-dated billing
#3DS on Subscription Creation
3DS verification may be triggered when the subscription is created (regardless of skipFirstCharge). If required, the response returns CUSTOMER_VERIFICATION with a challengeUrl. After the customer completes the challenge, subsequent scheduled charges are merchant-initiated and typically exempt from 3DS.
#Subscription States
| Status | Meaning |
|---|---|
TRIALING | Created with skipFirstCharge=true, no charge yet |
ACTIVE | Billing is running normally |
PAUSED | Charges suspended; resume by updating status to ACTIVE |
CANCELED | No more charges will occur |
The subscription is automatically paused after 3 consecutive failed charge attempts (configurable). It is automatically cancelled when endDate is reached.
#Subscription Webhook
For every scheduled charge attempt, Exirom sends a POST to your callbackUrl with:
| Field | Description |
|---|---|
subscriptionId | The subscription identifier |
transactionId | The individual charge transaction |
chargeDate | Date this charge was attempted |
amount / currency | Amount for this cycle |
transactionStatus | SUCCEED or FAILED |
declineCode / declineReason | Set on failure |
failureCount | Consecutive failed attempts |
nextChargeDate | Next scheduled attempt |
#Sandbox Testing
| Card Number | Recurring Behavior |
|---|---|
4111111111111111 | All scheduled charges succeed |
5500000000000004 | All scheduled charges succeed |
4000000000000002 | First charge succeeds; subsequent charges decline |
4000000000003220 | First charge triggers 3DS; subsequent charges succeed |
In sandbox, the scheduler runs every 5 minutes (vs. actual scheduled dates in production).
#Related
- API Reference: POST /api/v1/payments/card/recurring — Create subscription endpoint spec, Try It
- API Reference: GET /api/v1/payments/card/recurring/{subscriptionId} — Retrieve subscription
- API Reference: PUT /api/v1/payments/card/recurring/{subscriptionId} — Update subscription
- API Reference: DELETE /api/v1/payments/card/recurring/{subscriptionId} — Cancel subscription
- Tokenizing a Card — Required before creating a subscription