ขั้นตอนการถอนเงิน
เอกสารนี้อธิบายขั้นตอนการถอนเงินอย่างละเอียดสำหรับการเชื่อมต่อกับ Payment Gateway
ภาพรวม
ขั้นตอนการถอนเงินอธิบายกระบวนการทั้งหมดตั้งแต่ลูกค้าเริ่มขอถอนเงินบนเว็บไซต์ของร้านค้า จนถึงการโอนเงินออกสำเร็จ กระบวนการนี้ประกอบด้วยการสื่อสารผ่าน API, การประมวลผลคำขอถอนเงิน และการแจ้งเตือนผ่าน Webhook เพื่อแจ้งสถานะการถอนเงินให้ร้านค้าทราบ
ขั้นตอนการทำงาน
ขั้นตอนที่ 1: ลูกค้าเริ่มคำขอถอนเงิน
กระบวนการถอนเงินเริ่มต้นเมื่อลูกค้าบนเว็บไซต์ของร้านค้าต้องการถอนเงิน:
- ลูกค้าไปที่หน้าถอนเงินบนเว็บไซต์ของร้านค้า
- ลูกค้าระบุจำนวนเงินที่ต้องการถอน
- ลูกค้าตรวจสอบข้อมูลบัญชีธนาคารที่ลงทะเบียน
- ลูกค้ากดส่งคำขอถอนเงิน
ขั้นตอนที่ 2: ระบบหลังบ้านของร้านค้าตรวจสอบคำขอ
ก่อนส่งไปยัง Payment Gateway ระบบของร้านค้าควรทำการตรวจสอบเบื้องต้น:
ตรวจสอบยอดคงเหลือ:
- ตรวจสอบว่าลูกค้ามียอดคงเหลือเพียงพอสำหรับการถอน
- ตรวจสอบวงเงินหรือข้อจำกัดการถอน
- ตรวจสอบจำนวนเงินขั้นต่ำสำหรับการถอน
ตรวจสอบข้อมูลบัญชี:
- ยืนยันว่าบัญชีธนาคารของลูกค้าผ่านการตรวจสอบแล้ว
- ตรวจสอบให้แน่ใจว่าข้อมูลบัญชีครบถ้วนและถูกต้อง
- ตรวจสอบว่าบัญชีไม่ถูกระงับ
ตรวจสอบกฎธุรกิจ:
- ตรวจสอบข้อกำหนดเรื่องระยะเวลารอ (cooling-off period)
- ตรวจสอบวงเงินถอนรายวัน/รายเดือน
- ตรวจสอบสถานะ KYC/AML
ขั้นตอนที่ 3: ระบบหลังบ้านของร้านค้าส่งคำขอถอนเงิน
เมื่อผ่านการตรวจสอบ ระบบหลังบ้านของร้านค้าดำเนินการ:
หักยอดคงเหลือของลูกค้า (แนะนำ):
- หักจำนวนเงินถอนจากยอดคงเหลือที่ใช้ได้ทันที
- ย้ายเงินไปอยู่ในสถานะ "รอการถอน"
- ป้องกันการใช้เงินซ้ำขณะถอนอยู่ระหว่างดำเนินการ
เตรียมข้อมูล request สำหรับการถอนเงิน:
- ข้อมูลรับรองร้านค้า (
merchant_id,token) - Timestamp ปัจจุบัน (
time) - รหัสคำสั่งซื้อที่ไม่ซ้ำกัน (
merchant_order_id) - จำนวนเงินถอน (
amount) - ข้อมูลบัญชีธนาคารของลูกค้าสำหรับโอนเงิน (
bank,account_name,account_no) - URL สำหรับรับ Webhook (
notify_url)
- ข้อมูลรับรองร้านค้า (
สร้าง Signature ด้วย HMAC-SHA256 โดยใช้ secret key ของร้านค้า
ส่ง POST request ไปยัง API endpoint:
/withdraw/create
ตัวอย่าง API Request:
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "WITHDRAW0123456789",
"amount": "5000.00",
"bank": "KBANK",
"account_name": "สมชาย ใสสว่าง",
"account_no": "1234567890",
"notify_url": "https://merchant.com/callback/withdraw"
}
ขั้นตอนที่ 4: ระบบรับและตรวจสอบคำขอ
ระบบ Payment Gateway ประมวลผลคำขอถอนเงิน:
ตรวจสอบการยืนยันตัวตน:
- ตรวจสอบข้อมูลรับรองร้านค้า (
merchant_id,token) - ตรวจสอบ HMAC-SHA256 Signature
- ตรวจสอบความใหม่ของ timestamp เพื่อป้องกัน replay attack
- ตรวจสอบข้อมูลรับรองร้านค้า (
ตรวจสอบ Request:
- ตรวจสอบว่าฟิลด์บังคับทั้งหมดครบถ้วน
- ตรวจสอบรูปแบบจำนวนเงินและยอดขั้นต่ำ
- ตรวจสอบรหัสธนาคารและรูปแบบเลขที่บัญชี
- ตรวจสอบว่าร้านค้ามียอดคงเหลือเพียงพอสำหรับการถอน
สร้างคำสั่งถอนเงิน:
- สร้างรหัสคำสั่งซื้อเฉพาะของแพลตฟอร์ม (platform order ID)
- บันทึกรายละเอียดการถอนทั้งหมด
- ตั้งสถานะเริ่มต้นเป็น "pending"
ส่ง Response ทันที:
- ยืนยันว่าได้รับคำขอถอนเงินแล้ว
- ให้ platform order ID สำหรับติดตาม
- ระบุสถานะเป็น "pending"
ตัวอย่าง API Response:
{
"success": 200,
"data": {
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "pending",
"amount": "5000.00",
"order_datetime": "2024-04-28 14:30:15"
}
}
ฟิลด์สำคัญใน Response:
platform_order_id: รหัสคำสั่งถอนเงินเฉพาะของระบบstatus: สถานะเริ่มต้นเป็น "pending" เสมอorder_datetime: Timestamp เมื่อสร้างคำสั่งถอนเงิน
ขั้นตอนที่ 5: ร้านค้าอัปเดตหน้าจอลูกค้า
เมื่อได้รับ response สถานะ pending ระบบของร้านค้าควร:
อัปเดตสถานะคำสั่งซื้อในฐานข้อมูล:
- เก็บ
platform_order_idสำหรับอ้างอิง - ตั้งสถานะการถอนเป็น "pending"
- บันทึก timestamp ของคำขอ
- เก็บ
แสดงสถานะรอดำเนินการให้ลูกค้า:
- แสดงข้อความ "กำลังดำเนินการถอนเงิน" อย่างชัดเจน
- แสดงเวลาประมาณในการดำเนินการ (ถ้ามี)
- แสดงหมายเลขอ้างอิงคำสั่งซื้อ
- แสดงยอดคงเหลือที่อัปเดต (หักจำนวนเงินแล้ว)
ตั้งค่าการติดตามสถานะ:
- เตรียมรับ Webhook แจ้งเตือน
- อาจสร้างกลไก polling เป็นทางเลือกสำรอง
ขั้นตอนที่ 6: ระบบดำเนินการถอนเงิน
ระบบดำเนินการถอนเงิน:
การจัดการคิว:
- คำขอถอนเข้าคิวประมวลผล
- ดำเนินการตามลำดับ (FIFO)
- เวลาดำเนินการขึ้นอยู่กับปริมาณงานและเวลาทำการธนาคาร
การตรวจสอบการทุจริตและความเสี่ยง:
- อัลกอริทึมตรวจจับการทุจริตอัตโนมัติ
- ตรวจจับรูปแบบที่ผิดปกติ
- แจ้งเตือนรายการที่มีความเสี่ยงสูง
- ตรวจสอบ AML/CFT
การโอนเงิน:
- เริ่มโอนเงินผ่านธนาคารไปยังบัญชีของลูกค้า
- ใช้ Bank API หรือดำเนินการด้วยตนเองขึ้นอยู่กับธนาคารและจำนวนเงิน
- ติดตามสถานะการโอน
ผลลัพธ์การดำเนินการ:
กรณี A: โอนเงินสำเร็จ
- ธนาคารยืนยันการโอนสำเร็จ
- ระบบอัปเดตสถานะเป็น "success"
- ดำเนินต่อขั้นตอนที่ 7 (Webhook สำเร็จ)
กรณี B: โอนเงินล้มเหลว
- ธนาคารปฏิเสธการโอน (บัญชีไม่ถูกต้อง บัญชีปิดแล้ว ฯลฯ)
- ปัญหาทางเทคนิคทำให้ไม่สามารถโอนได้
- ระบบอัปเดตสถานะเป็น "failed"
- ดำเนินต่อขั้นตอนที่ 8 (Webhook ล้มเหลว)
ขั้นตอนที่ 7: ระบบส่ง Webhook แจ้งสำเร็จ
เมื่อการถอนเงินเสร็จสมบูรณ์:
Webhook ถูกเรียก:
- ระบบส่ง POST request ไปยัง
notify_url - รวมรายละเอียดการถอนเงินทั้งหมด
- สถานะระบุเป็น "success"
- ระบบส่ง POST request ไปยัง
Webhook Payload:
ตัวอย่าง Webhook สำเร็จ:
{
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "success",
"amount": "5000.00",
"completed_datetime": "2024-04-28 14:45:32",
"bank": "KBANK",
"account_no": "1234567890",
"account_name": "สมชาย ใสสว่าง"
}
Webhook Handler ของร้านค้าควร:
- ตรวจสอบ Signature ของ Webhook (ถ้ามี)
- ยืนยันว่า
merchant_order_idตรงกับคำขอถอนที่รอดำเนินการ - ตรวจสอบว่าคำสั่งซื้อยังไม่ถูกดำเนินการแล้ว
- อัปเดตสถานะคำสั่งซื้อเป็น "success" ในฐานข้อมูล
- บันทึก timestamp เมื่อเสร็จสิ้น
- ส่งการแจ้งเตือนให้ลูกค้า
- ตอบกลับ HTTP 200 OK เพื่อยืนยันการรับ
แจ้งเตือนลูกค้า:
- แจ้งเตือนทางอีเมล/SMS ว่าถอนเงินสำเร็จ
- อัปเดตประวัติรายการในบัญชี
- แสดงข้อความสำเร็จบนหน้าจอ
สำหรับรายละเอียด Webhook ดูเอกสาร Callback การถอนเงิน
ขั้นตอนที่ 8: ระบบส่ง Webhook แจ้งล้มเหลว
เมื่อไม่สามารถดำเนินการถอนเงินได้:
Webhook ถูกเรียก:
- ระบบส่ง POST request ไปยัง
notify_url - รวมรายละเอียดการถอนและเหตุผลที่ล้มเหลว
- สถานะระบุเป็น "failed"
- ระบบส่ง POST request ไปยัง
Webhook Payload:
ตัวอย่าง Webhook ล้มเหลว:
{
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "failed",
"amount": "5000.00",
"failed_datetime": "2024-04-28 14:40:18",
"bank": "KBANK",
"account_no": "1234567890",
"account_name": "สมชาย ใสสว่าง",
"error_message": "Invalid account number or account closed"
}
Webhook Handler ของร้านค้าควร:
- ตรวจสอบ Signature ของ Webhook (ถ้ามี)
- ยืนยันว่า
merchant_order_idตรงกับคำขอถอนที่รอดำเนินการ - อัปเดตสถานะคำสั่งซื้อเป็น "failed" ในฐานข้อมูล
- คืนยอดเงินที่หักไปกลับเข้ายอดคงเหลือของลูกค้า
- บันทึกเหตุผลที่ล้มเหลว
- แจ้งลูกค้าเรื่องความล้มเหลว
- ตอบกลับ HTTP 200 OK เพื่อยืนยันการรับ
แจ้งเตือนลูกค้า:
- แจ้งเตือนทันทีเรื่องการถอนเงินล้มเหลว
- อธิบายเหตุผลที่ล้มเหลวอย่างชัดเจน
- ให้คำแนะนำในการแก้ไข
- ยืนยันว่าได้คืนเงินเข้ายอดคงเหลือแล้ว
ทางเลือกเมื่อไม่ได้รับ Webhook
ในกรณีที่ระบบของร้านค้าไม่ได้รับ Webhook แจ้งเตือน:
ทางเลือกที่ 1: ตรวจสอบสถานะการถอนเงินด้วยตนเอง
ร้านค้าสามารถตรวจสอบสถานะการถอนเงินได้:
สร้างกลไก Polling:
- หลังจากรอเวลาที่เหมาะสม (เช่น 30-60 นาที)
- ส่ง request ไปยัง
/withdraw/queryendpoint - ระบุ
merchant_order_idหรือplatform_order_id
ประมวลผล Response:
- รับสถานะการถอนปัจจุบัน
- อัปเดตสถานะคำสั่งซื้อตามผลลัพธ์
- ดำเนินการที่เหมาะสมตามสถานะ
แนวทางปฏิบัติสำหรับ Polling:
- อย่า poll บ่อยเกินไป (เคารพ rate limit)
- ใช้ exponential backoff
- กำหนดระยะเวลา polling สูงสุด
- หยุด polling เมื่อได้รับสถานะสุดท้าย
ตัวอย่าง Query Request:
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "WITHDRAW0123456789"
}
สำหรับรายละเอียด ดูเอกสาร ตรวจสอบคำสั่งถอนเงิน
ทางเลือกที่ 2: ส่งเรื่องให้ฝ่ายสนับสนุน
สำหรับสถานะ pending ที่ค้างนานโดยไม่ได้รับ Webhook:
- ลูกค้าติดต่อฝ่ายสนับสนุนของร้านค้า
- ฝ่ายสนับสนุนตรวจสอบสถานะผ่าน API
- แก้ไขด้วยตนเองหากจำเป็น
- ประสานงานกับทีมสนับสนุนหากต้องการ
สถานะการถอนเงิน
สถานะ: pending
- คำอธิบาย: ได้รับคำขอถอนเงินและอยู่ในคิวรอดำเนินการ
- การดำเนินการของลูกค้า: รอการดำเนินการ
- การดำเนินการของร้านค้า: รอรับ Webhook แจ้งเตือน
- ระยะเวลาโดยทั่วไป: 5-60 นาทีในเวลาทำการธนาคาร
สถานะ: success
- คำอธิบาย: โอนเงินเข้าบัญชีธนาคารของลูกค้าสำเร็จ
- การดำเนินการของลูกค้า: ตรวจสอบบัญชีธนาคาร
- การดำเนินการของร้านค้า: อัปเดตสถานะ แจ้งลูกค้า
- ระยะเวลาโดยทั่วไป: สถานะสุดท้าย
สถานะ: failed
- คำอธิบาย: ไม่สามารถดำเนินการถอนเงินได้
- การดำเนินการของลูกค้า: ตรวจสอบข้อมูลบัญชี ส่งคำขอใหม่หากต้องการ
- การดำเนินการของร้านค้า: คืนเงินเข้ายอดคงเหลือ แจ้งลูกค้า
- ระยะเวลาโดยทั่วไป: สถานะสุดท้าย
สาเหตุที่ล้มเหลวบ่อย
ข้อมูลบัญชีไม่ถูกต้อง
สาเหตุ:
- เลขที่บัญชีไม่ถูกต้อง
- ชื่อบัญชีไม่ตรง
- บัญชีปิดหรือถูกระงับ
- รหัสธนาคารไม่ถูกต้อง
การแก้ไข:
- ลูกค้าแก้ไขข้อมูลบัญชีธนาคาร
- ร้านค้าตรวจสอบข้อมูลบัญชีซ้ำ
- ส่งคำขอถอนเงินใหม่
ยอดคงเหลือของร้านค้าไม่เพียงพอ
สาเหตุ:
- ยอดคงเหลือในระบบของร้านค้าต่ำเกินไป
- ยอดที่รอ settle ยังไม่เคลียร์
การแก้ไข:
- ร้านค้าเติมเงินเข้าบัญชีในระบบ
- รอให้ยอดที่รอ settle เคลียร์
- ติดต่อฝ่ายจัดการบัญชี
ปัญหาระบบธนาคาร
สาเหตุ:
- Bank API ไม่พร้อมใช้งานชั่วคราว
- ข้อจำกัดเรื่องเวลาทำการ (นอกเวลาทำการ)
- ธนาคารบำรุงรักษาระบบ
การแก้ไข:
- ระบบลองส่งใหม่อัตโนมัติ
- ดำเนินการด้วยตนเองในเวลาทำการถัดไป
- ลูกค้ารอการลองใหม่/ดำเนินการซ้ำ
ถูกระงับเนื่องจากกฎระเบียบ
สาเหตุ:
- รายการถูกแจ้งเตือนโดยระบบตรวจจับการทุจริต
- ถูกระงับเพื่อตรวจสอบ AML/CFT
- ข้อจำกัดทางกฎระเบียบ
การแก้ไข:
- ต้องมีการยืนยันตัวตนเพิ่มเติม
- ติดต่อทีม Compliance
- ส่งเอกสารที่ร้องขอ
ข้อควรพิจารณาที่สำคัญ
การจัดการยอดคงเหลือ
การหักยอดทันที (แนะนำ):
เมื่อลูกค้าขอถอนเงิน ให้ดำเนินการทันที:
- หักจำนวนเงินจากยอดคงเหลือที่ใช้ได้
- ย้ายไปยังบัญชี "รอการถอน"
- ป้องกันลูกค้าจากการใช้เงินซ้ำ
เมื่อได้รับ Webhook:
- ถ้าสำเร็จ: สรุปการถอน ไม่ต้องปรับยอด
- ถ้าล้มเหลว: คืนเงินจาก "รอการถอน" กลับเข้า "ยอดที่ใช้ได้"
เหตุผล:
- ป้องกันสถานการณ์ยอดติดลบ
- ทำให้การบัญชีง่ายขึ้น
- ป้องกันปัญหาจาก timing ของระบบ
ความน่าเชื่อถือของ Webhook
สร้าง Webhook Handler ที่มีความทนทาน:
Idempotency:
- ตรวจสอบว่าคำสั่งซื้อถูกดำเนินการแล้วหรือไม่
- ป้องกันการดำเนินการซ้ำ
- ใช้ database transaction
ตอบกลับอย่างรวดเร็ว:
- ตอบกลับ HTTP 200 ทันที
- ประมวลผล business logic แบบ asynchronous
- อย่าค้าง connection ไว้นาน
การจัดการข้อผิดพลาด:
- บันทึก log การรับ Webhook ทั้งหมด
- จัดการ request ที่ผิดรูปแบบอย่างสง่างาม
- สร้างกลไก retry สำหรับการประมวลผลที่ล้มเหลว
ความปลอดภัย:
- ตรวจสอบ Signature ของ Webhook
- ตรวจสอบที่มาของ request
- ใช้ HTTPS สำหรับ notify_url
ระยะเวลาดำเนินการที่คาดหวัง
การดำเนินการปกติ:
- ในเวลาทำการธนาคาร: 5-30 นาที
- นอกเวลาทำการ: วันทำการถัดไป
- วันหยุด/วันหยุดนักขัตฤกษ์: วันทำการถัดไป
ปัจจัยที่ส่งผลต่อความเร็ว:
- ความสามารถในการประมวลผลของธนาคาร
- จำนวนเงิน (จำนวนมากอาจต้องตรวจสอบเพิ่มเติม)
- ช่วงเวลาของวันและวันในสัปดาห์
- ปริมาณรายการในขณะนั้น
การสื่อสารกับลูกค้า
อัปเดตเชิงรุก:
- ยืนยันการรับคำขอถอนเงินทันที
- อัปเดตสถานะเมื่อถึงจุดสำคัญ
- แจ้งยืนยันสำเร็จหรือล้มเหลวขั้นสุดท้าย
คำแนะนำที่ชัดเจน:
- ระยะเวลาดำเนินการที่คาดหวัง
- สิ่งที่ลูกค้าควรทำขณะรอ
- วิธีตรวจสอบเงินเข้าบัญชีธนาคาร
- ช่องทางติดต่อเมื่อมีปัญหา
แผนภาพลำดับขั้นตอน
ลูกค้า เว็บไซต์ร้านค้า ระบบหลังบ้านร้านค้า Payment API
| | | |
|--[ขอถอนเงิน]------->| | |
| | | |
| |----[ตรวจสอบคำขอ]-------->| |
| | | |
| | [หักยอดคงเหลือ] |
| | | |
| | |--[POST /withdraw]------>|
| | | |
| | | [สร้างคำสั่ง]
| | | [สถานะ PENDING]
| | | |
| | |<--[Pending Response]---|
| | | |
| |<---[แสดงสถานะรอ]---------| |
| | | |
|<--[สถานะ Pending]---| | |
| | | |
| [รอดำเนินการ...] | |
| | | [ดำเนินการ]
| | | [โอนเงินผ่านธนาคาร]
| | | |
| | | [สำเร็จ/ล้มเหลว]
| | | |
| | |<--[Webhook Callback]---|
| | | |
| | [อัปเดตสถานะ / คืนเงินถ้าล้มเหลว] |
| | | |
| | |---[HTTP 200 OK]-------->|
| | | |
|<--[สถานะสุดท้าย]----|<---[แจ้งลูกค้า]----------| |
| | | |
เอกสารที่เกี่ยวข้อง
- สร้างคำสั่งถอนเงิน - ข้อกำหนด API สำหรับสร้างคำขอถอนเงิน
- Callback การถอนเงิน - รูปแบบและการจัดการ Webhook แจ้งเตือน
- ตรวจสอบคำสั่งถอนเงิน - การตรวจสอบสถานะการถอนเงิน
- การยืนยันตัวตน - การยืนยันตัวตนและการสร้าง Signature ของ API
- ตรวจสอบยอดเงิน - ตรวจสอบยอดคงเหลือของร้านค้าก่อนถอน