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

CredentialHeaderUsed ForRequirement
Merchant API Key (sk_...)X-API-Key/api/v1/payment/*, /api/v1/transactions, /api/v1/payout/*จำเป็น (ใช้ใน backend merchant เท่านั้น)
Payout SignatureIdempotency-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-IdWebhook callback ที่ส่งจาก PayGate ไปยังระบบของคุณแนะนำอย่างยิ่ง (verify ทุก callback)

2) Endpoint Catalog

รูปแบบนี้อ้างอิงแนว Postman docs: ระบุ method, path, auth, purpose แบบอ่านจบในหน้าเดียว

MethodPathAuthPurpose
POST/api/v1/payment/createX-API-Key (secret)สร้างรายการรับชำระ
GET/api/v1/payment/order/:orderIdX-API-Keyเช็กสถานะรายการจาก orderId
POST/api/v1/payout/createX-API-Key + Signature headersสร้างคำสั่งถอน 1 รายการ
POST/api/v1/payout/bulkX-API-Key + Signature headersสร้างคำสั่งถอนหลายรายการ
GET/api/v1/transactionsX-API-Keyดึงรายการธุรกรรมย้อนหลังแบบ paginated
GET/api/v1/payout/signature-settingsX-API-Keyดูกติกา signature ปัจจุบันจากระบบจริง
POST<your-webhook-url>X-Webhook-Signature (+ webhook headers)รับสถานะฝาก/ถอนอัตโนมัติจาก PayGate (callback)

3) Create Payment Contract

FieldTypeLevelDescriptionExample
amountnumberRequiredยอดที่ต้องชำระ (> 0)100
orderIdstringRecommendedเลขอ้างอิงฝั่งร้านค้า (ไม่ซ้ำต่อ merchant)ORD-10001
descriptionstringOptionalคำอธิบายรายการTopup
metadata.senderAccountNumberstringRecommendedเลขบัญชีผู้โอนแบบเต็ม (แนะนำส่งเป็นตัวเลขอย่างน้อย 8 หลัก)1673585481
metadata.memberNamestringRecommendedชื่อสมาชิก/เจ้าของบัญชีผู้โอนนาย ทองดี ใจงาม
metadata.customerIdstringOptionalรหัสสมาชิกฝั่ง merchant เพื่อ traceu_123
รองรับหลาย merchant และฝาก-ถอนอัตโนมัติ แนะนำส่ง `metadata.senderAccountNumber` (เลขบัญชีเต็ม) + `metadata.memberName` ทุกครั้ง เพื่อเพิ่มความแม่นยำในการยืนยันรายการอัตโนมัติ

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

FieldTypeLevelDescriptionExample
amountnumberRequiredยอดถอน (> 0)5
destination.bankCodestringRequiredรหัสธนาคารของปลายทาง (ดูตาราง bankCode ด้านล่าง)SCB
destination.bankNamestringRequiredชื่อธนาคารปลายทางธนาคารไทยพาณิชย์
destination.accountNumberstringRequiredเลขบัญชีปลายทาง (8-20 หลัก)4190621964
destination.accountNamestringRequiredชื่อบัญชีปลายทางเจษฎา
merchantRefstringOptionalถ้าไม่ส่ง ระบบ generate ให้ (แนะนำส่งถ้ามีเลขอ้างอิงฝั่ง merchant)M01-WD240001
metadataobjectOptionalข้อมูลเสริมสำหรับ trace/reconcile{"sourceSystem":"lotto-main"}
Endpoint ถอนเงินต้องมี `Idempotency-Key`, `X-Signature-Timestamp`, `X-Signature` ทุกครั้ง

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-settings

POST /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 AcceptedNormalized SCB CodeNote
SCB014Siam Commercial Bank
KBANK, KASIKORN004Kasikorn Bank
KTB, KRUNGTHAI006Krungthai Bank
BBL, BANGKOK002Bangkok Bank
TTB011TMBThanachart Bank
BAY025Bank of Ayudhya
GSB030Government Savings Bank
UOB024United Overseas Bank
CIMB022CIMB Thai
BAAC034Bank for Agriculture and Agricultural Cooperatives
GHB033Government Housing Bank
TISCO067TISCO Bank
KKP069Kiatnakin Phatra Bank
LHBANK073Land and Houses Bank
SME098SME Development Bank
001, 002, 004 ...ตรงตามที่ส่งส่งเป็นเลข 3 หลักตรงๆ ได้เช่นกัน
แนวทางมาตรฐานเหมือนเอกสาร Postman: ถ้าฝั่ง merchant มี master bank code อยู่แล้ว ให้ส่งเลข 3 หลักตรงๆ ได้เลย (เช่น `004`, `014`) เพื่อลดปัญหา alias ไม่ตรงกัน

6) Operational + Webhook

Webhook Setup Checklist

  1. ตั้ง Callback URL ฝั่งระบบของคุณให้รับ `POST` และตอบ `2xx` เมื่อรับสำเร็จ
  2. ตั้งค่า webhook ในระบบ PayGate (Dashboard > Webhooks) แล้วเลือก event ที่ต้องการ
  3. บันทึก webhook secret เพื่อตรวจลายเซ็น `X-Webhook-Signature` ทุกครั้ง
  4. รองรับ 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_123

Webhook 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 ได้ชัดเจน

EventFieldTypeLevelDescriptionExample
* (all events)eventstringRequiredชื่อ event ที่ส่งมาpayment.success
* (all events)timestampstring (ISO-8601)Requiredเวลาที่สร้าง callback payload2026-03-05T08:02:11.000Z
* (all events)webhookIdstringRequiredID ของ webhook config ในระบบ PayGatewh_123
payment.successdata.transactionIdstringRequiredID รายการรับชำระtx_123
payment.successdata.orderIdstringRequiredorderId จากฝั่ง merchantORD-10001
payment.successdata.amountnumberRequiredยอดที่ชำระ100
payment.successdata.statusstringRequiredสถานะรายการPAID
payment.successdata.paidAtstring (ISO-8601)Requiredเวลาชำระสำเร็จ2026-03-05T08:02:10.000Z
payment.failed | payment.expireddata.transactionIdstringRequiredID รายการรับชำระtx_124
payment.failed | payment.expireddata.orderIdstringRequiredorderId จากฝั่ง merchantORD-10002
payment.failed | payment.expireddata.amountnumberRequiredยอดรายการ100
payment.failed | payment.expireddata.statusstringRequiredสถานะรายการFAILED / EXPIRED
payout.success | payout.faileddata.idstringRequiredID payoutpo_123
payout.success | payout.faileddata.merchant_refstringRequiredmerchant reference ของคำสั่งถอนM01-WD240001
payout.success | payout.faileddata.statusstringRequiredสถานะ payoutSUCCESS / FAILED
payout.success | payout.faileddata.amountnumberRequiredยอดถอน5

8) Error Catalog (Payment + Payout)

สรุป error ที่พบบ่อยจาก endpoint หลัก เพื่อให้ทำ error handling ได้ครบตั้งแต่รอบแรก

POST /api/v1/payment/create

CodeHTTPWhen
Invalid amount400amount ไม่ถูกต้องหรือ <= 0
ยอดชำระขั้นต่ำคือ <min> บาท400amount ต่ำกว่าค่า minPaymentAmount
ยอดชำระสูงสุดคือ <max> บาท400amount เกินค่า maxPaymentAmount
Order ID already exists400orderId ซ้ำภายใน merchant เดียวกัน
Forbidden403ใช้ key ที่ไม่ใช่ secret key (sk_...) กับ endpoint แบบเขียนข้อมูล
Failed to create payment500ข้อผิดพลาดภายในระบบ

GET /api/v1/payment/order/:orderId

CodeHTTPWhen
Transaction not found404ไม่พบรายการตาม orderId ของ merchant นี้
Failed to get payment500ข้อผิดพลาดภายในระบบ

Payout Endpoints

CodeHTTPWhen
IDEMPOTENCY_KEY_REQUIRED400ไม่ส่ง Idempotency-Key สำหรับ payout endpoint
INVALID_MERCHANT_REF_FORMAT400merchantRef ไม่ตรงรูปแบบ PREFIX-REFERENCE
VALIDATION_ERROR400ข้อมูล request ไม่ครบหรือไม่ถูกต้อง
INSUFFICIENT_BALANCE400ยอดคงเหลือ merchant ไม่พอ
DUPLICATE_PAYOUT_REQUEST409merchantRef/idempotency ซ้ำกับคำขอเดิม

9) End-to-End Integration Flow

  1. Merchant backend สร้าง payment ผ่าน `POST /api/v1/payment/create`
  2. เมื่อมีผลชำระ PayGate ส่ง webhook callback (`payment.success|failed|expired`) ไปยัง callback URL
  3. Merchant backend ยืนยันสถานะซ้ำผ่าน `GET /api/v1/payment/order/:orderId` ก่อน credit/fulfillment
  4. เมื่อมีคำสั่งถอน ให้เรียก `POST /api/v1/payout/create` พร้อม signature และ idempotency
  5. รอ 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