เชื่อมต่อครั้งแรก
ให้ครบทั้งฝากและถอน
เริ่มจากตัวอย่างที่รันได้ ตรวจผลในเว็บร้าน แล้วนำขั้นตอนเดียวกันไปเชื่อมกับ backend ของคุณ
เตรียมของให้พร้อมก่อนเริ่ม
ใช้ Node.js 20 ขึ้นไป และ terminal สองหน้าต่าง ไม่ต้องติดตั้งฐานข้อมูลหรือ npm package
Sandbox ของ Gateway
รับ API ฝาก–ถอน เก็บยอดจำลอง และส่ง webhook ที่มีลายเซ็น
Backend ร้านตัวอย่าง
สร้างออเดอร์ เรียก API รับ webhook และอัปเดตยอดลูกค้าเพียงครั้งเดียว
ดาวน์โหลดสองไฟล์ไว้ในโฟลเดอร์เดียวกัน
node --versionควรได้ v20 หรือสูงกว่า · ดาวน์โหลด Node.js
127.0.0.1 ทั้ง API และ webhook เหมาะสำหรับเริ่มเชื่อมต่อและทดสอบ backend ในเครื่อง ยังไม่ใช่ hosted sandbox สำหรับเว็บร้านที่ deploy แล้วเปิด Sandbox และเว็บร้านตัวอย่าง
เข้าโฟลเดอร์ที่ดาวน์โหลดไว้ แล้วรันคำสั่งต่อไปนี้คนละ terminal
node sandbox.cjsเปิด Sandbox Console — 127.0.0.1:4545 ↗
node merchant-example.cjsเปิด เว็บร้านตัวอย่าง — 127.0.0.1:4546 ↗ แล้วกด ตรวจ API จาก backend
ถ้าจะใช้ backend ของคุณเอง
เปิด “แสดงค่าตั้งค่า Test” ใน Sandbox Console แล้วนำสามค่านี้ไปตั้งฝั่งเซิร์ฟเวอร์
| ค่า | ใช้ทำอะไร |
|---|---|
base_url | http://127.0.0.1:4545 |
api_key | ค่า gw_test_... ใน header X-Api-Key |
webhook_secret | ตรวจ HMAC ของข้อความที่ได้รับ ไม่ใช่ API key |
.gateway-sandbox.json อัตโนมัติ ข้อมูล API key ไม่ถูกส่งไปหน้าเว็บร้าน เก็บ credentials ของ backend คุณใน environment หรือ secret managerเรียก API ไม่ผ่าน / เปิดหน้าไม่ได้
Connection refused: ตรวจว่าเปิด terminal ทั้งสองค้างไว้และใช้ port ถูกต้อง
401: ใช้ Test key จาก Sandbox นี้ ห้ามใช้ production key
EADDRINUSE: port ถูกใช้อยู่ ให้หยุด Sandbox เก่าก่อน หรือตั้ง port ตาม README
หาไฟล์ไม่พบ: terminal ต้องอยู่ในโฟลเดอร์ที่มีทั้งสองไฟล์
รับผลกลับเข้า backend ของร้าน
ให้ Gateway แจ้งเหตุการณ์เข้ามา แล้วตรวจลายเซ็นก่อนบันทึกผล
- ใน Sandbox Console ใส่ Webhook URL ด้านล่าง แล้วกด บันทึก URL
- กด ส่ง Test Webhook
- ดู delivery ได้
delivered / HTTP 200และเว็บร้านแสดง✓ Test webhook
http://127.0.0.1:4546/webhookตัวอย่างร้านใช้ X-Gateway-Signature, อ่านสถานะซ้ำผ่าน API และตอบ 2xx หลังบันทึกสำเร็จ ปุ่มส่งซ้ำใช้ทดสอบว่าร้านไม่ลงยอดซ้ำ
sandbox.test ใช้ตรวจ URL และลายเซ็นเท่านั้น ไม่เพิ่มยอดและไม่ยืนยันว่าการฝาก–ถอนผ่าน ต้องทดสอบออเดอร์ในขั้นต่อไปWebhook ไม่ถึง หรือได้ 401 / 404
ไม่มี HTTP: ตรวจว่า backend รันอยู่และ URL ใช้ 127.0.0.1
401: ใช้ webhook secret ให้ตรง และตรวจ raw body ก่อน JSON parser เปลี่ยนข้อมูล
404: ตรวจ path /webhook; หากเป็น unknown_order ให้สร้างรายการจาก backend ร้านก่อน
3xx: ใช้ URL ปลายทางโดยตรง Sandbox ไม่ตาม redirect
สร้างรายการฝาก แล้วจำลองผลชำระ
เริ่มจากเว็บร้าน เพื่อให้มีออเดอร์ที่จับคู่กับ webhook ได้
- ในเว็บร้านตัวอย่าง เลือก Deposit จำนวน 500 บาท แล้วกดสร้างรายการ
- ควรได้
HTTP 201,payment_idและสถานะpending - ไป Sandbox Console หาเลขอ้างอิงเดียวกัน แล้วกด paid
- กลับเว็บร้าน ตรวจออเดอร์เป็น
paidและยอดลูกค้าเพิ่ม 500 บาทเพียงครั้งเดียว
{
"amount": 500,
"merchant_ref": "deposit-order-001"
}Headers: X-Api-Key, Content-Type: application/json, Idempotency-Key: deposit-order-001
ทดสอบให้ครบสามสถานการณ์
| สถานการณ์ | ผลฝั่งร้านที่ต้องตรวจ |
|---|---|
| กดส่งคำขอเดิมซ้ำ | ได้ payment เดิม ไม่สร้างรายการเพิ่ม |
| ส่ง webhook ของ paid ซ้ำ | ยอดลูกค้าไม่เพิ่มรอบที่สอง |
| รายการใหม่: expired แล้ว paid | ในเว็บร้านต้องเห็น Webhook payment.paid: late: true ใต้ออเดอร์ และ ✓ Late deposit พร้อมยอดเพิ่มเพียงครั้งเดียว |
expired เพื่อทดสอบ เมื่อใช้เงินจริง เปิด checkout_url ให้ลูกค้า และยืนยันจ่ายด้วย webhook/API ไม่ใช้การกลับ return_url เป็นหลักฐานตรวจข้อความจริงได้ที่ “Webhook ที่ผ่านการตรวจ” ในเว็บร้าน: payload.late มาจาก webhook ที่ตรวจลายเซ็นแล้ว ไม่อยู่ในผล GET ถ้าข้อมูลเก่าไม่มี payload ให้กดส่ง webhook เดิมซ้ำจาก Sandbox เพื่อเก็บหลักฐาน
ค่าธรรมเนียมตัวอย่าง 1.6%: ฝาก 500 → ยอดร้านใน Sandbox เพิ่ม 492 บาท ส่วนยอดลูกค้าในตัวอย่างเพิ่ม 500 บาท
ทดสอบถอนและการคืนยอดเมื่อถูกปฏิเสธ
Sandbox และเว็บร้านต่างมียอดจำลองเริ่มต้น 10,000 บาท
- ในเว็บร้าน เลือก Withdraw จำนวน 500 บาท ใช้เลขอ้างอิงใหม่
- สร้างรายการ ควรได้
HTTP 202และqueuedเว็บร้านกันยอดลูกค้าไว้ 500 บาท - ใน Sandbox Console กด paid แล้วกลับไปตรวจออเดอร์สำเร็จ โดยไม่หักยอดลูกค้าซ้ำ
- สร้างรายการใหม่เพื่อทดสอบ rejected และ unknown → paid
ดู request ถอนพร้อมข้อมูลผู้รับตัวอย่าง
{
"amount": 500,
"merchant_ref": "withdraw-order-001",
"recipient": {
"type": "account", "bank_code": "004", "account_no": "0012345678",
"account_name": "Example Recipient", "given_name": "Example", "surname": "Recipient",
"address_country": "TH", "address_city": "Bangkok", "address_street": "1 Example Road",
"tax_id": "1234567890123", "email": "recipient@example.com"
}
}ส่ง X-Api-Key และ Idempotency-Key เช่นเดียวกับฝาก เลขบัญชีเป็น string เพื่อเก็บศูนย์นำหน้า ใช้ข้อมูลสมมตินี้เฉพาะ Sandbox
| สถานการณ์ | ผลที่ต้องตรวจ |
|---|---|
| paid | ปิดรายการสำเร็จ ไม่หักยอดซ้ำเมื่อ webhook ซ้ำ |
| rejected | คืนยอดลูกค้าครั้งเดียว แม้ส่ง webhook ซ้ำ |
| unknown → paid | ระหว่าง unknown ยังไม่คืนเงินหรือส่งถอนใหม่ ตามรายการเดิมจนรู้ผล |
| ยอดร้านไม่พอ | API คืน 422 พร้อม withdrawal สถานะ rejected; จัดการ response ทันที ไม่รอ webhook |
ทดสอบยอดร้านไม่พอผ่าน backend ของคุณด้วยจำนวนที่เกินยอด Sandbox หรือกันยอดร้านด้วยรายการ queued เพิ่มก่อน ค่าถอนตัวอย่าง 0.2%: ถอน 500 → กันยอดร้าน 501 บาท ปุ่มเติมยอดจำลองเพิ่มเฉพาะยอดร้านใน Sandbox
ตรวจให้ครบก่อนใช้งานจริง
ผล Mock ยืนยันการเชื่อมต่อจำลอง การเปิดใช้งานจริงต้องตรวจค่าของร้านและ environment อีกครั้ง
เปลี่ยนไป Production อย่างไร
- รับ production URL, API key, webhook secret, เรท และสิทธิ์ฝาก/ถอนของร้านจากผู้ดูแล
- ตั้งค่าเหล่านี้ใน backend ที่ deploy แล้ว พร้อม HTTPS Webhook URL และ IP allowlist ตามที่ร้านใช้
- ใช้ฐานข้อมูลและรายการเงินจริงแยกจากข้อมูลทดลอง แล้วทดสอบรายการจริงตามแผนที่ตกลงกับผู้ดูแล
ข้อมูลที่ส่งให้ทีมช่วยตรวจเมื่อเชื่อมต่อไม่ผ่าน
ส่งขั้นตอนที่ติด, environment, merchant_ref, payment_id/withdrawal_id, เวลาพร้อม timezone, HTTP status และ response ที่ปิดข้อมูลส่วนบุคคลแล้ว ไม่ส่ง API key, webhook secret หรือไฟล์ข้อมูลของ Sandbox