កំពុងដំណើរការ...
ផ្ទាំង Web Checkout ត្រូវបានរចនាឡើងយ៉ាងស្រស់ស្អាត ដើម្បីផ្តល់ភាពងាយស្រួលបំផុតដល់អតិថិជន។ ផ្ទាំងនេះមាន សុពលភាពរាប់ថយក្រោយ ១០ នាទី (600 វិនាទី) គាំទ្រការបង្ហាញស្ថានភាពស្កេនភ្លាមៗ ព្រមទាំងមានប្រព័ន្ធ Mobile Deeplink ដែលជួយបើកកម្មវិធីធនាគារលើទូរស័ព្ទដៃដោយស្វ័យប្រវត្តិតែម្តង។
ដើម្បីការពារសុវត្ថិភាពពីការបង្វែរទិសដៅខុសច្បាប់ (Anti-Phishing) រាល់តំណភ្ជាប់បញ្ជូនបន្ត (return_url, success_url, cancel_url) ត្រូវតែស្ថិតក្រោម Domain ដែលបានផ្ទៀងផ្ទាត់រួចរាល់ជាមុនសិន នៅលើ Web Portal៖
លោកអ្នកអាចផ្ទៀងផ្ទាត់ភាពជាម្ចាស់កម្មសិទ្ធិដោយគ្រាន់តែដាក់ DNS TXT Record ឬដាក់ HTTP Verification File តាមការណែនាំលើផ្ទាំង Portal។ បើ Domain មិនទាន់ផ្ទៀងផ្ទាត់ទេ API នឹងបដិសេធមិនបង្កើត checkout_url ឡើយ។
ហៅ API /v1/generate_qr ដោយបញ្ជូនចំនួនទឹកប្រាក់ (amount) និងភ្ជាប់នូវ Redirect URLs នោះប្រព័ន្ធនឹងបង្កើត checkout_url ជូនភ្លាមៗ។ ឈ្មោះហាង និងរូបិយប័ណ្ណត្រូវបានកំណត់ដោយស្វ័យប្រវត្តិតាម Store Token របស់អ្នក។
{
"amount": 10.00,
"return_url": "https://shop.example.com/checkout/return",
"success_url": "https://shop.example.com/checkout/success",
"cancel_url": "https://shop.example.com/checkout/cancel"
}{
"responseCode": 0,
"responseMessage": "KHQR Generated Successfully.",
"data": {
"qr": "00020101021229370016A000000677010111...",
"md5": "c4ca4238a0b923820dcc509a6f75849b",
"tran_id": "178612345678",
"checkout_url": "https://checkout.khqr.dev/c4ca4238a0b923820dcc509a6f75849b"
}
}បញ្ចូលស្គ្រីប SDK ទៅក្នុងទំព័រវិបសាយរបស់អ្នក ហើយហៅ KHQR.pay(md5) ដើម្បីបើកផ្ទាំងទូទាត់ប្រាក់ភ្លាមៗ។ អ្នកអាចស្ដាប់ Events ដូចជា bakongPaymentSuccess, bakongPaymentCancel, និង bakongPaymentExpired៖
<!DOCTYPE html>
<html lang="km">
<head>
<title>Merchant Checkout Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://checkout.khqr.dev/static/js/checkout.min.js"></script>
</head>
<body style="background-color: #0b2447; color: white; padding: 40px; text-align: center;">
<button onclick="KHQR.pay('c4ca4238a0b923820dcc509a6f75849b')" style="padding: 15px 30px; background: #2563eb; color: white; border: none; border-radius: 10px; font-weight: bold; cursor: pointer;">
🛒 Pay with KHQR
</button>
<script>
// ១. ពេលអតិថិជនបង់ប្រាក់ជោគជ័យ (Success Event)
window.addEventListener('bakongPaymentSuccess', function(e) {
console.log("Client detected payment success:", e.detail);
// បិទ Popup បន្ទាប់ពីបង្ហាញដំណឹងជោគជ័យ
if (window.KHQR) window.KHQR.close();
});
// ២. ពេលអតិថិជនចុចបិទ ឬ Cancel
window.addEventListener('bakongPaymentCancel', function(e) {
console.log("Customer closed checkout without paying");
});
// ៣. ពេលអស់សុពលភាព ១០ នាទី (Expired Event)
window.addEventListener('bakongPaymentExpired', function(e) {
console.log("Payment session expired after 10 minutes");
});
</script
</body
</html}{
"md5": "c4ca4238a0b923820dcc509a6f75849b"
}{
"responseCode": 0,
"responseMessage": "Getting transaction successfully.",
"errorCode": null,
"data": {
"hash": "70b16ec07bcac5a87dcc...",
"tran_id": "178612345678",
"currency": "USD",
"amount": 10.0,
"status": "paid",
"trackingStatus": "SUCCESS",
"receiverBank": "Partner Bank",
"receiverBankAccount": "Merchant Name"
}
}📢 ចំណាំសំខាន់បំផុត៖ ដើម្បីសុវត្ថិភាព មិនត្រូវកាត់ស្តុកទំនិញដោយពឹងផ្អែកតែលើ Frontend Event ឬការ Redirect របស់ Browser ឡើយ។ ជំហានចុងក្រោយគឺត្រូវរង់ចាំ Server-to-Server Webhook បញ្ជាក់ជាផ្លូវការ។ រាល់ Payload ទាំងអស់ត្រូវបានចុះហត្ថលេខាឌីជីថល X-RBK-Signature (HMAC-SHA256) ដោយប្រើ Webhook Secret នៃហាងរបស់អ្នក។
{
"event": "payment.success",
"timestamp": 1727600015,
"data": {
"hash": "66afcc4f6102ff5198bea2482#######ac9e...",
"tran_id": "178612345678",
"md5": "c4ca4238a0b923820dcc509a6f75849b",
"amount": 10.0,
"currency": "USD",
"store_id": "66fae12...",
"store_name": "My Official Store",
"merchant_name": "Merchant Name",
"status": "paid",
"created_at": "2026-09-29T09:00:00+00:00",
"paid_at": "2026-09-29T09:00:15+00:00"
}
}{
"event": "payment.expired",
"timestamp": 1727600600,
"data": {
"hash": "ae076b51b17540a69a80559ea446406c...",
"tran_id": "178612345678",
"md5": "c4ca4238a0b923820dcc509a6f75849b",
"amount": 10.0,
"currency": "USD",
"store_id": "66fae12...",
"store_name": "My Official Store",
"merchant_name": "Merchant Name",
"status": "expired",
"created_at": "2026-09-29T09:00:00+00:00",
"expired_at": "2026-09-29T09:10:00+00:00"
}
}