PayGate API Documentation
มาตรฐานการเชื่อมต่อ (Production Ready)
เอกสารนี้ระบุ field จำเป็น, field แนะนำ, bankCode ที่รองรับ, ตัวอย่าง cURL และข้อกำหนดความปลอดภัยสำหรับทีมพัฒนา
Public API Base
https://api.hyronpay.com/api/v1
Webhook Direction
PayGate -> Your Callback URL (POST)
1) Authentication Matrix
เลือก credential ให้ตรง endpoint
| Credential | Header | Used For | Requirement |
|---|---|---|---|
| Merchant API Key (sk_...) | X-API-Key | /api/v1/payment/*, /api/v1/transactions, /api/v1/payout/* | จำเป็น (ใช้ใน backend merchant เท่านั้น) |
| Payout Signature | Idempotency-Key, X-Signature-Timestamp, X-Signature | /api/v1/payout/create, /api/v1/payout/bulk | จำเป็นสำหรับ endpoint ถอนเงิน |
| Webhook Signature (Callback Verify) | X-Webhook-Signature, X-Webhook-Event, X-Webhook-Timestamp, X-Webhook-Id | Webhook callback ที่ส่งจาก PayGate ไปยังระบบของคุณ | แนะนำอย่างยิ่ง (verify ทุก callback) |
2) Endpoint Catalog
รูปแบบนี้อ้างอิงแนว Postman docs: ระบุ method, path, auth, purpose แบบอ่านจบในหน้าเดียว
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /api/v1/payment/create | X-API-Key (secret) | สร้างรายการรับชำระ |
| GET | /api/v1/payment/order/:orderId | X-API-Key | เช็กสถานะรายการจาก orderId |
| POST | /api/v1/payout/create | X-API-Key + Signature headers | สร้างคำสั่งถอน 1 รายการ |
| POST | /api/v1/payout/bulk | X-API-Key + Signature headers | สร้างคำสั่งถอนหลายรายการ |
| GET | /api/v1/transactions | X-API-Key | ดึงรายการธุรกรรมย้อนหลังแบบ paginated |
| GET | /api/v1/payout/signature-settings | X-API-Key | ดูกติกา signature ปัจจุบันจากระบบจริง |
| POST | <your-webhook-url> | X-Webhook-Signature (+ webhook headers) | รับสถานะฝาก/ถอนอัตโนมัติจาก PayGate (callback) |
3) Create Payment Contract
| Field | Type | Level | Description | Example |
|---|---|---|---|---|
| amount | number | Required | ยอดที่ต้องชำระ (> 0) | 100 |
| orderId | string | Recommended | เลขอ้างอิงฝั่งร้านค้า (ไม่ซ้ำต่อ merchant) | ORD-10001 |
| description | string | Optional | คำอธิบายรายการ | Topup |
| metadata.senderAccountNumber | string | Recommended | เลขบัญชีผู้โอนแบบเต็ม (แนะนำส่งเป็นตัวเลขอย่างน้อย 8 หลัก) | 1673585481 |
| metadata.memberName | string | Recommended | ชื่อสมาชิก/เจ้าของบัญชีผู้โอน | นาย ทองดี ใจงาม |
| metadata.customerId | string | Optional | รหัสสมาชิกฝั่ง merchant เพื่อ trace | u_123 |
POST /api/v1/payment/create
curl -X POST 'https://api.hyronpay.com/api/v1/payment/create' \
-H 'X-API-Key: sk_xxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"orderId": "ORD-10001",
"description": "Topup",
"metadata": {
"customerId": "u_123",
"senderAccountNumber": "1673585481",
"memberName": "นาย ทองดี ใจงาม"
}
}'Create Payment Success Response (201)
{
"success": true,
"transaction": {
"id": "uuid",
"orderId": "ORD-10001",
"amount": 100,
"fee": 2,
"netAmount": 98,
"status": "PENDING",
"paymentMethod": "PROMPTPAY",
"qrCode": "data:image/png;base64,...",
"qrExpiry": "2026-03-05T08:15:00.000Z",
"createdAt": "2026-03-05T08:00:00.000Z"
}
}4) Payout Contract
| Field | Type | Level | Description | Example |
|---|---|---|---|---|
| amount | number | Required | ยอดถอน (> 0) | 5 |
| destination.bankCode | string | Required | รหัสธนาคารของปลายทาง (ดูตาราง bankCode ด้านล่าง) | SCB |
| destination.bankName | string | Required | ชื่อธนาคารปลายทาง | ธนาคารไทยพาณิชย์ |
| destination.accountNumber | string | Required | เลขบัญชีปลายทาง (8-20 หลัก) | 4190621964 |
| destination.accountName | string | Required | ชื่อบัญชีปลายทาง | เจษฎา |
| merchantRef | string | Optional | ถ้าไม่ส่ง ระบบ generate ให้ (แนะนำส่งถ้ามีเลขอ้างอิงฝั่ง merchant) | M01-WD240001 |
| metadata | object | Optional | ข้อมูลเสริมสำหรับ trace/reconcile | {"sourceSystem":"lotto-main"} |
Payout Signature Spec
payload = "<X-Signature-Timestamp>.<raw_body_json>"
X-Signature = hex(HMAC_SHA256(secret_api_key, payload))
Required Headers:
- Idempotency-Key
- X-Signature-Timestamp (unix seconds)
- X-Signature
- X-Signature-Nonce (optional, recommended)
Tip: ตรวจค่ากติกาปัจจุบันผ่าน GET /api/v1/payout/signature-settingsPOST /api/v1/payout/create
curl -X POST 'https://api.hyronpay.com/api/v1/payout/create' \
-H 'X-API-Key: sk_xxxxxxxxx' \
-H 'Idempotency-Key: m01-wd-20260304-0001' \
-H 'X-Signature-Timestamp: <unix_seconds>' \
-H 'X-Signature: <hmac_sha256_hex>' \
-H 'Content-Type: application/json' \
-d '{
"amount": 5,
"destination": {
"bankCode": "SCB",
"bankName": "ธนาคารไทยพาณิชย์",
"accountNumber": "4190621964",
"accountName": "เจษฎา"
},
"metadata": {
"sourceSystem": "merchant-backoffice"
}
}'Payout Create Success Response (201)
{
"success": true,
"object": "payout",
"idempotent": false,
"payout": {
"object": "payout",
"id": "po_123",
"merchant_id": "m_123",
"merchant_ref": "M01-WD240001",
"amount": 5,
"fee": 0,
"net_amount": 5,
"currency": "THB",
"destination": {
"bank_code": "014",
"bank_name": "ธนาคารไทยพาณิชย์",
"account_number": "4190621964",
"account_name": "เจษฎา"
},
"status": "QUEUED",
"status_reason": null,
"external_ref": null,
"requested_at": "2026-03-05T08:05:00.000Z",
"processed_at": null,
"created_at": "2026-03-05T08:05:00.000Z",
"metadata": {
"sourceSystem": "merchant-backoffice"
}
}
}Payout Error Response Example
{
"error": "idempotencyKey is required (send Idempotency-Key header or idempotencyKey field)",
"code": "IDEMPOTENCY_KEY_REQUIRED",
"details": null
}5) Bank Code Reference
`destination.bankCode` ส่งเป็น alias (เช่น `SCB`, `KBANK`) หรือเป็นเลข 3 หลักได้
| Input Accepted | Normalized SCB Code | Note |
|---|---|---|
| SCB | 014 | Siam Commercial Bank |
| KBANK, KASIKORN | 004 | Kasikorn Bank |
| KTB, KRUNGTHAI | 006 | Krungthai Bank |
| BBL, BANGKOK | 002 | Bangkok Bank |
| TTB | 011 | TMBThanachart Bank |
| BAY | 025 | Bank of Ayudhya |
| GSB | 030 | Government Savings Bank |
| UOB | 024 | United Overseas Bank |
| CIMB | 022 | CIMB Thai |
| BAAC | 034 | Bank for Agriculture and Agricultural Cooperatives |
| GHB | 033 | Government Housing Bank |
| TISCO | 067 | TISCO Bank |
| KKP | 069 | Kiatnakin Phatra Bank |
| LHBANK | 073 | Land and Houses Bank |
| SME | 098 | SME Development Bank |
| 001, 002, 004 ... | ตรงตามที่ส่ง | ส่งเป็นเลข 3 หลักตรงๆ ได้เช่นกัน |
6) Operational + Webhook
Webhook Setup Checklist
- ตั้ง Callback URL ฝั่งระบบของคุณให้รับ `POST` และตอบ `2xx` เมื่อรับสำเร็จ
- ตั้งค่า webhook ในระบบ PayGate (Dashboard > Webhooks) แล้วเลือก event ที่ต้องการ
- บันทึก webhook secret เพื่อตรวจลายเซ็น `X-Webhook-Signature` ทุกครั้ง
- รองรับ idempotency ฝั่งปลายทาง โดยใช้ `webhookId + event + data.id/orderId` เป็น dedupe key
GET /api/v1/payment/order/:orderId
curl 'https://api.hyronpay.com/api/v1/payment/order/ORD-10001' \
-H 'X-API-Key: sk_xxxxxxxxx'Payment Order Response Example
{
"transaction": {
"id": "tx_123",
"merchantId": "m_123",
"orderId": "ORD-10001",
"amount": 100,
"fee": 2,
"netAmount": 98,
"paymentMethod": "PROMPTPAY",
"status": "PAID",
"paidAt": "2026-03-05T08:02:10.000Z",
"createdAt": "2026-03-05T08:00:00.000Z"
}
}GET /api/v1/payout/signature-settings
curl 'https://api.hyronpay.com/api/v1/payout/signature-settings' \
-H 'X-API-Key: sk_xxxxxxxxx'Webhook Headers (Verify Signature)
X-Webhook-Signature: <hmac_sha256_hex>
X-Webhook-Event: payment.success
X-Webhook-Timestamp: 2026-03-05T08:02:11.000Z
X-Webhook-Id: wh_123Webhook Verify Example (Node.js)
import crypto from 'crypto';
function verifyWebhook(rawBody, signatureHeader, webhookSecret) {
const expected = crypto.createHmac('sha256', webhookSecret).update(rawBody).digest('hex');
const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(String(signatureHeader || ''), 'utf8');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// สำคัญ: verify จาก raw body เดิมที่รับเข้ามาWebhook Event: payment.success
{
"event": "payment.success",
"data": {
"transactionId": "uuid",
"orderId": "ORD-10001",
"amount": 100,
"status": "PAID",
"paidAt": "2026-03-05T08:02:10.000Z"
},
"timestamp": "2026-03-05T08:02:11.000Z",
"webhookId": "wh_123"
}Webhook Event: payment.failed
{
"event": "payment.failed",
"data": {
"transactionId": "uuid",
"orderId": "ORD-10001",
"amount": 100,
"status": "FAILED"
},
"timestamp": "2026-03-05T08:06:10.000Z",
"webhookId": "wh_123"
}Webhook Event: payment.expired
{
"event": "payment.expired",
"data": {
"transactionId": "uuid",
"orderId": "ORD-10001",
"amount": 100,
"status": "EXPIRED"
},
"timestamp": "2026-03-05T08:15:01.000Z",
"webhookId": "wh_123"
}Webhook Event: payout.success
{
"event": "payout.success",
"data": {
"id": "po_123",
"merchant_ref": "M01-WD240001",
"status": "SUCCESS",
"amount": 5
},
"timestamp": "2026-03-05T08:20:10.000Z",
"webhookId": "wh_123"
}Webhook Event: payout.failed
{
"event": "payout.failed",
"data": {
"id": "po_124",
"merchant_ref": "M01-WD240002",
"status": "FAILED",
"amount": 5
},
"timestamp": "2026-03-05T08:21:40.000Z",
"webhookId": "wh_123"
}Webhook Delivery Policy (Current Behavior: 2026-03-05)
- PayGate ส่ง callback แบบ best effort ต่อ webhook URL ที่ active และรองรับ event นั้น
- Timeout ต่อคำขอ default 10 วินาที (ปรับได้ด้วย `WEBHOOK_TIMEOUT_MS`)
- มี retry แบบ exponential backoff ตามค่า `WEBHOOK_MAX_ATTEMPTS` (default 3)
- ฝั่ง merchant ควร queue งานภายในและตอบ 2xx ให้เร็วที่สุด
7) Webhook Field Matrix
ตารางนี้สรุป field ที่ควรรองรับใน callback payload แยกตาม event เพื่อให้ทีม backend mapping ได้ชัดเจน
| Event | Field | Type | Level | Description | Example |
|---|---|---|---|---|---|
| * (all events) | event | string | Required | ชื่อ event ที่ส่งมา | payment.success |
| * (all events) | timestamp | string (ISO-8601) | Required | เวลาที่สร้าง callback payload | 2026-03-05T08:02:11.000Z |
| * (all events) | webhookId | string | Required | ID ของ webhook config ในระบบ PayGate | wh_123 |
| payment.success | data.transactionId | string | Required | ID รายการรับชำระ | tx_123 |
| payment.success | data.orderId | string | Required | orderId จากฝั่ง merchant | ORD-10001 |
| payment.success | data.amount | number | Required | ยอดที่ชำระ | 100 |
| payment.success | data.status | string | Required | สถานะรายการ | PAID |
| payment.success | data.paidAt | string (ISO-8601) | Required | เวลาชำระสำเร็จ | 2026-03-05T08:02:10.000Z |
| payment.failed | payment.expired | data.transactionId | string | Required | ID รายการรับชำระ | tx_124 |
| payment.failed | payment.expired | data.orderId | string | Required | orderId จากฝั่ง merchant | ORD-10002 |
| payment.failed | payment.expired | data.amount | number | Required | ยอดรายการ | 100 |
| payment.failed | payment.expired | data.status | string | Required | สถานะรายการ | FAILED / EXPIRED |
| payout.success | payout.failed | data.id | string | Required | ID payout | po_123 |
| payout.success | payout.failed | data.merchant_ref | string | Required | merchant reference ของคำสั่งถอน | M01-WD240001 |
| payout.success | payout.failed | data.status | string | Required | สถานะ payout | SUCCESS / FAILED |
| payout.success | payout.failed | data.amount | number | Required | ยอดถอน | 5 |
8) Error Catalog (Payment + Payout)
สรุป error ที่พบบ่อยจาก endpoint หลัก เพื่อให้ทำ error handling ได้ครบตั้งแต่รอบแรก
POST /api/v1/payment/create
| Code | HTTP | When |
|---|---|---|
| Invalid amount | 400 | amount ไม่ถูกต้องหรือ <= 0 |
| ยอดชำระขั้นต่ำคือ <min> บาท | 400 | amount ต่ำกว่าค่า minPaymentAmount |
| ยอดชำระสูงสุดคือ <max> บาท | 400 | amount เกินค่า maxPaymentAmount |
| Order ID already exists | 400 | orderId ซ้ำภายใน merchant เดียวกัน |
| Forbidden | 403 | ใช้ key ที่ไม่ใช่ secret key (sk_...) กับ endpoint แบบเขียนข้อมูล |
| Failed to create payment | 500 | ข้อผิดพลาดภายในระบบ |
GET /api/v1/payment/order/:orderId
| Code | HTTP | When |
|---|---|---|
| Transaction not found | 404 | ไม่พบรายการตาม orderId ของ merchant นี้ |
| Failed to get payment | 500 | ข้อผิดพลาดภายในระบบ |
Payout Endpoints
| Code | HTTP | When |
|---|---|---|
| IDEMPOTENCY_KEY_REQUIRED | 400 | ไม่ส่ง Idempotency-Key สำหรับ payout endpoint |
| INVALID_MERCHANT_REF_FORMAT | 400 | merchantRef ไม่ตรงรูปแบบ PREFIX-REFERENCE |
| VALIDATION_ERROR | 400 | ข้อมูล request ไม่ครบหรือไม่ถูกต้อง |
| INSUFFICIENT_BALANCE | 400 | ยอดคงเหลือ merchant ไม่พอ |
| DUPLICATE_PAYOUT_REQUEST | 409 | merchantRef/idempotency ซ้ำกับคำขอเดิม |
9) End-to-End Integration Flow
- Merchant backend สร้าง payment ผ่าน `POST /api/v1/payment/create`
- เมื่อมีผลชำระ PayGate ส่ง webhook callback (`payment.success|failed|expired`) ไปยัง callback URL
- Merchant backend ยืนยันสถานะซ้ำผ่าน `GET /api/v1/payment/order/:orderId` ก่อน credit/fulfillment
- เมื่อมีคำสั่งถอน ให้เรียก `POST /api/v1/payout/create` พร้อม signature และ idempotency
- รอ webhook `payout.success|failed` แล้วค่อยอัปเดตสถานะฝั่งสมาชิก
Step 1: Create Payment
curl -X POST 'https://api.hyronpay.com/api/v1/payment/create' \
-H 'X-API-Key: sk_xxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{
"amount": 100,
"orderId": "ORD-10001",
"description": "Topup",
"metadata": {
"customerId": "u_123",
"senderAccountNumber": "1673585481",
"memberName": "นาย ทองดี ใจงาม"
}
}'Step 2: Receive payment.success Webhook
{
"event": "payment.success",
"data": {
"transactionId": "uuid",
"orderId": "ORD-10001",
"amount": 100,
"status": "PAID",
"paidAt": "2026-03-05T08:02:10.000Z"
},
"timestamp": "2026-03-05T08:02:11.000Z",
"webhookId": "wh_123"
}Step 3: Confirm By OrderId
curl 'https://api.hyronpay.com/api/v1/payment/order/ORD-10001' \
-H 'X-API-Key: sk_xxxxxxxxx'Step 4: Create Payout
curl -X POST 'https://api.hyronpay.com/api/v1/payout/create' \
-H 'X-API-Key: sk_xxxxxxxxx' \
-H 'Idempotency-Key: m01-wd-20260304-0001' \
-H 'X-Signature-Timestamp: <unix_seconds>' \
-H 'X-Signature: <hmac_sha256_hex>' \
-H 'Content-Type: application/json' \
-d '{
"amount": 5,
"destination": {
"bankCode": "SCB",
"bankName": "ธนาคารไทยพาณิชย์",
"accountNumber": "4190621964",
"accountName": "เจษฎา"
},
"metadata": {
"sourceSystem": "merchant-backoffice"
}
}'Step 5: Receive payout.success Webhook
{
"event": "payout.success",
"data": {
"id": "po_123",
"merchant_ref": "M01-WD240001",
"status": "SUCCESS",
"amount": 5
},
"timestamp": "2026-03-05T08:20:10.000Z",
"webhookId": "wh_123"
}10) Interactive Docs (Try API Live)
ใช้สำหรับทดสอบเชื่อมต่อแบบเร็วจากหน้า docs โดยตรง (ควรใช้ test key/สภาพแวดล้อมทดสอบ)
Result
ยังไม่มีผลลัพธ์ กด Send Request เพื่อทดสอบ
11) Security Baseline
- เก็บ `sk_...` เฉพาะฝั่ง server (เช่น backend ของ `dog.e2p.asia`) ห้ามฝังใน frontend/browser
- เปิดใช้ HTTPS และจำกัด IP/Origin ตามโครงสร้างระบบของคุณ
- ใช้ idempotency และ signature ทุกคำสั่งถอนเงิน
- กำหนด rotation policy สำหรับ API key และ webhook secret/signature key