Void an authorisation

Releases an authorisation so the money the gateway was holding is no longer reserved and can never be captured. The void is its own transaction (a vo_ id) attached to the authorisation; it carries the authorised amount less anything already captured, and by default it also settles the agreement behind it, cancelling a contract that has never taken a payment or writing off the charge the authorisation was raised for. An authorisation is never refunded: it is captured (Capture an authorised payment) or voided, and only the resulting payment or capture can be refunded (Refund a payment).

Where you can do this

  • Merchant View: Transaction (Void)
  • API: Void a payment (POST /payments/{payment_id}/void) — :id is an authorisation's payment (pay_), capture (cap_) or transaction (tr_) id, or the payment's alt_key; the body is optional
  • Automatically (Shuttle): split payment rollback — one leg of a multi-part authorisation fails to authorise: every leg that did authorise is voided, keeping the balance
  • Automatically (Shuttle): contract completion — a contract is saved as COMPLETED while a successful authorisation is still open on it and the contract's authorised total exceeds that authorisation's amount: the authorisation is voided, keeping the balance

Before you start

  • The source is an authorisation (action AUTH) with an amount above zero whose status is neither DECLINED nor INVALID_PAYMENT_METHOD.
  • The gateway the authorisation was taken on still exists and is neither archived nor inactive.
  • Nothing need be true about how much of the authorisation is still uncaptured, unvoided or unexpired; see Rules.
  • From Merchant View: the instance option manual_capture is on and the authorisation still reports an authorised amount above zero.

Inputs

The call takes no body: the authorisation to void is the one named in the URL, and the amount is always what is left of it.

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
:id must resolve to an authorisation (action AUTH). A pay_, cap_ or tr_ id is fetched directly; anything else is searched as the payment's alt_key among authorisations, newest firstThe APINOT_FOUND: "Payment not found"
An alt_key that matches two authorisations, the older created within the last six months, is ambiguousThe APIINVALID_REQUEST: "Duplicate alt_key"
The gateway the authorisation was taken on must exist and be neither archived nor inactive; it is checked before the void record is created and again before the gateway is calledThe APIINVALID: "(BOLT-7185) Sorry we could not process this type of payment (archived gateway)."
Authorisation expiry is not checked, server-side or in Merchant View: Void stays on offer after expires has passed, where the screen badges the authorisation EXPIRED, and the gateway decidesThe API and Merchant View screenthe gateway's answer, recorded as a DECLINED void
A gateway decline is not an error response: the call returns the void with status DECLINED and the gateway's gateway_messageThe APIHTTP 200 with void.status DECLINED
A gateway that throws fails the call and leaves the void UNRESOLVED with no webhook; a payment connector that cannot be resolved at all is not an error and leaves the void UNRESOLVED with a webhookThe APIINVALID: "(BOLT-7010) Internal Error: Failed to process transaction with gateway" on a throw; HTTP 200 with void.status UNRESOLVED when no connector answered
The instance option manual_capture gates only Merchant View; the route accepts a void with the option offMerchant View screencontrol hidden

What happens

  • The caller receives a void object (vo_ id, amount, reference, status, gateway_status, gateway_message, processed, payment, source_transaction, parts) with status SUCCESS, PENDING, DECLINED or UNRESOLVED. A decline still returns HTTP 200, so read status; only a request that could not create a void at all returns an error.
  • The amount voided is what was authorised less what has already been captured. On success the authorisation's voided rises by it and its authorised falls to zero, so no capture can follow.
  • Unless the balance is retained, the agreement behind the authorisation is settled: a contract that has never taken a payment becomes CANCELLED; one that has taken money before keeps its status and the charge the authorisation was raised for is written off instead, clearing what it still owed and its next payment date (Write off a charge).
  • Webhooks: VOID.SUCCESS, VOID.PENDING, VOID.FAILED or VOID.UNRESOLVED for the void, PAYMENT.UPDATE for the authorisation, and CONTRACT.COMPLETE when the balance was not retained. A one-off due at once raises no contract webhook at all, so the most common shape of authorisation reports only the void. CHARGE.WRITTENOFF follows a written-off charge on every other contract shape.
  • In Merchant View the authorisation is badged VOIDED, Capture and Void disappear from it, and the screen moves to the new void transaction.

Who can do this

  • Roles: Admin only. Support holds none of the keys Shuttle accepts, and principle 1 withholds voids from Support deliberately: they control how money flows.
  • Permission keys (for clients managing permissions directly): agreement, payment_contract, payment_transaction or * on the client or on the authorisation's division, scoped to the payment's account; checked by Shuttle, which also passes a customer (account) session whose account is the payment's own. Without one the caller sees UNAUTHORIZED "Unauthorized" (HTTP 401). Merchant View requires payment_transaction specifically to show the action bar, so a user holding only agreement or payment_contract can void through the API but sees no control. Two of the keys the server accepts, agreement and payment_contract, are contract-servicing keys that intends to grant Support, which would hand Support the void it is meant never to have.
  • API keys: an instance session reaches the route with the same service-layer check. A key scoped read-only or to payment links carries only view permissions and cannot void; a key with full scope acts as Admin.

Related


Did this page help you?