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).

InputRequiredMeaning and constraints
statusyesWRITTENOFF 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.

RuleChecked byWhat you see
The charge must existThe APINOT_FOUND: "Charge not found"
On the DELETE form a COMPLETED, CANCELLED or WRITTENOFF charge is refused before anything is writtenThe APIVALIDATION_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 FAILINGThe APIVALIDATION_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 chargeThe API200, 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 ruleThe APIVALIDATION_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 touchedThe 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 CANCELLEDThe APIstatus 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 eachThe 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 onMerchant View screencontrol hidden
Merchant View rolls the charge back and shows "Failed to void charge" on any error; the server's message is not shownMerchant View screentoast

What happens

  • The charge ends WRITTENOFF with writtenoff_amount equal to its amount less what was paid, outstanding_amount zero and writeoff_date set; the response is 200 with the refreshed charge (204 on the DELETE form).
  • The contract's writtenoff_amount rises by the same amount and its outstanding_amount and overdue_amount fall; next_payment is cleared, so a retry that was pending for the written-off amount is dropped; next_due moves to the next open charge; next_charge is 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_date becomes COMPLETED and a CANCELLING contract becomes CANCELLED, with CONTRACT.COMPLETE. A recurring contract with a next_charge keeps 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_amount and outstanding_amount are 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_edit and manual_capture must 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


Did this page help you?