Skip to content

Cancelling a payment

Cancel a payment when the order is gone — the payer left, the basket changed — and nobody paid yet.

examples/curl/payments/cancel.sh
#!/usr/bin/env bash
# Cancel a payment nobody paid yet. The body is empty and signed as such.
set -euo pipefail
. "$(dirname "$0")/../signed-request.sh"
payment_id=$(mka_required PAYMENT_ID)
mka_request POST "/v1/payments/$payment_id/cancel" "" "$(mka_new_key)"

The body is empty and signed as such. The answer is 202 Accepted, not “cancelled”: the account may already be in the payer’s bank app. The payment carries cancellation {id, status}:

cancellation.status Meaning
requested, processing The provider is withdrawing the account. The payment is processing.
succeeded Cancelled. The payment is cancelled, and a webhook says so.
rejected Too late: the money came first. The payment goes on to succeeded; refund it if you must.

Read the payment, or wait for its webhook, to learn the outcome.

Answer Why Do
409 payment_busy + Retry-After: 1 The account is being assigned right now. Retry after a second with the same Idempotency-Key.
409 payment_not_cancellable Paid, ended, or being checked. Read the payment. Refund a succeeded one.
404 payment_not_found Not your payment. Check the id.

The same key again answers the cancellation’s current state, never a second cancellation.

While the payer has not paid and the window is open, change the amount on the same account rather than cancel and create:

examples/curl/payments/correct-amount.sh
#!/usr/bin/env bash
# Change the amount the payer is to transfer while the window is open.
set -euo pipefail
. "$(dirname "$0")/../signed-request.sh"
payment_id=$(mka_required PAYMENT_ID)
body=$(cat <<JSON
{
"amount": "${AMOUNT:-2600.00}",
"currency": "LKR",
"payment_version": $(mka_required PAYMENT_VERSION)
}
JSON
)
mka_request POST "/v1/payments/$payment_id/amount-correction" "$body" "$(mka_new_key)"

Send the payment_version you saw. The answer is 202 with correction {id, status}; once applied, the payment moves to the next version with the new amount. A stale version is 409 payment_version_conflict, a payment no longer waiting for money is 409 payment_not_correctable, the same amount is 409 amount_unchanged.