Payment Request Endpoint
Issues a payment instruction for a confirmed booking. This is the single payment entry point for every product type.
- Endpoint:
/api/v1/unified-payment/request - Method:
POST
Headers
| Header | Value | Required | Description |
|---|---|---|---|
Partner-Access-Token | Base64 String | Yes | Your encrypted AES-256 time-sensitive token. |
X-Currency | Currency Code | No | Requested currency code, e.g. THB or MMK. Falls back to your partner currency. |
Accept-Language | Language Code | No | Locale used on the hosted payment page, e.g. en or th. |
Content-Type | application/json | Yes | |
Accept | application/json | Yes |
Payload Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
invoice_no | String | Yes | The invoice_no returned by Checkout Confirm. The booking booking_number is also accepted. |
:::info payment_method is not sent here
The payment provider is taken from the booking itself — it was already fixed by the
payment_method field you sent to Checkout Confirm. Sending payment_method to this
endpoint has no effect and it is ignored.
:::
Sample Payload
{
"invoice_no": "7992370634757"
}
Sample Response
The data.type field tells you how to continue. Handle all four types.
link — redirect the buyer
Returned by 2C2P, Ksher, CB Pay, Pay Later and by fully discounted bookings.
{
"result": 1,
"message": "Payment processed successfully",
"data": {
"type": "link",
"url": "https://sandbox-pgw-ui.2c2p.com/payment/4.1/#/info/kSAops9Zwhos8hSTSeLTUWgQNiHuf8f"
}
}
Redirect the buyer to url. After payment the gateway sends them back to your
checkout page with an encoded payload.
qr — render the QR string
Returned by MM QR and AYA MM QR.
{
"result": 1,
"message": "Payment processed successfully",
"data": {
"type": "qr",
"qr_code": "000201010212504200245e785a3cf9cf61168c30cc85011..."
}
}
qr_code is an EMVCo QR payload string. Render it as a QR image for the buyer to scan.
prepay — hand the signed order to the wallet app
Returned by KBZ Pay.
{
"result": 1,
"message": "Payment processed successfully",
"data": {
"type": "prepay",
"appid": "kp733c2de4e3d3933ce9b10456e8e5f0",
"merch_code": "911010401",
"nonce_str": "7luL6Ed6DfFXI6C4GXzFm6xXGHbTtOJW",
"prepay_id": "KBZ002a71743c8bdc58d94708a6e719627422112845617",
"timestamp": "1778648325",
"orderinfo": "appid=kp733c2de4e3d3933ce9b10456e8e5f0&merch_code=911010401&nonce_str=7luL6Ed6DfFXI6C4GXzFm6xXGHbTtOJW&prepay_id=KBZ002a71743c8bdc58d94708a6e719627422112845617×tamp=1778648325&sign=096DA956B69F21ACEEFE23E97A6533C5",
"sign": "096DA956B69F21ACEEFE23E97A6533C5",
"signType": "SHA256",
"redirect_url": "https://your-domain.com/checkout?type=all&payload=eyJyZWZlcmVuY2Vfbm8iOiJ..."
}
}
Pass orderinfo, sign and signType to the KBZ Pay mini-app invoke on your frontend,
then send the buyer to redirect_url when the wallet returns.
form — post the returned HTML
Returned by providers that require a self-submitting bank form. url contains an HTML
document — write it into the page and let it submit itself.
{
"result": 1,
"message": "Payment processed successfully",
"data": {
"type": "form",
"url": "<html><body><form method=\"post\" action=\"...\">...</form></body></html>"
}
}
Fully Discounted Bookings
When a coupon covers 100% of the booking there is nothing to charge. The endpoint settles
the booking immediately — no gateway is involved — and returns a link response pointing
straight at your checkout result page:
{
"result": 1,
"message": "Payment processed successfully",
"data": {
"type": "link",
"url": "https://your-domain.com/checkout?type=all&payload=eyJyZWZlcmVuY2Vfbm8iOiJ..."
}
}
The booking is already paid at this point. Your frontend flow does not need to change —
follow the url exactly as you would for a gateway link.
Errors
| HTTP | Body | Cause |
|---|---|---|
401 | {"error": "Invalid API Key"} | Partner-Access-Token missing, malformed or expired. |
422 | {"message": "...", "errors": {"invoice_no": ["..."]}} | invoice_no is missing or not a string. |
500 | {"message": "Booking not found"} | No booking matches invoice_no — or it belongs to another partner. |
500 | {"message": "Your booking could not be found. Please contact support."} | The booking exists but the provider could not resolve it. |
500 | {"message": "<gateway message>"} | The gateway rejected the payment token request, e.g. an amount or merchant configuration problem. |
In production the exact message may be replaced by Server Error; the detailed message is
returned on UAT.
Payment Result
The gateway calls our backend directly when the buyer finishes paying — you do not report
the result to us. Read the final status with /api/v1/unified-booking/result using the
same invoice_no.
Failures raised by the gateway after the payment page opened (for example 2C2P
4081 — unable to authenticate card holder) are card or gateway side outcomes, not API
errors. In that case the payment request itself succeeded and the booking simply stays
unpaid; let the buyer retry by calling this endpoint again.