Write off a charge
Writes off the unpaid part of one charge so it is never collected: the charge ends WRITTENOFF, its unpaid amount moves into the contract's writtenoff_amount and out of outstanding_amount, and no payment is scheduled for it again. It is the counterpart of Terminate a contract: terminating a contract deliberately leaves its charges as they are, so a CANCELLED contract keeps reporting what was owed; writing each remaining charge off is the way to clear that balance for good. The same call, sent with any status other than WRITTENOFF on a written-off charge, writes it back on. The same write-off is also applied on the merchant's behalf when a contract is replaced (Amend a contract's terms, Amend a scheduled contract's instalments), when a new agreement supersedes a parent contract (Set up a recurring or scheduled agreement), when an authorisation is voided without retaining the balance (Void an authorisation), and automatically on contracts whose initiative has writeoff_unpaid.
Where you can do this
- Merchant View: Charge (Void charge)
- API: Update a charge (
PUT /charges/{charge_id}) — status WRITTENOFF on a charge that is not written off (write off); any other status on a WRITTENOFF charge (write back on) - Automatically (Shuttle): create-next-charge job — the contract's initiative has writeoff_unpaid: every ACTIVE charge on the contract is written off before the new charge is raised
Before you start
- The charge exists.
- To write off: the charge is not COMPLETED. Nothing else is checked server-side (see Rules); Merchant View offers the control only on an overdue charge of a recurring or scheduled contract that is in progress.
- To write back on: the charge is WRITTENOFF. The contract's status is not checked.
- The contract may be in any status. A charge on a CANCELLED or CANCELLING contract can be written off; that is the intended way to clear what Terminate a contract left owing.
Inputs
There is no write-off route of its own: this is the same PUT /c/api/charges/:id that amends a charge, and the status is the whole instruction. Fields that re-price or reschedule a charge belong to Amend a charge and are covered there; sending one here does not apply it, and on a one-off contract sending a different amount refuses the call outright (see Rules).
| Input | Required | Meaning and constraints |
|---|---|---|
| status | yes | WRITTENOFF writes the charge off. On a WRITTENOFF charge any other value writes it back on and the charge becomes ACTIVE whatever value was sent (the public spec offers ACTIVE). Sending WRITTENOFF on a charge already written off is treated as a plain update and refused (see Rules) |
The DELETE form carries no body.
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 charge must exist | The API | NOT_FOUND: "Charge not found" |
| On the DELETE form a COMPLETED, CANCELLED or WRITTENOFF charge is refused before anything is written | The API | VALIDATION_ERROR: "This charge is complete and cannot be written off" |
Sending status WRITTENOFF on a charge that is already WRITTENOFF is treated as an ordinary charge update, which refuses any charge that is not ACTIVE or FAILING | The API | VALIDATION_ERROR: "This charge is complete and cannot be updated" |
amount and due sent on a call that changes the write-off state are not applied. The write-off and write-back-on calls are sent with an empty body, and the write-off carries only the contract and charge ids, so neither field has anywhere to go. The public spec offers all three fields together on this call, so a caller re-pricing and writing off in one request gets only the write-off; the amount and the date have to be changed first through Amend a charge | The API | 200, charge WRITTENOFF, amount and due unchanged |
On a one-off contract's charge (no scheduler), an amount sent on the same call that differs from the current amount is refused before the write-off is considered; this is Amend a charge's rule | The API | VALIDATION_ERROR: "cannot change amount on non-recurring charges" |
| On a one-off contract (fixed amount due now) the charge is written off but no CHARGE.WRITTENOFF is raised and no job is touched | The API | (silent) |
| By design: no contract status is refused. A CANCELLED or CANCELLING contract's charge can be written off, and if that clears the last of the balance on a CANCELLING contract the contract becomes CANCELLED | The API | status as stated |
Automation: when the next charge is raised on a recurring contract whose initiative has writeoff_unpaid, every charge still ACTIVE on the contract is written off first, one CHARGE.WRITTENOFF each | The API | (silent) |
Merchant View offers Void only when the charge is overdue (due more than an hour ago and not COMPLETED, WRITTENOFF or CANCELLED), the contract is recurring or scheduled and in progress (ACTIVE, PENDING, SUSPENDED, UNRESOLVED or FAILING), and both the recurring_edit and manual_capture options are on | Merchant View screen | control hidden |
| Merchant View rolls the charge back and shows "Failed to void charge" on any error; the server's message is not shown | Merchant View screen | toast |
What happens
- The charge ends WRITTENOFF with
writtenoff_amountequal to its amount less what was paid,outstanding_amountzero andwriteoff_dateset; the response is 200 with the refreshed charge (204 on the DELETE form). - The contract's
writtenoff_amountrises by the same amount and itsoutstanding_amountandoverdue_amountfall;next_paymentis cleared, so a retry that was pending for the written-off amount is dropped;next_duemoves to the next open charge;next_chargeis unchanged on a recurring contract. - If nothing else is owed and no further charge is due, the contract completes: a scheduled-charge contract (charges[]) or a one-off with
scheduled_datebecomes COMPLETED and a CANCELLING contract becomes CANCELLED, with CONTRACT.COMPLETE. A recurring contract with anext_chargekeeps its status, so a FAILING contract stays FAILING. - CHARGE.WRITTENOFF is raised for every contract shape except a one-off due now; no CHARGE.COMPLETE will ever follow for that charge. No email or SMS is sent.
- Writing back on: the charge returns to ACTIVE with its unpaid instalments, the contract's
writtenoff_amountandoutstanding_amountare restored and CONTRACT.UPDATE is raised, but nothing is scheduled to collect it (see Rules). - In Merchant View the charge shows as VOIDED and the contract's statement carries a matching negative entry so the invoice and the write-off net to zero.
Who can do this
- Roles: Admin only today; intended for Support as well, and being aligned.
- Permission keys (for clients managing permissions directly): Merchant View shows Void only to a session holding
payment_contract. A customer (account) session may act only on charges of its own account (NO_PERMISSION: "No permissions"). A request with no session is refused (FORBIDDEN: "Invalid or missing API Key"). - Admin app options:
recurring_editandmanual_capturemust both be on for the control to appear. - Initiative option
writeoff_unpaid: turns on the automatic write-off of ACTIVE charges each time the next charge is raised.
Related
Updated 30 minutes ago