Skip to content
Appearance

KHQR API: generate a payment QR from your server

Use the ABA PayWay link already registered on a Bongluy store to create an amount-specific KHQR, then render the returned payload wherever your customer pays.

Create
POST /payment
Payload
qrString
Auth
Server-side bearer key
Outcome
Poll until paid or expired

What the KHQR API returns

One payment request returns the KHQR payload and the identifiers needed to observe the same payment later.

Call POST /payment with a store identifier and a decimal amount string. The response includes Bongluy's paymentid, qrString, optional mobile deeplinks, expireAt, and thetranId supplied by your system.

The currency field is record metadata. The actual charge follows the ABA PayWay link registered on the selected store, so configure the store correctly before creating live payment requests.

Create the QR on your server

Account API keys reach every store owned by the account and must never be embedded in browser or mobile application code.

Read the key from a server environment variable, send it as a bearer token, and use your order or invoice identifier astranId. Repeating the same transaction id for the same store returns the original payment instead of issuing another QR, which makes a timed-out create request safe to retry.

Create a KHQR payment
curl -X POST https://api.bongluy.com/payment \
  -H "Authorization: Bearer $BONGLUY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantStoreId": "branch-2",
    "amount": "12.50",
    "currency": "USD",
    "tranId": "INV-1042"
  }'

Render qrString as the source of truth

The API returns a plain KHQR payload rather than a fixed checkout widget, so the same payment can appear on web, point-of-sale, print, or chat surfaces.

Encode qrString with a QR library and present it beside the exact amount and expiry. Any KHQR-capable banking app can scan it. Keep the QR visible on mobile even when you also offer the returned ABA Mobile deeplink.

Render the returned payload
import QRCode from "qrcode";

const payment = await response.json();
const imageUrl = await QRCode.toDataURL(payment.qrString);

// Show imageUrl, amount, and expireAt together in checkout.

Bound checkout by expireAt

A QR is payable only inside the window chosen upstream; the returned expiry keeps your checkout and polling loop finite.

Display the deadline and stop waiting when it passes. If a record still says PENDING afterexpireAt, treat it as unpaid and reconcile later rather than leaving the payer on an endless spinner.

Create a replacement with a new tranId. Reusing the old one intentionally resolves to the original payment.

Keep checkout reads payment-scoped

Public checkout responses expose only the payment details needed by the payer, while account credentials and store administration stay on your server.

Do not proxy an account API key into the browser. Use the hosted checkout URL returned by the create call, or place your own server between the browser and authenticated account routes. For the full field definitions, error envelope, and rate limits, use the complete API reference.

Continue the integration

Read Payment status guide next, or use the complete API reference for request fields, response shapes, limits, and error behavior.