Bongluy Demo Store
12.50USD
Choose the rail, POST an amount, and receive a KHQR with its exact deadline. We watch the status with you until the outcome is known.
POST /payment
Authorization: Bearer sk_live_…
Content-Type: application/json
{
"merchantStoreId": "branch-2",
"amount": "12.50",
"currency": "USD",
"provider": "BAKONG",
"tranId": "INV-1042"
}Bongluy Demo Store
12.50USD
Today the link is the whole integration surface. You send it, the customer types the amount themselves, and your system finds out it was paid when somebody tells it. There is no call to make, no identifier to correlate, and no event to subscribe to.
tranId carried alongside it.The link already works. It just had no API. We gave it one.
Four steps carry the integration from one-time setup to a durable result. The returned expiry keeps the polling loop bounded.
Add a store with its required USD PayWay link, optional KHR link, and optional Bakong account ID. Then create an API key after signing in with Google or GitHub.
One authenticated request carries the store, amount, currency, provider, and your own tranId. It returns a payment id, KHQR payload, and exact expiry timestamp.
The payload is a plain KHQR string. Draw it on a web checkout, a POS screen, a printed slip, or a chat message — any KHQR-capable banking app can pay it.
Poll the status route every two or three seconds until the state leaves PENDING. Read the detail route when you need the durable record.
POST /payment
Authorization: Bearer sk_live_…
Content-Type: application/json
{
"merchantStoreId": "branch-2",
"amount": "12.50",
"currency": "USD",
"provider": "BAKONG",
"tranId": "INV-1042"
}{
"id": "8435481a-48a-4bb2-91d2-bcd1e604fb17",
"status": "PENDING",
"amount": "12.50",
"currency": "USD",
"tranId": "INV-1042",
"qrString": "00020101021229400015kh.gov.nbc…",
"paywayLink": null,
"khqrMd5": "e0f3…",
"deeplink": null,
"expireAt": "2026-08-14T09:32:11Z"
}Render the qrString and the amount, then show the status you already have. It moves to Success without a refresh because the checkout polls the public status route every two or three seconds.
ABA payments can offer a mobile deeplink when present. Bakong payments stay QR-first, so the scannable KHQR is always the source of truth.
Bongluy Demo Store
12.50USD
Demo payment is pending.
Authenticated store and payment routes take a server-side bearer key. Keys are prefixed sk_live_, shown once at creation, rate limited to 600 requests a minute, expire after 90 days, and carry fixed scopes. Public checkout reads use a separate server-side key.
/paymentCreate an ABA or Bakong payment. Returns the KHQR and expiry.
/payment?storeId=…&page=1List and page a store's payments.
/payment/statusPoll a payment by id or by your own tranId.
/payment/detailRead the full durable payment record.
/storesList the stores on the account.
{
"paymentId": "8435481a-48a-4bb2-91d2-bcd1e604fb17",
"status": "SUCCESS",
"expireAt": 1786763662418,
"settledTranId": "1234567890",
"receipt": "https://…",
"at": 1786763501992
}Poll /payment/status every two or three seconds until the state leaves PENDING. Read the returned clocks rather than assuming a duration, and never manufacture a terminal state from the local clock.
Read /payment/detail for the durable record. Merchant webhooks are not available yet, even though webhook fields can be stored on a store.
A store, provider, currency, and decimal amount string return a KHQR payload ready to render anywhere. ABA uses PayWay; Bakong builds the code locally.
ABA payments can carry ABA Mobile deeplinks for checkout without a second device. Bakong returns no deeplink, and the QR remains the source of truth on every rail.
Poll one lightweight endpoint every two or three seconds until the state changes. A separate detail route returns the durable payment record for reconciliation.
Send a tranId and a repeated request for that store returns the original payment instead of issuing a second QR. Retrying a timed-out create is then safe.
One account holds many stores, each with PayWay links, an optional Bakong account, a name, and an on/off switch. Payments and history remain scoped per store.
Every payment keeps its amount, currency, status, your tranId, the settled transaction id, receipt link, and timestamps. Lists are paged and filterable by status; detail supports exact tranId lookup.
Public payment and status routes use a separate server-held checkout key. They disclose only the store name, amount, status, and QR, keeping account API keys and account data out of checkout code.
Funds move from the payer straight into the merchant's own bank account. Bongluy holds no balance, runs no payout schedule, and carries no float.
The service handles QR payments only. There are no card numbers collected, transmitted, or stored anywhere, so there is nothing sensitive to leak.
Authenticated reads report a foreign payment or store exactly like one that does not exist, so another account's key cannot use responses to probe ids.
Account and checkout keys belong on your server. Public checkout responses are payment-scoped and never expose store ids, transaction ids, receipts, or internal errors.
An existing ABA PayWay payment link remains required on every store. Add a Bakong account ID when that store should also accept Bakong payments.
Poll POST /payment/status every two or three seconds until the state leaves PENDING. Use POST /payment/detail for the durable record. Merchant webhooks are not available yet.
Bongluy checks the provider once more at the deadline before marking a payment EXPIRED. Only that terminal status is an expiry verdict; a PENDING result still needs reconciliation.
Keys belong to the account, not to an individual store, so one key reaches every store that account owns. Keys are prefixed sk_live_, shown once at creation, rate limited to 600 requests a minute, and expire after 90 days.
Any KHQR-capable banking app can scan the code. ABA payments may also include an ABA Mobile deeplink; Bakong payments are paid from the QR.
Add the store, configure its payment rails, create a key, and POST your first amount, currency, and provider.