· API Docs
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}/cancel

Example 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 GET
  • IDEMPOTENCY_REQUEST_IN_PROGRESS — a request with this Idempotency-Key is still in progress; wait and retry with the same key
  • PAYIN_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.