Move the next charge
Moves the date on which a recurring contract's next charge will be created. Nothing else about the agreement changes: amount, frequency and number of payments stay as they are, so no replacement contract is created. Each later charge is dated one frequency interval on from the charge before it, so moving the next charge shifts the whole series that follows; the shift is applied charge by charge as each one is created, not at edit time. There is no dedicated endpoint: it is a contract update whose body carries only next_charge. It differs from Amend a contract's terms (same endpoint, but a change to amount, frequency or occurrences, which is a terms change) and from Reschedule the next payment (next_payment, which moves the next collection attempt for money already due, not the creation of the next charge).
Where you can do this
- Merchant View: Edit an upcoming charge or payment (Save)
- API: Update a contract (
PUT /contracts/{contract_id}) — body carries next_charge only
Before you start
- The contract is recurring (fixed or variable amount) and in progress: not completed, failed, cancelled, cancelling or suspended. A suspended contract is resumed instead (Resume a contract); a cancelled or cancelling one needs a resume; a completed or failed one is not editable.
- In Merchant View the contract must currently show a next charge date and the Merchant View option
recurring_editmust be on.
Inputs
| Input | Required | Meaning and constraints |
|---|---|---|
| next_charge | yes | New date for the next charge, as an ISO 8601 timestamp (yyyy-MM-ddTHH:mm:ss, optionally with milliseconds and Z), not in the past; or the literal now (lower case), which Shuttle replaces with the current server time. An empty value is ignored (see Rules). A timestamp without an offset is read on the server clock. |
Nothing else should be in the body: amount, frequency, occurrences or charges make the call a Amend a contract's terms or Amend a scheduled contract's instalments; status makes it a Suspend a contract or Resume a contract; next_payment makes it a Reschedule the next payment.
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.
| Rule | Checked by | What you see |
|---|---|---|
| The body must carry a contract object | The API | VALIDATION_ERROR: "API body error: missing contract object" |
next_charge (other than now) must not be earlier than the server clock when the request is received; checked before the contract is loaded | The API | VALIDATION_ERROR: "next_charge must be in the future" |
| The contract must exist and be visible to the session | The API | NOT_FOUND |
A one-off contract (ONEOFF with no scheduled date) cannot be updated | The API | VALIDATION_ERROR: "cannot update non-recurring contracts" |
A scheduled single payment (a one-off with a scheduled_date) has no next charge to move: it is one charge with a due date, changed through scheduled_date (Amend a contract's terms). A next_charge sent for one is not forwarded | The API | 200 OK, nothing moves |
A cancelled or cancelling contract cannot take a next_charge without resume; with it the call is a Resume a contract | The API | VALIDATION_ERROR: "resume required" |
| On a suspended contract next_charge is a resume, not a reschedule: the call goes to Shuttle's resume and the contract becomes ACTIVE, under Resume a contract rules | The API | (resume performed) |
| A completed or failed contract is not editable | The API | INVALID: "contract (status PAYMENTCOMPLETE is not editable)" (or FAILED) |
| The occurrence cap is not checked at edit time: if charge_count already equals occurrences the date is stored, and the next-charge job then clears it without creating a charge (the resume path does check this, see Resume a contract) | The API | 200 OK; no charge is ever created for the date |
| An empty or missing next_charge sends nothing to Shuttle and the contract is returned unchanged; the next charge date cannot be cleared by this call | The API | 200 OK, nothing changes |
| Moving next_charge alone is never a terms change, so no replacement contract is created | The API | (none) |
| Merchant View offers Edit Next Charge only while the contract shows a next charge date and is in progress (ACTIVE, PENDING, SUSPENDED, UNRESOLVED, FAILING); suspending clears the date, so in practice the link is hidden on suspended contracts | Merchant View screen | control hidden |
Merchant View asks for confirmation, but does not refuse, when the chosen date is less than five minutes ahead or is now; its picker allows any time from the start of today, so a time earlier today is confirmed client-side and then rejected by the server (past-date rule above), which the app reports with a generic message rather than the server's | Merchant View screen | confirmation modal; on server rejection the toast "Sorry, an error has occurred please try again later." |
| Merchant View disables Save until the date has been changed | Merchant View screen | control disabled |
What happens
- The contract keeps its amount, frequency, occurrences and status; no replacement contract is created. The response carries the same contract with next_charge set to the new date (
nowbecomes the time the request was received), and future_charges is derived from that date immediately. - A CONTRACT.UPDATE webhook is raised.
- The next charge is created on the new date (earlier where the payment method needs advance notice), and every later charge follows one frequency interval after the one before it, so the whole series that follows moves with it.
- The new charge is collected when it falls due; a failed collection follows the contract's retry schedule.
- On a suspended contract the same call resumes it instead: the contract becomes ACTIVE under Resume a contract rules.
Who can do this
- Roles: Admin only today; intended for Support as well, and being aligned.
- Permission keys (for clients managing permissions directly):
payment_contract(oragreement, or*) on the client or the contract's division, for the contract's account (all entry points; checked at the API, against the permissions the platform holds for the session). - Admin app: permission
payment_contracton the screen (an unpermitted user is sent back to the contract screen); optionrecurring_editshows the Edit Next Charge link.
Related
Updated 34 minutes ago