Endpoints
Endpoints
ระบบมี 2 endpoint สำหรับ Merchant
orgId และ merchantId จะได้รับจากผู้ให้บริการเมื่อสมัครใช้งาน ไม่ต้องสร้างเอง
สร้างคำขอรับเงิน (Pay-In)
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayInRequest/{merchantId}
สร้าง Payment Request แล้วได้รับ QR Code สำหรับให้ลูกค้า scan และโอนเงินเข้าบัญชีของ Merchant โดยตรง
Request Body
| Field | Type | Required | คำอธิบาย |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID จาก Merchant (ต้องไม่ซ้ำกัน) |
RefId2 |
string | ❌ | Reference เพิ่มเติม 2 |
RefId3 |
string | ❌ | Reference เพิ่มเติม 3 |
PayerName |
string | ✅ | ชื่อผู้จ่าย |
RequestedAmount |
number | ✅ | จำนวนเงิน (ต้องมากกว่า 0 และอยู่ใน range ที่ Merchant กำหนด) |
Currency |
string | ✅ | สกุลเงิน — ปัจจุบันรองรับเฉพาะ THB |
QrProvider |
string | ✅ | ธนาคารที่ออก QR — PP (PromptPay) หรือ SCB |
Description |
string | ❌ | คำอธิบายรายการ |
CustomerEmail |
string | ❌ | อีเมลของลูกค้า |
CustomerPhone |
string | ❌ | เบอร์โทรของลูกค้า |
Tags |
string | ❌ | Tag สำหรับจัดกลุ่มรายการ |
ตัวอย่าง Request
{
"RefId1": "ORDER-20260701-001",
"PayerName": "สมชาย ใจดี",
"RequestedAmount": 325,
"Currency": "THB",
"QrProvider": "PP",
"Description": "ชำระค่าสินค้า",
"RefId2": "CUST-12345"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"sessionId": "session-abc123",
"type": "PayIn",
"status": "Pending",
"requestedAmount": 325.00,
"generatedAmount": 325.52,
"currency": "THB",
"qrCode": "00020101021...",
"qrCodeImage": "data:image/png;base64,...",
"paymentUrl": "https://...",
"websocketPath": "/realtime/payment-tx",
"createdAt": "2026-07-01T10:00:00Z",
"expireAt": "2026-07-01T10:15:00Z",
"isQrAvailable": true,
"payInBankCode": "SCB",
"payInBankAccountNo": "xxx-xxxxx-x",
"payInBankAccountName": "ชื่อบริษัท",
"payInPromptPayId": null,
"slipUploadUrl": "/payin-slip-upload/org123/3fa85f64-5717-4562-b3fc-2c963f66afa6/a1b2c3d4-..."
}
}
Response Fields
| Field | คำอธิบาย |
|---|---|
id |
UUID ของ Payment Request — เก็บไว้สำหรับ reference |
status |
สถานะปัจจุบัน (ดู สถานะการชำระเงิน) |
requestedAmount |
จำนวนเงินที่ขอ |
generatedAmount |
จำนวนเงินที่ใช้จริง (อาจมีเศษสตางค์ random เพื่อ matching) |
isQrAvailable |
true หาก QR Code พร้อมให้ลูกค้า scan, false หากบัญชีปลายทางไม่รองรับ QR (เช่น ไม่ได้ผูกกับ PromptPay) — ดูรายละเอียดด้านล่าง |
qrCodeImage |
รูป QR Code เป็น Base64 — นำไปแสดงในแอปได้เลย (ว่างเปล่าหาก isQrAvailable เป็น false) |
payInBankCode |
รหัสธนาคารปลายทาง |
payInBankAccountNo |
เลขบัญชีปลายทาง |
payInBankAccountName |
ชื่อบัญชีปลายทาง |
payInPromptPayId |
หมายเลข PromptPay ปลายทาง (ถ้ามี) |
sessionId |
ใช้เชื่อมต่อ WebSocket เพื่อรับสถานะแบบ real-time |
websocketPath |
path สำหรับ WebSocket (/realtime/payment-tx) |
expireAt |
QR Code หมดอายุเมื่อไหร่ |
slipUploadUrl |
Relative path สำหรับหน้าอัปโหลดสลิป — ไม่มี domain นำหน้า ต้องนำไปต่อกับ https://merchant.please-payment.com (ดูคำอธิบายด้านล่าง) เพื่อสร้าง URL เต็ม แล้วส่งให้ลูกค้าเปิดหน้าอัปโหลดสลิปได้โดยไม่ต้อง login |
สำคัญ — ต้อง concat กับโดเมนไหน:
slipUploadUrlเป็น relative path เท่านั้น ต้องนำไปต่อกับโดเมนhttps://merchant.please-payment.comเอง เช่น หากslipUploadUrlคือ/payin-slip-upload/org123/xxx/yyyก็ให้สร้าง URL เต็มเป็นhttps://merchant.please-payment.com/payin-slip-upload/org123/xxx/yyy
การแสดงผล QR และข้อมูลบัญชี
ควรตรวจสอบ isQrAvailable ก่อนแสดงผลเสมอ:
| สถานการณ์ | วิธีแสดงผล |
|---|---|
isQrAvailable = true |
แสดง QR Code จาก qrCodeImage ให้ลูกค้า scan ตามปกติ |
isQrAvailable = false |
ไม่มี QR Code — แสดงข้อมูลบัญชี (payInBankCode, payInBankAccountNo, payInBankAccountName, payInPromptPayId) เพื่อให้ลูกค้ากรอกข้อมูลโอนเงินเอง |
หมายเหตุ: แนะนำให้แสดงข้อมูลบัญชี (
payInBankCode,payInBankAccountNo,payInBankAccountName,payInPromptPayId) ควบคู่กับ QR Code เสมอ — ลูกค้าบางรายอาจต้องการโอนด้วยตัวเองแม้มี QR
แนะนำ: นำ
slipUploadUrlไปทำเป็น QR Code แสดงในหน้าชำระเงินของคุณ — ลูกค้าสแกน QR ด้วยกล้องมือถือแล้วเปิดหน้าอัปโหลดสลิปได้เลย ไม่ต้องพิมพ์ URL เอง ใช้ได้ทั้ง Pay-In ปกติ และ Pay-In P2P
หน้าอัปโหลดสลิป
เมื่อลูกค้าเปิด Slip Upload URL ลูกค้าจะเจอหน้าอัปโหลดสลิปสำหรับ Payment Request นั้นๆ ซึ่งมีฟีเจอร์ดังนี้:
- อัปโหลดรูปสลิป — เลือกรูปจากกล้องหรือ Gallery ของมือถือ
- เลขอ้างอิงสลิป — กรอก 4 หลักแรกและ 4 หลักสุดท้ายของเลขอ้างอิงสลิป (alphanumeric) เพื่อ matching และตรวจจับสลิปซ้ำ
- หมายเหตุ — ช่องเสริมสำหรับข้อความเพิ่มเติม
- ตรวจสอบสลิปซ้ำ — ระบบแจ้งเตือนอัตโนมัติถ้าพบสลิปที่มีเลขอ้างอิงเดียวกันในระบบแล้ว
ลูกค้าไม่ต้อง login เพื่อใช้หน้านี้ — URL มี token ฝังอยู่แล้ว และหมดอายุใน 24 ชั่วโมง
แม้ HTTP status code จะเป็น
200แต่ต้องตรวจสอบstatusใน response body ด้วย — ถ้า"OK"คือสำเร็จ ถ้าค่าอื่นคือมีข้อผิดพลาด (ดู การจัดการ Error)
สร้างคำขอรับเงินแบบ P2P (Pay-In P2P)
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayInRequestP2P/{merchantId}
สร้าง Pay-In Request แบบ Peer-to-Peer (P2P) — ระบบจะจับคู่กับ Pay-Out Request ที่รอดำเนินการอยู่โดยอัตโนมัติ แล้วให้ลูกค้าโอนเงินตรงไปยังบัญชีของผู้รับ (แทนที่จะโอนผ่าน QR Code ของระบบ)
P2P คืออะไร? แทนที่เงินจะเข้าบัญชีของ Merchant ก่อน แล้วค่อยโอนออก — P2P ให้ผู้ส่งโอนตรงถึงผู้รับเลย ระบบทำหน้าที่จับคู่และยืนยัน
Request Body
| Field | Type | Required | คำอธิบาย |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID จาก Merchant (ต้องไม่ซ้ำกัน) |
RefId2 |
string | ❌ | Reference เพิ่มเติม 2 |
RefId3 |
string | ❌ | Reference เพิ่มเติม 3 |
PayerName |
string | ✅ | ชื่อผู้จ่าย |
RequestedAmount |
number | ✅ | จำนวนเงิน (ต้องมากกว่า 0 และอยู่ใน range ที่ Merchant กำหนด) |
Currency |
string | ✅ | สกุลเงิน — ปัจจุบันรองรับเฉพาะ THB |
QrProvider |
string | ✅ | PP หรือ SCB (ระบบใช้สำหรับ internal matching) |
Description |
string | ❌ | คำอธิบายรายการ |
ตัวอย่าง Request
{
"RefId1": "P2P-ORDER-20260701-001",
"PayerName": "สมชาย ใจดี",
"RequestedAmount": 1000,
"Currency": "THB",
"QrProvider": "PP"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "PayIn",
"status": "Pending",
"requestedAmount": 1000.00,
"generatedAmount": 1000.00,
"currency": "THB",
"qrCode": null,
"qrCodeImage": "",
"isQrAvailable": false,
"payInBankCode": "KBANK",
"payInBankAccountNo": "012-3-45678-9",
"payInBankAccountName": "ชื่อผู้รับปลายทาง",
"payInPromptPayId": "0812345678",
"slipUploadUrl": "/payin-slip-upload/org123/3fa85f64-5717-4562-b3fc-2c963f66afa6/a1b2c3d4-..."
}
}
ความแตกต่างจาก Pay-In ปกติ
| Pay-In ปกติ | Pay-In P2P | |
|---|---|---|
isQrAvailable |
true (ส่วนใหญ่) |
false (ส่วนใหญ่) — บัญชี P2P มักไม่ผูกกับ PromptPay |
qrCodeImage |
รูป QR Code | ว่างเปล่า ("") เมื่อ isQrAvailable = false |
payInBankAccountName |
บัญชี Merchant | บัญชีของผู้รับปลายทาง (จาก Pay-Out Request ที่จับคู่) |
| การโอนเงิน | สแกน QR Code | โอนตรงไปยังบัญชีที่ระบุใน response (กรอกข้อมูลบัญชีเอง) |
slipUploadUrl |
✅ | ✅ (สำคัญมาก — ลูกค้าต้องอัปโหลดสลิปเป็นหลักฐาน) |
สำคัญ: สำหรับ P2P —
isQrAvailableมักเป็นfalseเพราะบัญชีปลายทางอาจไม่ผูกกับ PromptPay ในกรณีนี้ ต้องแสดงข้อมูลบัญชี (payInBankCode,payInBankAccountNo,payInBankAccountName,payInPromptPayId) เพื่อให้ลูกค้ากรอกโอนเงินเองด้วยตัวเอง พร้อมทั้งแสดงslipUploadUrlเพื่อให้อัปโหลดสลิปหลักฐานการโอน
สำคัญ — ต้อง concat กับโดเมนไหน:
slipUploadUrlเป็น relative path เช่นเดียวกับ Pay-In ปกติ ต้องนำไปต่อกับhttps://merchant.please-payment.comเอง เช่นhttps://merchant.please-payment.com/payin-slip-upload/org123/xxx/yyy(ดูคำอธิบายเต็มในหัวข้อ Response Fields ด้านบน)
แนะนำ: นำ
slipUploadUrlไปทำเป็น QR Code แสดงควบคู่กับข้อมูลบัญชีปลายทาง — ลูกค้าโอนเงินแล้วสแกน QR เปิดหน้าอัปโหลดสลิปได้เลยโดยไม่ต้องพิมพ์ URL เอง (ดูตัวอย่างหน้าอัปโหลดสลิปด้านบน)
Error
ERROR_NO_P2P_ACCOUNT_MATCH: หากไม่มี Pay-Out Request ที่รอดำเนินการอยู่ในระบบ จะได้รับ error นี้ — แปลว่าในขณะนั้นไม่มีรายการที่สามารถจับคู่ได้
สร้างคำขอโอนเงินออก (Pay-Out)
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitPayOutRequest/{merchantId}
สร้างคำขอโอนเงินออกไปยังบัญชีปลายทาง
Request Body
| Field | Type | Required | คำอธิบาย |
|---|---|---|---|
RefId1 |
string | ✅ | Reference ID จาก Merchant (ต้องไม่ซ้ำกัน) |
RefId2 |
string | ❌ | Reference เพิ่มเติม 2 |
RefId3 |
string | ❌ | Reference เพิ่มเติม 3 |
RequestedAmount |
number | ✅ | จำนวนเงิน (ต้องมากกว่า 0) |
QrProvider |
string | ✅ | ต้องเป็น PP (PromptPay เท่านั้น สำหรับ Pay-Out) |
BankCode |
string | ✅ | รหัสธนาคารปลายทาง เช่น SCB, KBANK, BAY — ดูรหัสธนาคารที่รองรับทั้งหมด |
BankAccountNo |
string | ✅ | เลขบัญชีปลายทาง |
BankAccountName |
string | ✅ | ชื่อบัญชีปลายทาง |
PromptPayId |
string | ❌ | หมายเลข PromptPay ปลายทาง |
AccountType |
string | ❌ | ประเภทบัญชี: Native หรือ PromptPay |
ข้อมูลบัญชีปลายทาง: ต้องส่ง
BankCode+BankAccountNo+BankAccountNameเข้ามาเสมอทุกครั้ง (ดูรหัสธนาคารที่รองรับ) แม้จะโอนผ่าน PromptPay ก็ตาม — ถ้าทราบหมายเลข PromptPay ของปลายทางด้วย สามารถส่งPromptPayId+AccountTypeเพิ่มเติมได้ หรือจะส่งPayinBankAccountId(ID จากระบบ) แทนทั้งหมดนี้ก็ได้เช่นกัน
แนะนำ: หากทราบหมายเลข PromptPay ของบัญชีปลายทาง แนะนำให้ส่ง
PromptPayIdมาด้วย เนื่องจากการโอนผ่าน PromptPay จะช่วยให้ระบบประมวลผลได้เร็วขึ้น และผู้รับได้รับเงินได้รวดเร็วยิ่งขึ้น
ตัวอย่าง Request (โอนผ่านบัญชีธนาคาร)
{
"RefId1": "PAYOUT-20260701-001",
"RequestedAmount": 500,
"QrProvider": "PP",
"BankCode": "KBANK",
"BankAccountNo": "0123456789",
"BankAccountName": "สมชาย ใจดี",
"AccountType": "Native"
}
ตัวอย่าง Request (โอนผ่าน PromptPay)
{
"RefId1": "PAYOUT-20260701-002",
"RequestedAmount": 200,
"QrProvider": "PP",
"PromptPayId": "0812345678",
"AccountType": "PromptPay"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "7bc95f12-3a21-4f89-c4ed-1d852a77bfc8",
"type": "PayOut",
"status": "Pending",
"requestedAmount": 500.00,
"currency": "THB",
"createdAt": "2026-07-01T10:05:00Z"
}
}
สร้างคำขอถอนเงิน (Withdrawal)
POST https://api.please-payment.com/api/PaymentRequest/org/{orgId}/action/SubmitWithdrawalRequest/{merchantId}
ใช้ endpoint นี้เมื่อ Merchant เองต้องการถอนเงินออกไปยังบัญชีของตัวเอง ต่างจาก Pay-Out ทั่วไปที่เป็นการโอนเงินออกไปให้ ลูกค้า ของ Merchant — ภายในระบบจะสร้างคำขอชนิดเดียวกับ Pay-Out ทุกประการ เพียงแต่ติด flag ว่าเป็น withdrawal เพื่อให้แยกออกจาก Pay-Out ปกติในรายงานต่าง ๆ
Request body, วิธีคิดค่าธรรมเนียม, รูปแบบ Response และ Webhook เหมือนกับ สร้างคำขอโอนเงินออก (Pay-Out) ทุกอย่าง 100% — ต่างกันแค่ endpoint path (
SubmitWithdrawalRequestแทนSubmitPayOutRequest) เท่านั้น ส่วนที่อธิบายไว้ด้านบนสำหรับ Pay-Out ใช้กับ endpoint นี้ได้เหมือนกันทุกประการ
Request Body
เหมือนกับ สร้างคำขอโอนเงินออก (Pay-Out) — RefId1, RefId2, RefId3, RequestedAmount, QrProvider และข้อมูลบัญชีปลายทาง (BankCode+BankAccountNo+BankAccountName, หรือ PromptPayId+AccountType, หรือ PayinBankAccountId)
ตัวอย่าง Request
{
"RefId1": "WITHDRAW-20260701-001",
"RequestedAmount": 500,
"QrProvider": "PP",
"BankCode": "KBANK",
"BankAccountNo": "0123456789",
"BankAccountName": "สมชาย ใจดี",
"AccountType": "Native"
}
Response
{
"status": "OK",
"description": "Success",
"paymentResponse": {
"id": "7bc95f12-3a21-4f89-c4ed-1d852a77bfc8",
"type": "PayOut",
"status": "Pending",
"requestedAmount": 500.00,
"currency": "THB",
"createdAt": "2026-07-01T10:05:00Z"
}
}
Webhook: ไม่มี event ใหม่ — คำขอถอนเงินยังคงยิง event
PaymentOut.Success/PaymentOut.Rejectedเหมือนที่อธิบายไว้ใน Webhooks พร้อม payload fields แบบเดียวกันทุกประการ