Skip to content
API DocsDocs

Recurring Payments

Create and manage subscription billing with a saved card token

3 min readUpdated Mar 24, 2026

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

  1. Tokenize the card — get a cardToken from the tokenize endpoint
  2. Create a subscription — pass the token with a plan defining the billing schedule
  3. First charge — happens immediately on creation (or is deferred for free trials)
  4. Subsequent charges — automatic on each cycle date; you receive a webhook per charge
  5. Manage — retrieve, update, pause, or cancel via the subscription ID

#The Plan Object

The plan defines the billing schedule:

FieldDescription
amountDecimal amount per billing cycle
currencyISO 4217 code (e.g. EUR)
frequencyDAILY, WEEKLY, MONTHLY, or CUSTOM
intervalMultiplier for frequency (e.g. MONTHLY + 3 = quarterly, CUSTOM + 45 = every 45 days)
startDateISO 8601 date when billing begins
endDateOptional 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

StatusMeaning
TRIALINGCreated with skipFirstCharge=true, no charge yet
ACTIVEBilling is running normally
PAUSEDCharges suspended; resume by updating status to ACTIVE
CANCELEDNo 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:

FieldDescription
subscriptionIdThe subscription identifier
transactionIdThe individual charge transaction
chargeDateDate this charge was attempted
amount / currencyAmount for this cycle
transactionStatusSUCCEED or FAILED
declineCode / declineReasonSet on failure
failureCountConsecutive failed attempts
nextChargeDateNext scheduled attempt

#Sandbox Testing

Card NumberRecurring Behavior
4111111111111111All scheduled charges succeed
5500000000000004All scheduled charges succeed
4000000000000002First charge succeeds; subsequent charges decline
4000000000003220First charge triggers 3DS; subsequent charges succeed

In sandbox, the scheduler runs every 5 minutes (vs. actual scheduled dates in production).

Was this helpful?