CasherMatch

Cancel operation

POST /v1/cancel_operation

Request cancellation of a payment operation. Payout cancellation is not available through this endpoint.

Endpoint

POST /v1/cancel_operation
Content-Type: application/json
X-API-Key: nspay_live_…

Request

FieldTypeRequiredDescription
operation_idUUIDconditionalServer-issued payment operation ID.
merchant_operation_idstringconditionalMerchant payment ID used for Create.
reasonstringnoCancellation reason for the audit log, at most 2048 bytes. An empty value uses cancel.

Provide exactly one operation identifier. The shop is resolved from X-API-Key; an operation from another shop returns 404 Not Found without revealing that it exists.

To cancel a payment whose Create call may still be in flight, you must identify it by merchant_operation_id — see Cancelling a payment you just created.

{
  "operation_id": "f6c2e7d4-3e5b-4f1f-8a02-9d6c7e8a1b22",
  "reason": "customer_request"
}

Response

A successful command returns 200 OK with the cancellation outcome and the current operation snapshot:

{
  "outcome": "cancelled",
  "operation": {
    "operation_id": "f6c2e7d4-3e5b-4f1f-8a02-9d6c7e8a1b22",
    "type": "payment",
    "status": "cancelled"
  }
}
OutcomeMeaning
cancelledCancellation was confirmed and the payment is terminal.
already_terminalThe payment was already terminal; no new lifecycle or accounting change was made.

cancelled means the cancellation is recorded durably and the payment is terminal, so it can no longer be routed or accept money. This holds even when the cancellation overtakes its own Create call: the two commands serialise on one durable admission record on the server, so the outcome you receive is authoritative in either order.

The guarantee attaches to a cancelled response you actually received. If the request times out or returns 503, no decision may be assumed — retry the same command (it is idempotent) or read the operation state.

The command is idempotent. Repeating it with the same identifier returns the same decision and makes no further lifecycle or accounting change, so it is always safe to retry.

Cancelling a payment you just created

A cancellation may arrive while the Create call that it refers to is still being processed — for example when you apply your own timeout to Create and give up on it. That case is supported, with one requirement:

Identify the payment by merchant_operation_id. A payment that does not exist yet has no server-issued operation_id to match against, so a request carrying only operation_id returns 404 Not Found. Sending merchant_operation_id lets the API prove the payment is yours before refusing it on your behalf.

{
  "merchant_operation_id": "order-4711",
  "reason": "client_timeout"
}

The usual outcome is cancelled, with the in-flight Create refused rather than routed: it returns no payment details to you, and none are shown to your customer. If the Create call is still open on your side it completes as a cancelled payment.

If the Create finished first, the cancellation is applied to the real payment and the outcome reflects its actual state — cancelled if it could still be cancelled, or already_terminal if it had reached a terminal state.

A cancelled outcome is authoritative even in this race. When the cancellation won — the usual outcome above — payment details are never issued for that operation: not in the Create response, not on a later read.

When the Create finished first, cancelled means the real payment was cancelled. A Create response already on the wire, or a later read of the operation, may still show the details that payment had been issued — the two requests are answered independently and nothing can recall a response already sent. Those details belong to a cancelled payment that can never complete, so discard them and do not show them to your customer.

Repeating the command remains free and idempotent, but is not required to trust the result.

One reading caveat: while the racing Create is still running, reading the operation may return 404. That is the create completing, not the cancellation being in doubt — and if the Create never reached us at all, the 404 is the final answer.

Errors and retries

  • 400 Bad Request — the identifier is missing/ambiguous, operation_id is not a UUID, or reason exceeds 2048 bytes.
  • 401 Unauthorized — the API key is missing or invalid.
  • 404 Not Found — the operation does not exist in the authenticated shop.
  • 412 Precondition Failed — the ID belongs to a payout or the payment cannot be cancelled in its current state.
  • 503 Service Unavailable — cancellation could not be durably accepted before the request deadline.

Do not interpret a timeout or 503 as a successful cancellation. Read the operation state or retry the same command with the same identifier.

On this page