ขั้นตอนการฝาก (Deposit Flow)
✅ แนะนำ : ใช้ สร้างคำสั่งชำระเงิน — FLEX (หน้าชำระเงิน) — เรียก API ครั้งเดียว ระบบจะเลือกใช้ทุกช่องทางการชำระเงินที่มีโดยอัตโนมัติ และคืน
payment_urlของหน้าชำระเงินที่จัดการ flow ของลูกค้าให้ทั้งหมด (วิธีใช้งาน, QR Code หรือบัญชีปลายทาง, ยอดที่ต้องโอนเป๊ะ, countdown, แจ้งสลิป และสถานะ real-time)
เอกสารนี้อธิบายขั้นตอนการฝากเงินแบบครบวงจร เมื่อเชื่อมต่อกับ Payment Gateway ผ่าน endpoint FLEX
ภาพรวม
Deposit flow คือกระบวนการตั้งแต่ลูกค้ากดฝากเงินบนเว็บไซต์ของร้านค้า ไปจนถึงการยืนยันเครดิตยอดเงิน สำเร็จ ด้วย FLEX ร้านค้าเรียก API เพียง ครั้งเดียว แล้วพาลูกค้าไปยังหน้าชำระเงินที่ระบบ โฮสต์ให้ หน้านั้นจะพาลูกค้าทำรายการทั้งหมด และร้านค้าจะได้รับแจ้งผ่าน webhook เมื่อการชำระเงินสำเร็จ
ขั้นตอน
Step 1: ลูกค้าเริ่มทำรายการฝาก
กระบวนการเริ่มเมื่อลูกค้าบนเว็บไซต์ร้านค้าต้องการฝากเงิน:
- ลูกค้าเข้าหน้าฝากเงินบนเว็บไซต์ร้านค้า
- ลูกค้ากรอกจำนวนเงินที่ต้องการฝาก
- ลูกค้ากดยืนยันคำสั่งฝาก
Step 2: Backend ร้านค้าสร้างคำสั่ง FLEX
เมื่อรับคำสั่งฝากจากลูกค้า ระบบ backend ของร้านค้าต้อง:
เตรียม payload ของคำขอ ประกอบด้วย:
- Credential ของ merchant (
merchant_id,token) - timestamp ปัจจุบัน (
time) - merchant order id ที่ไม่ซ้ำ (
merchant_order_id) - จำนวนเงินฝาก (
amount) - URL สำหรับ webhook (
notify_url) - (optional)
redirect_url— หน้าที่จะพาลูกค้ากลับมาหลังชำระเงิน - (optional)
payment_theme— ธีมของหน้าชำระเงิน
- Credential ของ merchant (
สร้าง signature แบบ HMAC-SHA256 ด้วย secret key ของร้านค้า
ส่ง POST request ไปยัง API endpoint:
/payment-flex/create
ตัวอย่าง Request:
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "ORDER0123456789789445566",
"amount": "1000.00",
"notify_url": "https://merchant.com/callback/payment",
"redirect_url": "https://merchant.com/return",
"payment_theme": "halo"
}
Step 3: ระบบคืน Payment URL ของหน้าชำระเงิน
ระบบจะประมวลผลคำขอและ:
- ตรวจสอบ credential และ signature
- สร้าง platform order id ที่ไม่ซ้ำ
- เลือกช่องทางการชำระเงินที่ดีที่สุดให้ออเดอร์นั้น
- คืน
payment_urlของหน้าชำระเงินกลับมา
ตัวอย่าง Response:
{
"success": 200,
"data": {
"platform_order_id": "THBP202605061004030AAAA001",
"payment_method": "FLEX",
"payment_url": "https://payment.example.com/THBP202605061004030AAAA001/<hash>"
}
}
ฟิลด์สำคัญใน Response:
platform_order_id: order id ของระบบ — เก็บไว้ใช้กระทบยอดpayment_url: หน้าชำระเงิน — พาลูกค้าไปที่นี่
Pending-order guard (
409) : ลูกค้าหนึ่งบัญชีเปิด FLEX order ค้างได้ครั้งละ 1 รายการ ถ้าลูกค้ามี order ค้างอยู่ API จะคืน409พร้อมdata.pending_order_id— ให้ใช้ order เดิมต่อ, ให้ลูกค้ายกเลิกบนหน้าชำระเงิน, หรือยกเลิกจาก backend ผ่าน ยกเลิกคำสั่งชำระเงิน ก่อนสร้างรายการใหม่
Step 4: ร้านค้าเปิด Payment URL ให้ลูกค้า
ร้านค้าเพียงพาลูกค้าไปที่ payment_url — ไม่ต้อง render อะไรเองเลย:
- redirect browser ของลูกค้าไปที่
payment_urlหรือ - ฝังเป็น iframe ในหน้าเว็บของคุณเอง
Step 5: หน้าชำระเงินจัดการ Flow ลูกค้าให้ทั้งหมด
หน้าชำระเงินที่ระบบโฮสต์ให้จะพาลูกค้าทำทุกอย่าง:
- คำแนะนำการชำระเงินที่ชัดเจน
- QR Code หรือ บัญชีปลายทาง (แล้วแต่ช่องทางที่เลือก)
- ยอดที่ต้องโอน เป๊ะ (
transfer_amountที่อาจมีเศษทศนิยม) - countdown แสดงเวลาที่เหลือก่อนหมดอายุ
- การแจ้งสลิป (ถ้าต้องใช้)
- สถานะการชำระเงินแบบ real-time
ลูกค้าจ่ายผ่านแอปธนาคารและ (ถ้าจำเป็น) แจ้งสลิป — ทั้งหมดบนหน้าชำระเงิน คุณไม่ต้องสร้างส่วนเหล่านี้เอง
Step 6: ระบบตรวจจับและยืนยันการชำระเงิน
เมื่อลูกค้าโอนเงินเสร็จ:
- ระบบตรวจจับรายการเงินเข้า
- ระบบตรวจสอบยอดและจับคู่กับออเดอร์ที่เปิดอยู่
- สถานะการชำระเงินถูกอัปเดตเป็น paid
Step 7: ระบบส่ง Webhook แจ้งร้านค้า
หลังยืนยันการชำระเงินสำเร็จ ระบบจะส่ง webhook ไปที่ร้านค้า:
- ยิง POST request ไปที่
notify_urlที่ส่งมาตอนสร้างออเดอร์ - payload มีรายละเอียดยืนยันการชำระเงิน (
mode: PAYMENT,status: PAID) - ระบบจะ retry จนกว่าจะได้
HTTP 200ดังนั้น handler ของคุณต้อง idempotent
ดูรายละเอียด webhook ที่ Payment Callback
Step 8: ร้านค้าเครดิตยอดให้ลูกค้า
เมื่อได้รับ webhook ระบบร้านค้าควร:
ตรวจสอบ webhook:
- ตรวจ signature
- ยืนยันว่า
merchant_order_idตรงกับออเดอร์เดิม - เช็คว่ายังไม่ได้ประมวลผลออเดอร์นี้มาก่อน (กันเครดิตซ้ำ)
อัปเดตสถานะออเดอร์: mark ว่าจ่ายแล้ว เก็บ
platform_order_idเครดิตให้ลูกค้า: เพิ่มยอดฝากเข้ายอดเงินของลูกค้า
ตอบกลับ: คืน
HTTP 200 OKเพื่อยืนยันว่าได้รับ webhook แล้ว
หลังชำระเงิน หน้าชำระเงินจะพาลูกค้ากลับไปที่ redirect_url (ถ้าระบุ)
Flow สำรอง: กรณี Webhook ไม่มา
ถ้าไม่ได้รับ webhook (ปัญหา network, server ล่ม ฯลฯ) มี 2 วิธีตรวจสอบสำรอง:
วิธีที่ 1: Query สถานะการชำระเงิน
ร้านค้า query สถานะการชำระเงินได้เอง:
- ส่งคำขอไปที่
/payment/queryพร้อมmerchant_order_idหรือplatform_order_id - รับสถานะปัจจุบัน
- ประมวลผลตามสถานะที่ได้
ดูรายละเอียดที่ ตรวจสอบคำสั่งชำระเงิน
วิธีที่ 2: ลูกค้าแจ้งสลิป
บนหน้า FLEX ลูกค้าสามารถอัปโหลดสลิปได้โดยตรง ถ้าต้องการส่งสลิปแบบ server-to-server ใช้ Slip Upload API:
- แนบรูปสลิปและ order reference
- ระบบตรวจสอบสลิปกับรายการธุรกรรมแล้วยืนยัน
ดูรายละเอียดที่ อัปโหลดสลิป
ข้อควรระวัง
เรื่องเวลาสำคัญมาก
Decimal Variance Matching: หน้าชำระเงินจะแสดงยอด
transfer_amountเป๊ะให้ลูกค้า (เช่น 1000.03 แทน 1000.00) ซึ่งล็อกกับออเดอร์และช่วงเวลานั้นเพื่อจับคู่ให้แม่นยำผลของการโอนช้า: ถ้าลูกค้าโอนหลังหมดเวลา ระบบอาจจัดสรรยอดเป๊ะนั้นให้ออเดอร์อื่นไปแล้ว เงินอาจถูกเครดิตให้ออเดอร์ผิด และ ระบบคืนเงินที่จัดสรรผิดไม่ได้ — countdown บนหน้าชำระเงิน มีไว้เพื่อป้องกันเรื่องนี้
โอนครั้งเดียว: ลูกค้าต้องโอนครั้งเดียว ยอดเป๊ะ ก่อนหมดเวลา
Idempotency สำคัญมาก
เพราะระบบจะ retry webhook จนกว่าจะได้ HTTP 200 handler ของคุณ จะ ได้รับ
platform_order_id เดิมมากกว่าหนึ่งครั้ง ให้เครดิตแบบ idempotent เสมอ — เครดิตแต่ละออเดอร์เพียงครั้งเดียว
ไม่ว่าจะมี callback เข้ามากี่ครั้ง
การจัดการ Error
กรณีที่พบบ่อย
ออเดอร์หมดอายุ: ลูกค้าไม่จ่ายทันเวลา → ลูกค้าสร้างคำสั่งฝากใหม่ (pending guard
409จะถูกปลดเมื่อออเดอร์เดิมปิด/ถูกยกเลิก)มีออเดอร์ค้าง (
409): ลูกค้ามี FLEX order เปิดอยู่แล้ว → ใช้data.pending_order_idเดิม หรือยกเลิก (บนหน้าชำระเงิน หรือผ่าน cancel API) ก่อนสร้างใหม่ อย่า retry วนลูกค้ายกเลิก: ลูกค้ากด ยกเลิก บนหน้าชำระเงิน → มี callback
CANCELLEDการยกเลิกอาจไม่ถือเป็น ที่สิ้นสุดเสมอไป อาจมี callbackPAIDตามมาภายหลังสำหรับออเดอร์เดิมได้ (ให้ถือว่าPAIDถูกต้อง) มิฉะนั้นให้สร้างออเดอร์ใหม่เมื่อลูกค้าลองอีกครั้งWebhook ส่งไม่สำเร็จ: จ่ายสำเร็จแต่ร้านค้าไม่ได้รับแจ้ง → ใช้ query API หรือ slip upload ข้างต้น ป้องกันด้วยการทำ webhook endpoint ที่ทนทานและ idempotent พร้อม fallback poll
Best Practice สำหรับร้านค้า
การจัดการออเดอร์:
- เก็บ
platform_order_idจาก response ไว้กระทบยอด - จัดการ
409ด้วยการใช้data.pending_order_idเดิม
- เก็บ
หน้าชำระเงิน:
- แค่ redirect (หรือ iframe) ลูกค้าไปที่
payment_url— อย่าดึง QR / เลขบัญชีออกมา render เองใน UI - ระบุ
redirect_urlเพื่อพาลูกค้ากลับมาที่เว็บคุณหลังจ่ายเสร็จ
- แค่ redirect (หรือ iframe) ลูกค้าไปที่
การทำ Webhook:
- ทำ webhook handler แบบ idempotent (กันเครดิตซ้ำ)
- ตอบ
HTTP 200เร็ว ๆ แล้วค่อยประมวลผลแบบ async ถ้าจำเป็น - ตรวจ signature และ log ทุก webhook ไว้ตรวจสอบ
การกู้คืนเมื่อ Error:
- ทำ payment-query polling เป็น backup ของ webhook (เช่น ออเดอร์ที่ค้าง > 1 ชม.)
- เก็บ API response ทั้งหมดไว้ debug
การสื่อสารกับลูกค้า:
- ส่ง email/SMS ยืนยันเมื่อฝากสำเร็จ
- มีช่องทางติดต่อ support สำหรับปัญหาการชำระเงิน
Sequence Diagram
Customer Merchant Website Merchant Backend Payment API Payment Page
| | | | |
|--[Enter Amount]---->| | | |
| |----[Create Deposit]----->| | |
| | |--[POST /payment-flex]-->| |
| | |<--[payment_url]---------| |
| |<---[payment_url]---------| | |
|--[Open payment_url]-|--------------------------|-------------------------|------------------->|
|<--[Instructions + QR or bank account + countdown]------------------------|--------------------|
|--[Transfer & submit slip on the page]------------------------------------|------------------->|
| | | [Verify Payment] |
| | |<--[Webhook Callback]---| |
| | [Credit Account] | |
| | |---[HTTP 200 OK]-------->| |
|<--[Redirect to redirect_url]------------------------------------------------------------------|
เอกสารที่เกี่ยวข้อง
- สร้างคำสั่งชำระเงิน — FLEX - ข้อกำหนด API ของ endpoint FLEX
- ฝังหน้าชำระเงินผ่าน iframe - การฝังหน้าชำระเงินในเว็บคุณ
- Payment Callback - รูปแบบและการจัดการ webhook
- ตรวจสอบคำสั่งชำระเงิน - ตรวจสอบสถานะการชำระเงินทางเลือก
- อัปโหลดสลิป - ยืนยันการชำระเงินด้วยการแจ้งสลิป
- การยืนยันตัวตน - การยืนยันตัวตนและการสร้าง signature