ขั้นตอนการถอนเงิน

เอกสารนี้อธิบายขั้นตอนการถอนเงินอย่างละเอียดสำหรับการเชื่อมต่อกับ Payment Gateway

ภาพรวม

ขั้นตอนการถอนเงินอธิบายกระบวนการทั้งหมดตั้งแต่ลูกค้าเริ่มขอถอนเงินบนเว็บไซต์ของร้านค้า จนถึงการโอนเงินออกสำเร็จ กระบวนการนี้ประกอบด้วยการสื่อสารผ่าน API, การประมวลผลคำขอถอนเงิน และการแจ้งเตือนผ่าน Webhook เพื่อแจ้งสถานะการถอนเงินให้ร้านค้าทราบ

ขั้นตอนการทำงาน

ขั้นตอนที่ 1: ลูกค้าเริ่มคำขอถอนเงิน

กระบวนการถอนเงินเริ่มต้นเมื่อลูกค้าบนเว็บไซต์ของร้านค้าต้องการถอนเงิน:

  1. ลูกค้าไปที่หน้าถอนเงินบนเว็บไซต์ของร้านค้า
  2. ลูกค้าระบุจำนวนเงินที่ต้องการถอน
  3. ลูกค้าตรวจสอบข้อมูลบัญชีธนาคารที่ลงทะเบียน
  4. ลูกค้ากดส่งคำขอถอนเงิน

ขั้นตอนที่ 2: ระบบหลังบ้านของร้านค้าตรวจสอบคำขอ

ก่อนส่งไปยัง Payment Gateway ระบบของร้านค้าควรทำการตรวจสอบเบื้องต้น:

  1. ตรวจสอบยอดคงเหลือ:

    • ตรวจสอบว่าลูกค้ามียอดคงเหลือเพียงพอสำหรับการถอน
    • ตรวจสอบวงเงินหรือข้อจำกัดการถอน
    • ตรวจสอบจำนวนเงินขั้นต่ำสำหรับการถอน
  2. ตรวจสอบข้อมูลบัญชี:

    • ยืนยันว่าบัญชีธนาคารของลูกค้าผ่านการตรวจสอบแล้ว
    • ตรวจสอบให้แน่ใจว่าข้อมูลบัญชีครบถ้วนและถูกต้อง
    • ตรวจสอบว่าบัญชีไม่ถูกระงับ
  3. ตรวจสอบกฎธุรกิจ:

    • ตรวจสอบข้อกำหนดเรื่องระยะเวลารอ (cooling-off period)
    • ตรวจสอบวงเงินถอนรายวัน/รายเดือน
    • ตรวจสอบสถานะ KYC/AML

ขั้นตอนที่ 3: ระบบหลังบ้านของร้านค้าส่งคำขอถอนเงิน

เมื่อผ่านการตรวจสอบ ระบบหลังบ้านของร้านค้าดำเนินการ:

  1. หักยอดคงเหลือของลูกค้า (แนะนำ):

    • หักจำนวนเงินถอนจากยอดคงเหลือที่ใช้ได้ทันที
    • ย้ายเงินไปอยู่ในสถานะ "รอการถอน"
    • ป้องกันการใช้เงินซ้ำขณะถอนอยู่ระหว่างดำเนินการ
  2. เตรียมข้อมูล request สำหรับการถอนเงิน:

    • ข้อมูลรับรองร้านค้า (merchant_id, token)
    • Timestamp ปัจจุบัน (time)
    • รหัสคำสั่งซื้อที่ไม่ซ้ำกัน (merchant_order_id)
    • จำนวนเงินถอน (amount)
    • ข้อมูลบัญชีธนาคารของลูกค้าสำหรับโอนเงิน (bank, account_name, account_no)
    • URL สำหรับรับ Webhook (notify_url)
  3. สร้าง Signature ด้วย HMAC-SHA256 โดยใช้ secret key ของร้านค้า

  4. ส่ง 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 ประมวลผลคำขอถอนเงิน:

  1. ตรวจสอบการยืนยันตัวตน:

    • ตรวจสอบข้อมูลรับรองร้านค้า (merchant_id, token)
    • ตรวจสอบ HMAC-SHA256 Signature
    • ตรวจสอบความใหม่ของ timestamp เพื่อป้องกัน replay attack
  2. ตรวจสอบ Request:

    • ตรวจสอบว่าฟิลด์บังคับทั้งหมดครบถ้วน
    • ตรวจสอบรูปแบบจำนวนเงินและยอดขั้นต่ำ
    • ตรวจสอบรหัสธนาคารและรูปแบบเลขที่บัญชี
    • ตรวจสอบว่าร้านค้ามียอดคงเหลือเพียงพอสำหรับการถอน
  3. สร้างคำสั่งถอนเงิน:

    • สร้างรหัสคำสั่งซื้อเฉพาะของแพลตฟอร์ม (platform order ID)
    • บันทึกรายละเอียดการถอนทั้งหมด
    • ตั้งสถานะเริ่มต้นเป็น "pending"
  4. ส่ง 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:

ขั้นตอนที่ 5: ร้านค้าอัปเดตหน้าจอลูกค้า

เมื่อได้รับ response สถานะ pending ระบบของร้านค้าควร:

  1. อัปเดตสถานะคำสั่งซื้อในฐานข้อมูล:

    • เก็บ platform_order_id สำหรับอ้างอิง
    • ตั้งสถานะการถอนเป็น "pending"
    • บันทึก timestamp ของคำขอ
  2. แสดงสถานะรอดำเนินการให้ลูกค้า:

    • แสดงข้อความ "กำลังดำเนินการถอนเงิน" อย่างชัดเจน
    • แสดงเวลาประมาณในการดำเนินการ (ถ้ามี)
    • แสดงหมายเลขอ้างอิงคำสั่งซื้อ
    • แสดงยอดคงเหลือที่อัปเดต (หักจำนวนเงินแล้ว)
  3. ตั้งค่าการติดตามสถานะ:

    • เตรียมรับ Webhook แจ้งเตือน
    • อาจสร้างกลไก polling เป็นทางเลือกสำรอง

ขั้นตอนที่ 6: ระบบดำเนินการถอนเงิน

ระบบดำเนินการถอนเงิน:

  1. การจัดการคิว:

    • คำขอถอนเข้าคิวประมวลผล
    • ดำเนินการตามลำดับ (FIFO)
    • เวลาดำเนินการขึ้นอยู่กับปริมาณงานและเวลาทำการธนาคาร
  2. การตรวจสอบการทุจริตและความเสี่ยง:

    • อัลกอริทึมตรวจจับการทุจริตอัตโนมัติ
    • ตรวจจับรูปแบบที่ผิดปกติ
    • แจ้งเตือนรายการที่มีความเสี่ยงสูง
    • ตรวจสอบ AML/CFT
  3. การโอนเงิน:

    • เริ่มโอนเงินผ่านธนาคารไปยังบัญชีของลูกค้า
    • ใช้ Bank API หรือดำเนินการด้วยตนเองขึ้นอยู่กับธนาคารและจำนวนเงิน
    • ติดตามสถานะการโอน
  4. ผลลัพธ์การดำเนินการ:

    กรณี A: โอนเงินสำเร็จ

    • ธนาคารยืนยันการโอนสำเร็จ
    • ระบบอัปเดตสถานะเป็น "success"
    • ดำเนินต่อขั้นตอนที่ 7 (Webhook สำเร็จ)

    กรณี B: โอนเงินล้มเหลว

    • ธนาคารปฏิเสธการโอน (บัญชีไม่ถูกต้อง บัญชีปิดแล้ว ฯลฯ)
    • ปัญหาทางเทคนิคทำให้ไม่สามารถโอนได้
    • ระบบอัปเดตสถานะเป็น "failed"
    • ดำเนินต่อขั้นตอนที่ 8 (Webhook ล้มเหลว)

ขั้นตอนที่ 7: ระบบส่ง Webhook แจ้งสำเร็จ

เมื่อการถอนเงินเสร็จสมบูรณ์:

  1. Webhook ถูกเรียก:

    • ระบบส่ง POST request ไปยัง notify_url
    • รวมรายละเอียดการถอนเงินทั้งหมด
    • สถานะระบุเป็น "success"
  2. 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": "สมชาย ใสสว่าง"
}
  1. Webhook Handler ของร้านค้าควร:

    • ตรวจสอบ Signature ของ Webhook (ถ้ามี)
    • ยืนยันว่า merchant_order_id ตรงกับคำขอถอนที่รอดำเนินการ
    • ตรวจสอบว่าคำสั่งซื้อยังไม่ถูกดำเนินการแล้ว
    • อัปเดตสถานะคำสั่งซื้อเป็น "success" ในฐานข้อมูล
    • บันทึก timestamp เมื่อเสร็จสิ้น
    • ส่งการแจ้งเตือนให้ลูกค้า
    • ตอบกลับ HTTP 200 OK เพื่อยืนยันการรับ
  2. แจ้งเตือนลูกค้า:

    • แจ้งเตือนทางอีเมล/SMS ว่าถอนเงินสำเร็จ
    • อัปเดตประวัติรายการในบัญชี
    • แสดงข้อความสำเร็จบนหน้าจอ

สำหรับรายละเอียด Webhook ดูเอกสาร Callback การถอนเงิน

ขั้นตอนที่ 8: ระบบส่ง Webhook แจ้งล้มเหลว

เมื่อไม่สามารถดำเนินการถอนเงินได้:

  1. Webhook ถูกเรียก:

    • ระบบส่ง POST request ไปยัง notify_url
    • รวมรายละเอียดการถอนและเหตุผลที่ล้มเหลว
    • สถานะระบุเป็น "failed"
  2. 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"
}
  1. Webhook Handler ของร้านค้าควร:

    • ตรวจสอบ Signature ของ Webhook (ถ้ามี)
    • ยืนยันว่า merchant_order_id ตรงกับคำขอถอนที่รอดำเนินการ
    • อัปเดตสถานะคำสั่งซื้อเป็น "failed" ในฐานข้อมูล
    • คืนยอดเงินที่หักไปกลับเข้ายอดคงเหลือของลูกค้า
    • บันทึกเหตุผลที่ล้มเหลว
    • แจ้งลูกค้าเรื่องความล้มเหลว
    • ตอบกลับ HTTP 200 OK เพื่อยืนยันการรับ
  2. แจ้งเตือนลูกค้า:

    • แจ้งเตือนทันทีเรื่องการถอนเงินล้มเหลว
    • อธิบายเหตุผลที่ล้มเหลวอย่างชัดเจน
    • ให้คำแนะนำในการแก้ไข
    • ยืนยันว่าได้คืนเงินเข้ายอดคงเหลือแล้ว

ทางเลือกเมื่อไม่ได้รับ Webhook

ในกรณีที่ระบบของร้านค้าไม่ได้รับ Webhook แจ้งเตือน:

ทางเลือกที่ 1: ตรวจสอบสถานะการถอนเงินด้วยตนเอง

ร้านค้าสามารถตรวจสอบสถานะการถอนเงินได้:

  1. สร้างกลไก Polling:

    • หลังจากรอเวลาที่เหมาะสม (เช่น 30-60 นาที)
    • ส่ง request ไปยัง /withdraw/query endpoint
    • ระบุ merchant_order_id หรือ platform_order_id
  2. ประมวลผล Response:

    • รับสถานะการถอนปัจจุบัน
    • อัปเดตสถานะคำสั่งซื้อตามผลลัพธ์
    • ดำเนินการที่เหมาะสมตามสถานะ
  3. แนวทางปฏิบัติสำหรับ Polling:

    • อย่า poll บ่อยเกินไป (เคารพ rate limit)
    • ใช้ exponential backoff
    • กำหนดระยะเวลา polling สูงสุด
    • หยุด polling เมื่อได้รับสถานะสุดท้าย

ตัวอย่าง Query Request:

{
  "merchant_id": "AA12345678",
  "token": "testtokentesttokentesttokentesttokentesttoken",
  "time": 1656272222,
  "merchant_order_id": "WITHDRAW0123456789"
}

สำหรับรายละเอียด ดูเอกสาร ตรวจสอบคำสั่งถอนเงิน

ทางเลือกที่ 2: ส่งเรื่องให้ฝ่ายสนับสนุน

สำหรับสถานะ pending ที่ค้างนานโดยไม่ได้รับ Webhook:

  1. ลูกค้าติดต่อฝ่ายสนับสนุนของร้านค้า
  2. ฝ่ายสนับสนุนตรวจสอบสถานะผ่าน API
  3. แก้ไขด้วยตนเองหากจำเป็น
  4. ประสานงานกับทีมสนับสนุนหากต้องการ

สถานะการถอนเงิน

สถานะ: pending

สถานะ: success

สถานะ: failed

สาเหตุที่ล้มเหลวบ่อย

ข้อมูลบัญชีไม่ถูกต้อง

สาเหตุ:

การแก้ไข:

ยอดคงเหลือของร้านค้าไม่เพียงพอ

สาเหตุ:

การแก้ไข:

ปัญหาระบบธนาคาร

สาเหตุ:

การแก้ไข:

ถูกระงับเนื่องจากกฎระเบียบ

สาเหตุ:

การแก้ไข:

ข้อควรพิจารณาที่สำคัญ

การจัดการยอดคงเหลือ

การหักยอดทันที (แนะนำ):

เมื่อลูกค้าขอถอนเงิน ให้ดำเนินการทันที:

  1. หักจำนวนเงินจากยอดคงเหลือที่ใช้ได้
  2. ย้ายไปยังบัญชี "รอการถอน"
  3. ป้องกันลูกค้าจากการใช้เงินซ้ำ

เมื่อได้รับ Webhook:

เหตุผล:

ความน่าเชื่อถือของ Webhook

สร้าง Webhook Handler ที่มีความทนทาน:

  1. Idempotency:

    • ตรวจสอบว่าคำสั่งซื้อถูกดำเนินการแล้วหรือไม่
    • ป้องกันการดำเนินการซ้ำ
    • ใช้ database transaction
  2. ตอบกลับอย่างรวดเร็ว:

    • ตอบกลับ HTTP 200 ทันที
    • ประมวลผล business logic แบบ asynchronous
    • อย่าค้าง connection ไว้นาน
  3. การจัดการข้อผิดพลาด:

    • บันทึก log การรับ Webhook ทั้งหมด
    • จัดการ request ที่ผิดรูปแบบอย่างสง่างาม
    • สร้างกลไก retry สำหรับการประมวลผลที่ล้มเหลว
  4. ความปลอดภัย:

    • ตรวจสอบ Signature ของ Webhook
    • ตรวจสอบที่มาของ request
    • ใช้ HTTPS สำหรับ notify_url

ระยะเวลาดำเนินการที่คาดหวัง

การดำเนินการปกติ:

ปัจจัยที่ส่งผลต่อความเร็ว:

การสื่อสารกับลูกค้า

อัปเดตเชิงรุก:

คำแนะนำที่ชัดเจน:

แผนภาพลำดับขั้นตอน

ลูกค้า            เว็บไซต์ร้านค้า          ระบบหลังบ้านร้านค้า          Payment API
   |                     |                          |                         |
   |--[ขอถอนเงิน]------->|                          |                         |
   |                     |                          |                         |
   |                     |----[ตรวจสอบคำขอ]-------->|                         |
   |                     |                          |                         |
   |                     |                    [หักยอดคงเหลือ]                |
   |                     |                          |                         |
   |                     |                          |--[POST /withdraw]------>|
   |                     |                          |                         |
   |                     |                          |                    [สร้างคำสั่ง]
   |                     |                          |                    [สถานะ PENDING]
   |                     |                          |                         |
   |                     |                          |<--[Pending Response]---|
   |                     |                          |                         |
   |                     |<---[แสดงสถานะรอ]---------|                         |
   |                     |                          |                         |
   |<--[สถานะ Pending]---|                          |                         |
   |                     |                          |                         |
   |       [รอดำเนินการ...]                         |                         |
   |                     |                          |                    [ดำเนินการ]
   |                     |                          |                    [โอนเงินผ่านธนาคาร]
   |                     |                          |                         |
   |                     |                          |                   [สำเร็จ/ล้มเหลว]
   |                     |                          |                         |
   |                     |                          |<--[Webhook Callback]---|
   |                     |                          |                         |
   |                     |              [อัปเดตสถานะ / คืนเงินถ้าล้มเหลว]    |
   |                     |                          |                         |
   |                     |                          |---[HTTP 200 OK]-------->|
   |                     |                          |                         |
   |<--[สถานะสุดท้าย]----|<---[แจ้งลูกค้า]----------|                         |
   |                     |                          |                         |

เอกสารที่เกี่ยวข้อง