Cancel Payment Order (by Merchant Order ID)
Cancel an open payment order from your backend using your own merchant_order_id —
the id you sent to /payment-flex/create. The platform resolves it to the
gateway order internally, so you do not need to have stored the returned platform_order_id.
This is the same operation as /payment/cancel, but keyed by your order id
instead of the gateway one. The main use case is clearing the pending-order 409 returned by
/payment-flex/create: only one open FLEX order is allowed per customer account at a time, so a second
create returns
{
"success": false,
"code": 409,
"error": "you have a pending payment order. complete or cancel it first.",
"data": { "pending_order_id": "THBP20260613123300zBuseUwN" }
}
Call /payment/cancel-by-merchant-order-id with the merchant_order_id of the stuck order to cancel it,
then retry the create.
The customer can also cancel from the hosted payment page itself. This endpoint is the server-to-server equivalent for your backend.
URL : /payment/cancel-by-merchant-order-id
Method : POST
Request
{
"merchant_id" : "[Merchant id]",
"token" : "[Auth Token]",
"time" : "[Time Stamp]",
"merchant_order_id" : "[your merchant order id to cancel]"
}
| param name | description | example |
|---|---|---|
| merchant_order_id | Your own order id — the one you sent to /payment-flex/create. Must have been created within the last 24 hours. | ORDER0123456789789445566 |
Data example
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "ORDER0123456789789445566"
}
When can an order be cancelled?
A cancel succeeds only when all of the following hold:
- The order belongs to your merchant account.
- The order was created within the last 24 hours (the internal resolution window).
- The order status is
open(not yet paid, expired, or already cancelled). - No payment slip has been uploaded for the order yet.
On a successful cancel the system also:
- releases the pending-order guard — so you can immediately create a new order for the same customer account,
- sends a
CANCELLEDpayment callback to yournotify_url(see Payment Callback).
⚠️ A cancel is not always final: in some cases the order may still be paid afterwards, in which case a subsequent
PAIDcallback follows for the sameplatform_order_id— always treatPAIDas authoritative.
Success Response
Code : 200 OK
{
"success": 200,
"data": {
"platform_order_id": "THBP20260613123300zBuseUwN",
"merchant_order_id": "ORDER0123456789789445566",
"status": "cancelled"
}
}
A retry of a cancel on an already-cancelled order also returns 200 (with "already_cancelled": true)
— the call is idempotent.
Error Responses
Condition : Invalid merchant id, token, or signature
Code : 403
{ "error": { "code": 403, "message": "authentication failed" } }
Condition : Order not found — the merchant_order_id was not created via FLEX, is older than
24 hours, or is not owned by you.
Code : 500
{ "error": { "code": 500, "message": "merchant order id not found" } }
Condition : Order exists but cannot be cancelled — not open, a slip was already uploaded, or it is
past the cancellable window.
Code : 409
{ "success": false, "code": 409, "error": "cannot cancel order" }