Set up a recurring or scheduled agreement

Creates an agreement whose collections are driven by a schedule rather than a single payment now: a recurring agreement (a frequency, optionally a fixed number of payments and a delayed start), a one-off payment due on a future date, or a schedule of named charges. It is the same checkout submission as Take a one-off payment; the payload decides which shape of contract Shuttle builds. A recurring agreement with no start date and a charge schedule with a charge due "now" still take their first payment at checkout; a delayed start, a scheduled date or an all-future schedule create the contract and store the payment method without charging, and the scheduler collects when the dates fall due.

Where you can do this

  • The hosted checkout: Payment form (Process Payment (recurring, scheduled date or charge schedule))
  • API: Create a checkout (POST /checkouts) — frequency other than ONEOFF, or scheduled_date / scheduled_days, or a charges[] schedule; prepares the checkout the form then submits
  • The hosted checkout: the hosted checkout submits a frequency other than ONEOFF, or a scheduled date, or the request carried a charges[] schedule
  • The hosted checkout: completing the same agreement after a 3DS or hosted redirect
  • API: Create a payment (POST /payments) — no contract named and the body carries frequency other than ONEOFF, start_date / start_days, scheduled_date / scheduled_days, or charges[]

Before you start

  • A channel with an initiative whose amount-due configuration lists the requested frequency as active (the hosted checkout only offers the initiative's frequencies); a charge schedule or scheduled date needs no frequency.
  • A payment method the gateway can store: recurring, scheduled and charge-schedule agreements always store the method, so the gateway must offer save-card or create-token for the card type (the hosted checkout forces the save-card option on and refuses to submit a card type the gateway cannot save).
  • From the hosted checkout: a checkout request for the channel, prepared by POST /c/api/checkout or the legacy per-session request, holding the fixed values (nonce, amount, currency, frequency, occurrences, dates, action, account, charges).

Inputs

Names are as POST /c/api/checkout and POST /c/api/payments carry them.

InputRequiredMeaning and constraints
frequencyconditionalRecurring interval; anything other than ONEOFF makes the agreement recurring. Must be one the initiative lists. Cannot be combined with charges[] or scheduled_date
occurrencesnoFixed number of collections; absent means indefinite. Read only alongside a recurring frequency, because Shuttle files it under that frequency's own values, so an occurrences sent with a ONEOFF, a scheduled date or a charge schedule is dropped (a schedule's number of payments is its number of charges). the hosted checkout accepts 1 to 99 (below 1000 when the request fixes it); the server accepts any integer
start_datenoDelays the first collection to that date; only meaningful with a recurring frequency
start_daysnoDelays the first collection by that many days; an alternative to start_date
scheduled_datenoFor a ONEOFF with an amount, the future date the single payment falls due
scheduled_daysnoThe same, expressed as a number of days ahead
charges[]conditionalNamed instalments: amount above zero, due (an ISO date or the literal "now"), optional alt_key and legal_entities[] (id, amount). Amounts must sum to amount; each charge's legal-entity split must sum to the charge. Cannot be combined with frequency, occurrences, start or scheduled dates, or an authorise action
amountconditionalPresent makes a known-amount recurring agreement; absent with a frequency makes a variable-amount one. A scheduled date needs an amount. Scaled to four decimals, must not be zero
currencyconditionalRequired whenever amount is sent; ISO 4217 code
keep_active_untilnoDate until which an ongoing contract is held open after its last collection instead of completing; a malformed date is ignored on this path
nonceyesIdempotency key; a contract is bound to it for 24 hours (two years for payment-link nonces)
alt_keynoYour reference for the contract
metadatanoCustom key-value pairs stored on the contract
event_datenoThe date the contract relates to
descriptionnoGoods or service description shown on receipts
payment_method, save_card, action, accountsee Take a one-off paymentPayment method values, account resolution and the payment action are shared with the one-off path

Rules

Checked by the API means Shuttle refuses the request however it is sent; a screen name means only that screen refuses it, and a direct API call would be accepted.

RuleChecked byWhat you see
The frequency must be one the initiative's amount-due configuration lists as active and, unless indefinite, the number of payments must be present; otherwise the agreement never reaches its submission stepThe APIBOLT-1101 AGREEMENT_CREATION_FAILED, with the amount-step validation errors; the hosted checkout only offers the initiative's frequencies and requires 1 to 99 occurrences when finite
If the initiative's amount-due configuration has recurring switched off, a frequency is ignored and a one-off contract is builtThe APIsilent
charges[] and a recurring frequency are mutually exclusiveThe API, mirrored by the hosted checkouthosted checkout: INVALID_REQUEST "Cannot specify both charges and frequency"; POST /c/api/payments: VALIDATION_ERROR "Cannot specify both charges[] and frequency"; Shuttle: BOLT-7004 CONTRACT_CREATION_FAILED "validation.error.charges.mutually.exclusive"; the form: "frequency cannot be used with charges"
A charge schedule cannot carry start_date, start_days, scheduled_date, scheduled_days or occurrencesThe hosted checkout onlythe form refuses with "... cannot be used with charges"; not enforced server-side (Shuttle takes the schedule and ignores the other fields)
Each charge needs an amount above zero and a due date; the charges must sum to the contract amount; each charge's legal-entity split must sum to the charge; an empty schedule is refusedThe API, mirrored by the hosted checkoutShuttle: INVALID (BOLT-7004) "validation.error.charges.empty" / "amount.required" / "amount.must.be.positive" / "whenDue.required" / "amount.mismatch" / "legal.entity.mismatch" / "legal.entity.amount.invalid"; POST /c/api/payments: VALIDATION_ERROR "Charge at index n 'amount' required..." / "Sum of charges (...) must equal contract amount (...)" (within 0.01); the form: "Invalid charge amount..." / "Amount parameter (...) does not match the charges total (...)"
A charge schedule is not supported when tax rules are configured on the designationThe APIINVALID (BOLT-7086) "Scheduled charges are not supported when tax rules are configured on the designation"
A scheduled one-off cannot be an authorisationThe API, mirrored by the hosted checkoutShuttle: INVALID "Invalid value for field action."; POST /c/api/payments and the form: "Scheduled payments do not support auth / capture"
A scheduled date cannot be combined with a recurring frequencyThe API (POST /c/api/payments) and the hosted checkoutVALIDATION_ERROR / "Scheduled payments do not support frequency"; Shuttle silently drops the scheduled date when the frequency is not ONEOFF
A scheduled date must be at least one minute in the futureThe API (POST /c/api/payments) and the hosted checkoutVALIDATION_ERROR / "Scheduled payments must be scheduled for at least 1 minute in the future"; not enforced by Shuttle or the hosted checkout, so a past date on the form path collects as soon as the scheduler fires
A start date cannot be more than 48 hours in the pastThe APIVALIDATION_ERROR "start_date cannot be more than 48 hours in the past"; not enforced by Shuttle or the hosted checkout (the form only offers tomorrow onwards for four years); a past start date collects immediately after activation
start_date requires a recurring frequencyThe hosted checkout only"start_date requires a recurring frequency..."; Shuttle ignores a start date on a ONEOFF
save_card cannot be false for a scheduled date or a schedule with future charges; the method is always stored for recurring, scheduled and charge-schedule agreementsThe API, mirrored by the hosted checkoutShuttle forces storage regardless of save_card; the form refuses "Scheduled payments do not support save_card: false" / "saveCard cannot be false with future-dated charges..."
The payment method must be storable by the gateway when nothing is collected at checkout; a gateway that reports a tokenisation failure rejects the agreement, one that needs a redirect parks the contract in setup until the redirect completesThe APIBOLT-1206 TOKENISATION_FAILED with the gateway message; otherwise the response carries the tokenisation redirect and the contract stays in SETUP (see Change the payment method on a contract for the attach-on-completion rule)
A payment method (or gateway data, or force_payment_method) is required on POST /c/api/paymentsThe APIVALIDATION_ERROR "Missing payment method"
The amount is scaled to four decimals and must not be zeroThe APIBOLT-1168 INVALID_AMOUNT
For a recurring agreement, any contract created on the same nonce in the last 24 hours that has left SETUP counts as a duplicate, even with no transaction; for every shape a contract on the nonce with a successful, pending, unattributed or unresolved transaction is a duplicateThe API, mirrored by the hosted checkoutShuttle: status DUPLICATE, BOLT-1191 with the existing contract (and transaction) identifiers; POST /c/api/checkout: DUPLICATE or PROCESSING "duplicate nonce"; the form shows "This payment has already been processed." and offers Continue to the existing receipt
Only one submission per nonce runs at a timeThe APIBOLT-7059, shown by the hosted checkout as "It appears this payment is already in progress."
Account, channel and initiative resolution, fraud blocking and gateway selection are shared with the one-off path: unknown or foreign account, registration or anonymous checkout disabled, blocked session, initiative key and code both given, no initiative or valid domicile for the channelThe APIsee Take a one-off payment; INVALID_ACCOUNT / REGISTRATION_DISABLED / ANONYMOUS_DISABLED / BAD_PERMISSIONS_EXCEPTION, BOLT-1188 FRAUD_DETECTED, BOLT-1165, BOLT-7081, BOLT-1164
The completion call after a redirect re-runs submission for the same contract; a contract that has already left setup returns its existing transaction rather than a second oneThe APIas submission

What happens

  • A contract is created in SETUP, shaped by the payload: recurring (frequency, optional occurrences and start_date), a single payment due on scheduled_date, or a charge schedule (charges[]). The payment method is always stored on it, and CHARGE.CREATED is raised for each charge created up front.
  • Anything due now (a recurring agreement with no start date, or a charge due "now") is collected at checkout. A successful payment activates the contract (ACTIVE, or PENDING while a delayed-settlement method clears), raises CONTRACT.START and PAYMENT.SUCCESS, and emails the addresses the checkout request named in success_email. A decline leaves the contract in SETUP so the same nonce can be retried.
  • Nothing due now (a delayed start, a scheduled date, all charges in the future) takes no payment: the stored method activates the contract (ACTIVE) and raises CONTRACT.START; no success_email is sent at creation.
  • No receipt is emailed or texted to the payer automatically. The hosted checkout shows a receipt page at the end (unless skip_receipt is set), and the checkout's success_email emails the addresses the checkout request names, but sending the payer a receipt of their own is the integrator's to do.
  • The response carries the contract id and, when a payment was taken, the transaction id; or a 3DS, hosted or tokenisation redirect that must be completed through the submit call before the contract leaves SETUP.
  • Later, each collection is taken on its due date: recurring at each frequency interval from the start or first charge (CHARGE.CREATED and CONTRACT.UPDATE, then PAYMENT.SUCCESS or PAYMENT.FAILED); a scheduled payment or charge schedule on each charge's due date. The contract completes (COMPLETED, CONTRACT.COMPLETE) once the fixed number of payments, or every charge, is settled; keep_active_until holds it open until that date.
  • A failed collection moves the contract to FAILING and is retried on the initiative's retry schedule; when the retries are spent the arrears are settled through a manual payment or by rescheduling.

Who can do this

  • Roles: none; the entry points are customer-facing and authorised by the checkout or account session, not by an operator.
  • Recurring is offered only when the initiative has frequencies configured and its amount-due configuration supports recurring; the form hides the recurring section when the request fixes the frequency to ONEOFF. A charge schedule or scheduled date can only be set on the request, not chosen on the form.

Related


Did this page help you?