NEW
Cancelling a Payin
Cancel a still-pending payin through the public API — a payin that is no longer pending returns 409 PAYIN_STATUS_TRANSITION_INVALID.
When cancellation is allowed
Only a payin with status pending can be cancelled. A payin that is already success, expired, failed, or cancelled is rejected.
- A payin with an uploaded slip is usually no longer pending — it cannot be cancelled through the API
- Cancelling sends no webhook — the cancel API response carries the result
Duplicate order_ref
If a create POST reuses an order_ref, the API returns 409 RESOURCE_EXISTS — look up the original with GET /v1/payins?order_ref=... instead of creating again.
Example 409 response:
json
{
"success": false,
"data": null,
"error": "this resource already exists",
"code": "RESOURCE_EXISTS",
"meta": {
"request_id": "019f2d25-7fd6-795d-be86-873e8d3632e5",
"timestamp": 1783168860
}
}Cancelling a payin
Call the cancel endpoint to release a pending payin:
BASH
POST /v1/payins/{id}/cancelExample 200 response:
json
{
"success": true,
"data": {
"id": "0198cbff-db9b-7b6a-9f82-6a55fdfb6575",
"status": "cancelled",
"order_ref": "ORDER-2026-00081"
}
}Error codes
RESOURCE_EXISTS— duplicate order_ref (409); look up the original with GETIDEMPOTENCY_REQUEST_IN_PROGRESS— a request with this Idempotency-Key is still in progress; wait and retry with the same keyPAYIN_STATUS_TRANSITION_INVALID— the payin is not pending and cannot be cancelled (409)PAYIN_NOT_FOUND— payin not found or belongs to another merchant (404)
Example error response when the payin cannot be cancelled:
json
{
"success": false,
"data": null,
"error": "payin is success and cannot be cancelled",
"code": "PAYIN_STATUS_TRANSITION_INVALID",
"meta": {
"request_id": "019f2d26-1a02-7b31-9c44-2f61c0d8a9e1",
"timestamp": 1783168920
}
}Full request/response details are in the API Reference → POST /v1/payins/{id}/cancel.