ข้ามไปยังเนื้อหา

Pay-ins (รับเงิน)

pay-in คือรายการเรียกเก็บเงินจาก payer หนึ่งคน คุณสร้างรายการ ระบบคืนช่องทางจ่าย (QR หรือบัญชีปลายทาง) ผู้จ่ายโอนเงิน แล้วระบบจับคู่การโอนและแจ้งผลผ่าน webhook

MethodPathใช้ทำอะไร
POST/v1/payinsสร้าง pay-in
GET/v1/payins/{id}ดู pay-in พร้อม payTo (ใส่ ?include=paymentImage เพื่อรับรูปด้วย)
GET/v1/payinsค้นหารายการ
POST/v1/payins/{id}/cancelยกเลิกรายการที่ pending หรือ expired
POST/v1/payins/{id}/slipอัปโหลดสลิปของผู้จ่าย (ดูตรวจสลิป)
POST /v1/payins
ฟิลด์จำเป็นคำอธิบาย
payerส่ง payer หรือ payerId อย่างใดอย่างหนึ่งบัญชีธนาคารของผู้จ่าย: bankCode, accountNumber, accountName และ accountNameEn (ไม่บังคับ) ดูส่ง payer แบบ inline
payerIdส่ง payer หรือ payerId อย่างใดอย่างหนึ่งpayer_... ของผู้จ่ายที่มีอยู่แล้ว (Payers)
amountใช่สตริงทศนิยม เช่น "150.00" ต้องอยู่ในช่วง payinMinimum-payinMaximum ของบัญชีคุณ
currencyใช่THB, USD, USDT หรือ LAK
methodไม่auto (ค่าเริ่มต้น), promptpay_qr, bank_transfer, crypto, lao_qr
referenceไม่เลขคำสั่งซื้อของคุณ ไม่เกิน 128 ตัว ส่งกลับใน response และ webhook และใช้ค้นหาได้
webhookUrlใช่URL http(s) ที่จะรับ webhook ไม่เกิน 2048 ตัว
returnUrlไม่URL ที่หน้าชำระเงินจะพาผู้จ่ายกลับไปหลังจ่ายเสร็จ
{
"payer": {
"bankCode": "SCB",
"accountNumber": "1234567890",
"accountName": "สมชาย สบายดี"
},
"amount": "150.00",
"currency": "THB",
"reference": "order-10001",
"webhookUrl": "https://shop.example.com/webhooks/payments",
"returnUrl": "https://shop.example.com/orders/10001"
}

ถ้าคุณเก็บ ID ของ payer ไว้แล้ว ส่ง "payerId": "payer_7c0a4b8e2f3d4a1b9c8d7e6f5a4b3c2d" แทน payer ได้

query parameter: include=paymentImage เพิ่มรูปสำเร็จรูปใน response (ดูด้านล่าง)

สิ่งที่ควรรู้

  • ยอดที่ต้องโอนคือ amount ใน response ระบบอาจเพิ่มเศษสตางค์เพื่อใช้จับคู่ ทำให้ amount (เช่น 150.37) ต่างจาก requestedAmount (150.00) ให้แสดง amount แก่ผู้จ่าย
  • ช่องทางจ่ายเลือกอัตโนมัติ สำหรับเงินบาท คำขอแบบ promptpay_qr หรือ bank_transfer ระบบจะเลือกช่องทางที่เหมาะให้ ดูช่องทางที่ใช้จริงได้จาก method ใน response
  • payer หนึ่งคนมี pay-in ที่รอจ่ายได้ครั้งละหนึ่งรายการ ถ้ายังมีรายการ pending อยู่ จะได้ 409 pending_payin_exists ให้รอรายการเดิมจบ หรือยกเลิกก่อน
  • สำหรับ crypto ข้อมูลปลายทางใน payTo จะเป็น walletAddress และ network
  • ส่ง header Idempotency-Key เพื่อให้การส่งซ้ำหลัง timeout ไม่สร้าง pay-in ซ้ำ ดูส่งคำขอสร้างรายการซ้ำอย่างปลอดภัย

ส่ง payerId หรือ payer อย่างใดอย่างหนึ่งเท่านั้น ถ้าส่งทั้งคู่จะได้ 400 parameters_exclusive ถ้าไม่ส่งเลยจะได้ 400 parameter_missing

  • บัญชีที่มีอยู่แล้ว: ใช้ payer เดิม ถ้าคุณมี payer ที่ bankCode และ accountNumber ตรงกันอยู่แล้ว pay-in จะใช้ payer คนนั้น และไม่เปลี่ยนชื่อที่บันทึกไว้ เพราะระบบใช้ชื่อนี้จับคู่การโอนเข้า ถ้าชื่อที่ส่งมาต่างจากเดิม (ไม่นับตัวพิมพ์เล็กใหญ่และช่องว่างที่เกิน) ระบบยังสร้าง pay-in ให้ และใส่ payer_name_differs ไว้ใน warnings ของ response ถ้าต้องการเปลี่ยนชื่อ ใช้ PATCH /v1/payers/{id}
  • บัญชีใหม่: สร้าง payer ให้ ระบบสร้าง payer สถานะ active โดยตรวจสอบเหมือน POST /v1/payers ทุกอย่าง (รูปแบบฟิลด์ และบัญชีที่ถูกระงับ) ข้อผิดพลาดจะชี้ไปที่ฟิลด์ย่อย เช่น param: "payer.accountNumber" ถ้ารหัสธนาคารไม่ถูกต้องจะได้ 422 bank_not_found พร้อม param: "payer.bankCode" คำขอที่เข้ามาพร้อมกันด้วยบัญชีเดียวกันจะสร้าง payer เพียงคนเดียว
  • payer ที่สร้างใหม่จะยังอยู่แม้ pay-in จะถูกปฏิเสธในขั้นต่อไป (เช่น amount_below_minimum) เมื่อส่งใหม่ระบบจะใช้ payer คนเดิม
  • payer ที่ถูกปิดหรือถูกระงับจะได้ข้อผิดพลาดเดียวกับการใช้ payerId (payer_inactive, payer_blocked) โดย param เป็น "payer"
  • response มี payerId และ payer เก็บ ID ไว้ถ้าต้องการใช้ payerId ครั้งต่อไป
{
"data": { "object": "payin", "id": "pin_...", "payerId": "payer_7c0a4b8e2f3d4a1b9c8d7e6f5a4b3c2d", "...": "..." },
"warnings": [
{
"code": "payer_name_differs",
"message": "An existing payer with this bank account was used. Its stored account name differs from the one sent and was kept; it is used for payment matching.",
"param": "payer.accountName"
}
],
"requestId": "req_..."
}

warnings มีเฉพาะเมื่อมีคำเตือนเท่านั้น

payTo.qrPayload คือข้อความที่อยู่ใน QR code สำหรับชำระเงิน นำไปสร้าง QR code เองด้วยไลบรารี QR ใดก็ได้

methodqrPayload
promptpay_qrpayload แบบ EMVCo/PromptPay ซึ่งมี amount อยู่แล้ว
lao_qrpayload ของ Lao QR
bank_transfer, cryptonull (ให้แสดงบัญชีหรือ wallet จาก payTo)

ระบบไม่ส่ง paymentImage (รูป PNG สำเร็จรูปของ QR code หรือบัตรข้อมูลการโอน) มาโดยอัตโนมัติ ถ้าต้องการ ให้ใส่ ?include=paymentImage กับ POST /v1/payins หรือ GET /v1/payins/{id} ค่า include ใส่ได้หลายค่าคั่นด้วย , และค่าที่ระบบไม่รู้จักจะถูกข้ามไป query string เป็นส่วนหนึ่งของลายเซ็น จึงต้องเซ็น /v1/payins?include=paymentImage ทั้งหมด

response ของการสร้างและการดูรายการ (GET /v1/payins/{id}) มี payTo ด้วย และมี paymentImage เมื่อขอด้วย ?include=paymentImage ส่วนผลการค้นหาและ webhook ไม่มีทั้งสองฟิลด์นี้

{
"object": "payin",
"id": "pin_3f2b1c0d9e8f4a7b8c6d5e4f3a2b1c0d",
"reference": "order-10001",
"payerId": "payer_7c0a4b8e2f3d4a1b9c8d7e6f5a4b3c2d",
"payer": {
"object": "payer",
"id": "payer_7c0a4b8e2f3d4a1b9c8d7e6f5a4b3c2d",
"bankCode": "SCB",
"bankName": "Siam Commercial Bank",
"accountNumber": "1234567890",
"accountName": "สมชาย สบายดี",
"accountNameEn": "Somchai Sabuydee",
"status": "active",
"referralCode": null,
"createdAt": "2026-01-01T00:00:00.000Z"
},
"requestedAmount": "150.00",
"amount": "150.37",
"fee": "2.25",
"currency": "THB",
"method": "promptpay_qr",
"status": "pending",
"failureReason": null,
"webhookUrl": "https://shop.example.com/webhooks/payments",
"returnUrl": "https://shop.example.com/orders/10001",
"checkoutUrl": "https://pay.example.com/3f2b1c0d-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
"payerAccount": {
"bankCode": "SCB",
"accountNumber": "1234567890",
"accountName": "สมชาย สบายดี"
},
"payTo": {
"bankCode": "KBANK",
"bankName": "Kasikorn Bank",
"accountNumber": "0987654321",
"accountName": "Example Co., Ltd.",
"promptpayId": "0812345678",
"qrPayload": "00020101021229370016A000000677010111011300668123456785802TH53037645406150.3763046572"
},
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
ฟิลด์คำอธิบาย
requestedAmountยอดที่คุณขอ
amountยอดที่ผู้จ่ายต้องโอน (รวมเศษสตางค์ที่ระบบเพิ่ม)
feeค่าธรรมเนียมรวมของรายการ
methodช่องทางที่ใช้จริง
failureReasonข้อความสั้นๆ เมื่อรายการไม่สำเร็จ เช่น หมดเวลา หรือถูกยกเลิก เป็น null ในกรณีอื่น
checkoutUrlหน้าชำระเงินสำเร็จรูป อาจเป็น null ถ้าบริการนี้ไม่ได้เปิดไว้ ให้แสดง payTo (หรือ QR code ที่สร้างจาก payTo.qrPayload) เองแทน
payerAccountบัญชีของผู้จ่ายที่ใช้กับรายการนี้
payToบัญชีหรือ wallet ปลายทางที่ผู้จ่ายต้องโอนเข้า และ qrPayload
payTo.qrPayloadข้อความใน QR code สำหรับ promptpay_qr / lao_qr กรณีอื่นเป็น null
paymentImageมีเฉพาะเมื่อใส่ ?include=paymentImage: รูป PNG แบบ data URI (QR code หรือบัตรข้อมูลการโอน) ใส่ใน <img> ได้ทันที

ส่วนการคิดยอดให้ลูกค้าของคุณจาก requestedAmount หรือ amount ให้เป็นไปตามสัญญาที่ตกลงกับทีมงาน

สถานะความหมายสิ้นสุดหรือยัง
pendingสร้างแล้ว รอผู้จ่ายโอนยัง
processingกำลังดำเนินการยัง
succeededจับคู่การโอนได้แล้ว (จาก statement ธนาคาร สลิป หรือยืนยันโดยเจ้าหน้าที่)สิ้นสุด
expiredผู้จ่ายไม่โอนภายในเวลาที่กำหนดสิ้นสุด (ยังยกเลิกได้)
canceledถูกยกเลิกโดยคุณหรือโดยระบบสิ้นสุด
rejectedถูกปฏิเสธสิ้นสุด
failedดำเนินการไม่สำเร็จ ดู failureReasonสิ้นสุด

อัปเดตคำสั่งซื้อจาก webhook เป็นหลัก และใช้ GET ตรวจซ้ำเมื่อไม่แน่ใจ ดู Webhooks

GET /v1/payins?status=pending,processing&createdFrom=2026-01-01T00:00:00Z&limit=50
พารามิเตอร์คำอธิบาย
statusสถานะเดียวหรือหลายสถานะคั่นด้วย ,
referenceตรงกับ reference ทุกตัวอักษร
payerIdเฉพาะรายการของ payer คนนี้
createdFrom, createdToช่วงเวลาที่สร้าง ISO-8601 รวมขอบ
limit, cursorการแบ่งหน้า ดูภาพรวม
POST /v1/payins/{id}/cancel

ไม่มี body (hash สตริงว่างตอนเซ็น) ยกเลิกได้เฉพาะรายการที่ pending หรือ expired คืน object ของ pay-in ที่มีสถานะ canceled การยกเลิกผ่าน API ไม่ส่ง webhook เพราะคุณได้ผลจาก response แล้ว

HTTPcodeความหมายและสิ่งที่ควรทำ
400parameter_missing, parameter_invalidฟิลด์ขาดหรือรูปแบบผิด (รวมถึงไม่ส่งทั้ง payerId และ payer) ดู error.param
400parameters_exclusiveส่งทั้ง payerId และ payer มา ให้ส่งอย่างใดอย่างหนึ่ง
400unsupported_currency, unsupported_methodสกุลเงินหรือช่องทางที่ไม่รองรับ
400invalid_webhook_url, invalid_return_urlURL ไม่ใช่ http(s) หรือรูปแบบผิด
403payins_disabledบัญชีของคุณปิดการรับเงินอยู่ ติดต่อซัพพอร์ต
404payer_not_foundpayerId ไม่มีอยู่หรือไม่ใช่ของบัญชีคุณ
422bank_not_foundpayer.bankCode ไม่ใช่รหัสจาก GET /v1/banks
404resource_not_foundID ของ pay-in ไม่ถูกต้อง
409pending_payin_existspayer มี pay-in ที่รอจ่ายอยู่แล้ว
409payin_not_cancelableสถานะปัจจุบันยกเลิกไม่ได้
422amount_below_minimum, amount_above_maximumยอดนอกช่วงที่บัญชีกำหนด ข้อความระบุค่าขีดจำกัด
422amount_below_feeยอดต่ำกว่าค่าธรรมเนียม
422payer_inactive, payer_blockedpayer ถูกปิดหรือถูกระงับ
422no_collection_account_availableขณะนี้ไม่มีบัญชีรับเงินว่าง ลองใหม่ภายหลัง
422not_available_now, maintenanceอยู่นอกเวลาให้บริการหรือปิดปรับปรุง ลองใหม่ภายหลัง

รายการรหัสทั้งหมดดูที่รหัสข้อผิดพลาด