Skip to content

Live P2P API — ขอบเขตที่พัฒนาแล้ว ​

สถานะ: implementation 0092 — รอตรวจและ deploy

หน้านี้อธิบายโค้ดที่พัฒนาแล้ว ไม่ได้ยืนยันว่าเปิดให้ใช้บน production ของคุณแล้ว ให้ผู้ให้บริการยืนยันรุ่นและการตั้งค่า Merchant ก่อนเชื่อมต่อเงินจริง เอกสารส่วนที่ติดป้าย Target contract อธิบายขอบเขตที่กว้างกว่าและไม่ได้เปิดครบในรุ่นนี้

ใช้ https://api.<โดเมน White Label> กับ Live key และ HMAC เดิม (PG-Version: 2026-08-01) environment มาจาก hostname และ credential ไม่รับ field หรือ header สำหรับเปลี่ยนเป็น Live/Test

Endpoint ในขอบเขตนี้ ​

Method และ pathสิทธิ์ของ keyผลลัพธ์
POST /v1/pay/withdrawalswithdrawals:writeสร้าง P2P payout และกันยอด รอการอนุมัติสองคน
GET /v1/pay/withdrawals/{id}withdrawals:readสถานะและยอดของรายการถอนเต็มใบ
GET /v1/pay/withdrawalswithdrawals:readรายการถอนของ Merchant นี้
GET /v1/pay/depositsdeposits:readสรุปรายการฝาก ไม่มีบัญชีรับโอน QR หรือคำสั่งชำระเงิน
GET /v1/pay/balancewallet:readยอด available, pending clearing และ reserved
GET /v1/pay/eventswallet:readอ่าน business event ต่อด้วย sequence

เส้นทางสร้าง/อ่านรายการฝากเดิมยังใช้ flow เดิม รุ่นนี้ไม่ได้เพิ่ม Customer API, API ลงทะเบียน beneficiary, inline beneficiary, Merchant quote หรือคำสั่งยกเลิกรายการถอน

เตรียม key และบัญชีปลายทาง ​

Live key ใหม่เลือกได้เฉพาะ deposits:read, deposits:write, withdrawals:read, withdrawals:write, wallet:read ตามงานที่ต้องใช้ key เดิมไม่ได้รับสิทธิ์เพิ่มอัตโนมัติ และ rotate คงสิทธิ์ที่ key เดิมได้รับไว้ sandbox:write ใช้ได้เฉพาะ Test key ดู Sandbox ที่รองรับ

ให้ผู้ดูแลจัดเตรียม beneficiary ที่มีอยู่แล้ว ต้องเป็นของ Merchant และ Live mode เดียวกัน มีสถานะ verified รับรายการใหม่ได้ และผ่านเงื่อนไขบัญชี/ธนาคารปัจจุบัน ใช้ ID รูปแบบ ben_ ตามด้วย UUID ที่ตัดขีดออกเป็นเลขฐานสิบหกพิมพ์เล็ก 32 ตัว เช่น ben_92000000000040008000000000000423 ห้ามส่ง raw UUID, เลขบัญชี หรือ object beneficiary อ่าน บัญชีปลายทาง และ สร้างรายการถอน

สร้างรายการถอน ​

ตัวอย่าง body สำหรับคำขอที่เซ็นแล้ว:

json
{
  "amount_minor": 100000,
  "currency": "THB",
  "merchant_reference": "WD-20261017-0001",
  "end_user_ref": "customer-001",
  "beneficiary_id": "ben_92000000000040008000000000000423",
  "metadata": { "order": "WD-20261017-0001" }
}
  • amount_minor เป็นจำนวนเต็มบวกหน่วยสตางค์ ไม่เกิน 9007199254740991 และต้องไม่น้อยกว่ายอดขั้นต่ำตามนโยบาย P2P ปัจจุบัน จำนวนในตัวอย่างยังต้องผ่านนโยบายนั้น
  • merchant_reference และ end_user_ref ยาว 1–64 ตัวอักษร ไม่มี control characters reference ไม่ซ้ำต่อ Merchant ส่วน end_user_ref เป็น reference ของคุณ ไม่ใช่การสร้าง Customer
  • metadata มีไม่เกิน 20 keys ชื่อ key ยาว 1–40 ตัวอักษร ค่าเป็น string ยาวไม่เกิน 500 ตัวอักษร client รับเฉพาะ device_fingerprint, ip, user_agent ที่ผ่านการตรวจรูปแบบ ข้อมูล client นี้ไม่ถูกเก็บใน payment metadata หรือ response
  • ใช้ Idempotency-Key 8–200 ตัวอักษรเดิมและ body เดิมเมื่อ retry ทุก attempt ใช้ nonce ใหม่และเซ็นใหม่ exact replay ตอบ receipt เดิมพร้อม Idempotent-Replay: true

201 เริ่มที่ status: "pending_approval", requires_approval: true, version: 0 และกันยอด total_locked_minor = amount_total_minor + fee_total_minor ทันที ต้องผ่านการอนุมัติพนักงานสองคนตาม flow เดิมก่อนเข้า matching pool ยังไม่ใช่การโอนสำเร็จ และไม่ใช่ flow ถอนค่าคอมมิชชันของ Agent

ค่าธรรมเนียมมาจากราคาขาย Payout ของ Merchant โดยตรึง matrix ทั้งสี่ source ตอนสร้าง ฐานค่าธรรมเนียม P2P รุ่นนี้ใช้ wl_pool อ่าน fee_total_minor และ total_locked_minor จาก response ไม่คำนวณว่าเงินที่กันไว้เท่ากับยอดถอนอย่างเดียว 402 insufficient_balance หมายถึงยอด available ไม่พอสำหรับยอดถอนรวม fee และไม่สร้างรายการ บัญชีปลายทางไม่พร้อมได้ 409 beneficiary_not_verified; ยอดต่ำกว่านโยบายได้ 422 amount_below_p2p_minimum

อ่านรายการและยอด ​

ID รายการถอนเป็น wdr_ + UUID hex พิมพ์เล็ก 32 ตัว ใช้ GET /v1/pay/withdrawals/{id} เป็นสถานะเต็มปัจจุบัน สถานะสาธารณะคือ pending_approval, open, partially_filled, settled, expired, canceled, rejected

ยอด principal แยกเป็นสี่ส่วน โดย A = amount_total_minor: A = filled_minor + reserved_minor + remaining_minor + reversed_minorreserved_minor คือยอดที่จัดสรรให้ผู้ฝากแล้วแต่ยังไม่ยืนยันการโอน จึงอาจได้ remaining_minor: 0, reserved_minor: A, filled_minor: 0 ในรายการ openremaining เป็นศูนย์ไม่ได้แปลว่าจ่ายแล้ว ตรวจสถานะล่าสุดและยอดที่โอนสำเร็จ เมื่อจ่ายครบโดยไม่มียอดย้อนกลับ จะเป็น settled, filled_minor = A และ reserved_minor = remaining_minor = reversed_minor = 0

ทั้งรายการฝากและถอนรับ limit 1–100 (default 20), status, updated_after แบบ UTC เช่น 2026-10-17T00:00:00Z และ cursor จาก next_cursor เท่านั้น cursor มีรูปแบบ cur_<epochmicro>_<uuidhex> ให้ส่งกลับตามเดิม เรียง created_at ใหม่ไปเก่าและใช้ ID ตัดสินเมื่อเวลาเท่ากัน เปลี่ยนตัวกรองให้เริ่มหน้าแรกใหม่; เมื่อ has_more: false จะได้ next_cursor: null นี่คือการแบ่งหน้าข้อมูลปัจจุบัน ไม่ใช่ snapshot ที่ตรึงสถานะตลอดการอ่าน

Balance ตอบ field เหล่านี้ ไม่มีการดึง pending clearing มารวมเป็นยอดถอนได้:

json
{
  "livemode": true,
  "available_minor": 250000,
  "pending_clearing_minor": 10000,
  "reserved_minor": 5000,
  "currency": "THB",
  "as_of": "2026-10-17T00:00:00.000Z"
}

อ่าน event โดยไม่เปลี่ยนสัญญา webhook ​

เรียก GET /v1/pay/events?since_sequence=0&limit=20 แล้วบันทึก next_sequence เป็น decimal string เพื่อเรียกต่อ sequence ของแต่ละ event เป็น string เช่นกัน ลำดับเพิ่มต่อ Merchant เมื่อมีข้อมูลหน้าถัดไปให้ส่ง next_sequence เดิมกลับใน since_sequence

รุ่นนี้ส่ง business snapshots ของ withdrawal.created, withdrawal.partial_fill, withdrawal.terminal และ deposit.settled เท่านั้น data.object เป็น snapshot แบบเดิมของ event นั้น ไม่ใช่ Withdrawal object เต็มใบ ถ้าต้องแสดงสถานะ/ยอดล่าสุดให้ GET รายการถอน เมื่อ snapshot ใช้ withdrawal_id แบบ UUID ให้ประกอบ public ID เป็น wdr_ ตามด้วย UUID ที่ตัดขีดออก

ซองข้อมูล webhook ที่เซ็นยังคง 7 field เดิม: id, object, type, api_version, livemode, created_at, datasequence และ account เป็น metadata เพิ่มสำหรับ response ของการ polling เท่านั้น ตรวจ Ed25519 จาก raw webhook bytes ที่ได้รับตาม วิธีตรวจลายเซ็น ไม่ใช้ JSON ที่ประกอบใหม่จากผล polling ไปตรวจแทน signed webhook body

ขอบเขตนี้ยังต้องผ่านการตรวจ SQL, การ deploy และการตั้งค่า host/key/policy ของผู้ให้บริการ ก่อนเปิดใช้งานเงินจริง

เอกสารชุดนี้อิงสัญญา API เวอร์ชัน 2026-08-01