Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ozura.com/llms.txt

Use this file to discover all available pages before exploring further.

Recurring mode lets you create a checkout session that, on successful payment, automatically enrolls the customer in a billing plan. The customer fills in their card details once; OzuraPay handles every subsequent charge on the schedule you define.
How it works under the hood: When the customer pays, Checkout calls PayAPI’s createRecurringPlan endpoint rather than the standard cardSale endpoint. The customer’s card is tokenized by the vault and never stored by your server.

Enable Recurring Mode

Set checkoutMode to "recurring" and include a recurringConfig object:
{
  "merchantId": "your_merchant_id",
  "merchantName": "My App",
  "amount": "29.99",
  "currency": "USD",
  "checkoutMode": "recurring",
  "recurringConfig": {
    "planName": "Monthly Pro",
    "interval": "monthly",
    "startDate": "2026-06-01"
  },
  "successUrl": "https://yoursite.com/welcome",
  "cancelUrl": "https://yoursite.com/pricing",
  "errorUrl": "https://yoursite.com/error"
}
recurringConfig is required when checkoutMode is "recurring". Omitting it returns a 400 validation error.

recurringConfig Fields

Required

FieldTypeConstraintsDescription
planNamestringMax 50 charsLabel for this subscription plan, shown to the customer in the checkout UI
intervalstring"daily", "weekly", "monthly", "yearly"Billing frequency keyword. Combine with intervalCount for non-standard periods (e.g. every 3 months)
startDatestringYYYY-MM-DDFirst billing date shown to the customer for legal disclosure. Not forwarded to the payment processor — the processor starts billing based on when the plan is created, not this date

Optional

All fields below are optional. When omitted, they are not stored on the session and not sent to PayAPI — any defaults listed are applied by the PayAPI, not by Checkout.
Type note: intervalCount, initialCycles, maxCycles, and maxAttempts must be JSON numbers (not strings). initialAmount and setupFee must be JSON strings (quoted decimals like "9.99"). This matches how PayAPI expects them.
FieldTypePayAPI defaultDescription
planDescriptionstring (max 100 chars)Short description shown below the plan name in the checkout UI
intervalCountinteger ≥ 11Billing period multiplier. Combined with interval to define the billing period. interval: "monthly" + intervalCount: 3 = billed every 3 months (quarterly). interval: "weekly" + intervalCount: 2 = every 2 weeks
endDatestring (YYYY-MM-DD)indefiniteDate after which the processor stops billing automatically. Omit for an ongoing plan
maxCyclesinteger ≥ 1indefiniteMaximum number of billing cycles before the plan completes automatically. Omit for an ongoing plan. Can be set alongside endDate — whichever limit is hit first stops billing
maxAttemptsinteger ≥ 03How many times PayAPI retries a failed charge before marking the attempt failed. Pass 0 to disable retries
setupFeestring (decimal, e.g. "9.99")One-time fee charged on the first billing cycle only, in addition to the regular amount. Does not repeat
initialAmountstring (decimal, e.g. "9.99")Override the billing amount for the first N cycles (introductory / trial pricing). Must be paired with initialCycles to have effect. See Trial Pricing
initialCyclesinteger ≥ 1Number of cycles at the initialAmount before switching to the standard session amount. Has no effect if initialAmount is not also set
merchantRecurringReferencestring (max 50 chars)Your own subscription or customer ID forwarded to PayAPI. Use this to correlate the plan back to your records — it is the recommended way to look up a plan ID after enrollment

amount Field

The amount on the session is the standard recurring charge — what the customer is billed on each normal billing cycle.
{
  "amount": "29.99",
  "checkoutMode": "recurring",
  "recurringConfig": { ... }
}
What gets charged on the first cycle? Checkout forwards amount, setupFee, initialAmount, and initialCycles as separate fields to PayAPI. PayAPI combines them and calculates the actual charge — Checkout does not compute a combined total locally.
ConfigurationEffective first cycle chargeSubsequent cycles
No trial fieldsamountamount
setupFee onlysetupFee + amount (PayAPI adds them)amount
initialAmount + initialCyclesinitialAmount (repeated for N cycles)amount
All threesetupFee + initialAmount (PayAPI adds them)amount (after initialCycles expire)
There is no field called intervalAmount. The field that overrides the billing amount for the first N cycles is initialAmount.
items arrays are not supported for recurring mode. Recurring charges are a fixed scalar amount, not a cart total. Providing items returns a 400 error.

Surcharge

Add a credit card surcharge to the recurring charge using surchargePercent. The surcharge is shown as a line item in the order summary and forwarded to the payment processor.
{
  "amount": "29.99",
  "checkoutMode": "recurring",
  "surchargePercent": "2.00",
  "recurringConfig": {
    "planName": "Monthly Pro",
    "interval": "monthly",
    "startDate": "2026-06-01"
  }
}
  • Accepts a string ("2.00") or number (2.0)
  • Maximum "3.00" (Florida 3% cap)
  • Displayed as a separate line item: Surcharge (2.00%)
  • Applied to the base amount before tax
See Surcharge below for the full reference.

Trial Pricing

Use setupFee, initialAmount, and initialCycles together to offer introductory pricing.

Setup Fee Only

A one-time fee added to the first billing cycle:
{
  "amount": "29.99",
  "recurringConfig": {
    "planName": "Pro Monthly",
    "interval": "monthly",
    "startDate": "2026-06-01",
    "setupFee": "9.99"
  }
}
CycleCharged
Cycle 1$9.99 + $29.99 = $39.98
Cycle 2+$29.99

Introductory Rate

Override the amount for the first N cycles:
{
  "amount": "29.99",
  "recurringConfig": {
    "planName": "Pro Monthly",
    "interval": "monthly",
    "startDate": "2026-06-01",
    "initialAmount": "9.99",
    "initialCycles": 2
  }
}
CycleCharged
Cycle 1–2$9.99
Cycle 3+$29.99

Combined (Setup Fee + Trial)

{
  "amount": "49.99",
  "recurringConfig": {
    "planName": "Annual Premium",
    "interval": "yearly",
    "startDate": "2026-07-01",
    "setupFee": "10.00",
    "initialAmount": "19.99",
    "initialCycles": 1
  }
}
CycleCharged
Cycle 1$10.00 (setup) + $19.99 (trial) = $29.99
Cycle 2+$49.99

Interval Examples

Use interval alone for standard periods. Add intervalCount to create any custom period — the two fields multiply together.
{ "interval": "daily" }                             // Every day
{ "interval": "weekly" }                            // Every week
{ "interval": "monthly" }                           // Every month
{ "interval": "yearly" }                            // Every year (annual)
{ "interval": "weekly",  "intervalCount": 2 }       // Every 2 weeks (biweekly)
{ "interval": "monthly", "intervalCount": 3 }       // Every 3 months (quarterly)
{ "interval": "monthly", "intervalCount": 6 }       // Every 6 months (semi-annual)
{ "interval": "daily",   "intervalCount": 30 }      // Every 30 days
intervalCount is a JSON number (not a string). "intervalCount": "3" will return a 400 validation error.

Capped Plans

Use endDate or maxCycles to automatically stop billing:
{
  "amount": "9.99",
  "checkoutMode": "recurring",
  "recurringConfig": {
    "planName": "12-Month Plan",
    "interval": "monthly",
    "startDate": "2026-06-01",
    "maxCycles": 12,
    "endDate": "2027-06-01"
  }
}
Either field alone is sufficient; you can set both for belt-and-suspenders control.

Full Example

Monthly subscription with a 3% surcharge, 1-month trial, and a 12-cycle cap:
curl -X POST https://checkout.ozura.com/api/sessions/create \
  -H "X-API-KEY: your_vault_key" \
  -H "X-OZURA-API-KEY: your_merchant_key" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "your_merchant_id",
    "merchantName": "My SaaS",
    "amount": "49.99",
    "currency": "USD",
    "checkoutMode": "recurring",
    "surchargePercent": "3.00",
    "successUrl": "https://yoursite.com/welcome",
    "cancelUrl": "https://yoursite.com/pricing",
    "errorUrl": "https://yoursite.com/error",
    "recurringConfig": {
      "planName": "Pro Monthly",
      "planDescription": "Unlimited access to all Pro features",
      "interval": "monthly",
      "startDate": "2026-06-01",
      "initialAmount": "0.00",
      "initialCycles": 1,
      "setupFee": "5.00",
      "maxCycles": 12,
      "maxAttempts": 3,
      "merchantRecurringReference": "cus_abc123"
    }
  }'

What the Customer Sees

The checkout page displays a Subscription Summary block above the payment form showing:
  • Plan name and description
  • Billing interval and start date
  • Surcharge row (if surchargePercent is set)
  • End date and cycle cap (if configured)
  • Setup fee and trial pricing (if applicable)
The payment form and button are identical to a standard payment session.

Success Redirect

After a successful recurring signup, the customer is redirected to your successUrl with the standard transaction parameters:
https://yoursite.com/welcome?success=true&sessionId=session_xxx&checkoutMode=recurring&transactionId=250107000019C4E1B&transactionType=sale&amount=49.99&currency=USD&ozuraMerchantId=ozu_xxx&surchargeAmount=1.50&cardLastFour=1111&cardBrand=VISA&transDate=2026-06-01T12:00:00.000Z
ParameterDescription
checkoutMode"recurring"
transactionType"sale" (the initial CIT charge that enrolled the customer)
transactionIdThe initial charge transaction ID from the payment processor
surchargeAmountCalculated surcharge amount in the session currency
(all other standard params)Same as a standard payment — see Handle the Result
planId is not included in the success URL redirect. The PayAPI plan ID is part of the raw payment processor response but is not appended to the redirect URL. To retrieve the plan ID for subscription management (pause, cancel, lookup), query the PayAPI recurring plan endpoints using your merchant credentials — PayAPI associates plans with the merchantRecurringReference or by listing plans for your merchant account.
Create a shareable recurring subscription link:
{
  "merchantId": "your_merchant_id",
  "merchantName": "My SaaS",
  "amount": "29.99",
  "currency": "USD",
  "checkoutMode": "recurring",
  "recurringConfig": {
    "planName": "Monthly Pro",
    "interval": "monthly",
    "startDate": "2026-06-01"
  },
  "successUrl": "https://yoursite.com/welcome",
  "cancelUrl": "https://yoursite.com/pricing",
  "errorUrl": "https://yoursite.com/error"
}
Post this to POST /api/payment-links/create and share the returned url. Each customer who visits the link and pays is enrolled in their own plan. See Payment Links for full details.

Surcharge Reference

surchargePercent is independent of checkoutMode — it works on standard payment sessions too.
FieldTypeRequiredBehaviour when omittedConstraints
surchargePercentstring or numberNoTreated as 0% at charge time — no surcharge line item shown, "0.00" sent to the payment processor03.00 (Florida maximum). Normalised internally to two decimal places (e.g. 2.5"2.50")
The surcharge is:
  • Displayed as a line item in the order summary: Surcharge (X.XX%)
  • Applied to the base amount (before tax)
  • Forwarded to the payment processor on every charge (including recurring cycles)
  • Applied to debit cards at the processor’s discretion — PayAPI performs a BIN lookup and excludes debit cards automatically where required
{
  "amount": "100.00",
  "surchargePercent": "3.00"
}
Order summary: Subtotal $100.00 + Surcharge (3.00%) $3.00 = Total $103.00