Recurring Billing Guide
Create and manage recurring payment contracts that charge a stored payment method on a schedule.
Cresora Recurring lets you create a contract that automatically charges a stored payment method on a fixed schedule.
Concepts
- Contract — the recurring agreement: a stored payment method, an amount, a frequency, and a schedule (start date, optional end date or installment count).
- Installment — a single scheduled charge generated from a contract.
There is no separate "plan" or "subscription" object — the contract is the recurring entity. Each scheduled charge is materialized as a normal transaction, so it shows up in your transaction reporting like any other payment.
Prerequisites — tokenize the payment method first
A contract charges a vault token, never a raw card or bank number. Capture the payment method once via a Hosted Payment Page tokenization session, then pass the resulting token as payment_method_token. See the Tokenization Guide →.
Create a recurring contract
curl -X POST https://api.cresoracommerce.com/api/v1/contracts \
-H "Authorization: Bearer csk_test_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"merchant_id": "b1e7c0f2-3a4d-4e5f-8a9b-0c1d2e3f4a5b",
"payment_method_type": "CARD",
"payment_method_token": "tok_xxxxxxxxxxxx",
"amount": "99.00",
"currency": "USD",
"frequency": "MONTHLY",
"start_date": "2026-08-01"
}'import requests, uuid
resp = requests.post(
"https://api.cresoracommerce.com/api/v1/contracts",
headers={
"Authorization": "Bearer csk_test_xxxxxxxxxxxx",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"merchant_id": "b1e7c0f2-3a4d-4e5f-8a9b-0c1d2e3f4a5b",
"payment_method_type": "CARD",
"payment_method_token": "tok_xxxxxxxxxxxx",
"amount": "99.00",
"currency": "USD",
"frequency": "MONTHLY",
"start_date": "2026-08-01",
},
)
contract = resp.json() # contract["id"]const resp = await fetch("https://api.cresoracommerce.com/api/v1/contracts", {
method: "POST",
headers: {
Authorization: "Bearer csk_test_xxxxxxxxxxxx",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
merchant_id: "b1e7c0f2-3a4d-4e5f-8a9b-0c1d2e3f4a5b",
payment_method_type: "CARD",
payment_method_token: "tok_xxxxxxxxxxxx",
amount: "99.00",
currency: "USD",
frequency: "MONTHLY",
start_date: "2026-08-01",
}),
});
const contract = await resp.json();Bounding the schedule (optional)
By default a contract charges indefinitely until you cancel it. To bound it, supply either:
end_date— stop after this date, orremaining_installments— a fixed number of charges, ortotal_amount— a fixed contract total.
Manage a contract
| Action | Endpoint |
|---|---|
| Get status | GET /api/v1/contracts/{contractId} |
| Retry a failed installment | POST /api/v1/contracts/{contractId}/retry |
| Cancel | POST /api/v1/contracts/{contractId}/cancel |
Contracts move through PENDING_ACTIVATION → ACTIVE → COMPLETED (or CANCELLED / FAILED), and can be PAUSED and RESUMED. Field-level edits (amount, frequency, payment method) are not supported — cancel the contract and create a new one instead.
ACH recurring contracts
For ACH payment methods (payment_method_type of ACH_WEB, ACH_PPD, or ACH_CCD), you must also supply the NACHA authorization context on create: ach_sec_code, ach_account_type (CHECKING / SAVINGS), name_on_check, and authorization_timestamp (when the consumer authorized the debit).
NACHA requires you to re-notify the consumer when the debit date or amount changes, or when enough time has elapsed since the original authorization. Cresora captures the original authorization_timestamp on the contract, but sending the re-notification to your customer before the next charge is your responsibility. Monitor contract.payment_success / contract.payment_failed to track each installment.
Webhook events
| Event | When |
|---|---|
contract.created | Contract created |
contract.payment_success | A scheduled installment charged successfully |
contract.payment_failed | A scheduled installment failed (soft decline) |
contract.completed | Final installment paid — contract complete |
contract.paused | Contract paused |
contract.resumed | Contract resumed |
contract.cancelled | Contract cancelled before completion |
Frequencies
frequency accepts one of:
| Value | Meaning |
|---|---|
WEEKLY | Every week |
BIWEEKLY | Every 2 weeks |
MONTHLY | Every month |
QUARTERLY | Every 3 months |
ANNUALLY | Every year |