Merchant Integration · v1

Gateway API Reference

คู่มือเชื่อมต่อระบบรับชำระเงินสำหรับร้านค้า — สร้างรายการ รับ QR PromptPay และรับแจ้งผลผ่าน webhook

Base URL https://gateway.alphaquestcom.com Auth X-Api-Key Callback IP 18.136.50.160
สารบัญ
  1. การยืนยันตัวตน
  2. ภาพรวมการทำงาน
  3. สร้างรายการชำระเงิน
  4. ดูสถานะรายการ
  5. ยกเลิกรายการ
  6. ดูยอดคงเหลือ
  7. Webhook (แจ้งผล)
  8. รหัสข้อผิดพลาด

1. การยืนยันตัวตน

ทุก request ที่ขึ้นต้นด้วย /v1/ ต้องแนบ API key ของร้านใน header:

X-Api-Key: gw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
เก็บ key เป็นความลับ — key ขึ้นต้น gw_live_ ใช้ฝั่งเซิร์ฟเวอร์เท่านั้น ห้ามฝังในเว็บ/แอปฝั่งลูกค้า หากรั่วให้แจ้งเพื่อ rotate ทันที (key เดิมจะใช้ไม่ได้)

2. ภาพรวมการทำงาน

Idempotency: ทุกครั้งที่สร้างรายการต้องแนบ header Idempotency-Key (สตริงไม่ซ้ำต่อ 1 ออร์เดอร์ เช่นเลขออร์เดอร์ของร้าน) — ยิงซ้ำด้วย key เดิมจะได้รายการเดิม ไม่เกิดรายการซ้ำ

3. สร้างรายการชำระเงิน

POST/v1/payments

Headers

Headerคำอธิบาย
X-Api-Keyจำเป็นAPI key ของร้าน
Idempotency-Keyจำเป็นสตริงไม่ซ้ำต่อออร์เดอร์ (1–128 ตัวอักษร)
Content-Typeจำเป็นapplication/json

Body

FieldTypeคำอธิบาย
amountnumberจำเป็นยอดเงิน (บาท) จำนวนบวก ≤ 1,000,000 ทศนิยมไม่เกิน 2 ตำแหน่ง
merchant_refstringจำเป็นรหัสอ้างอิงของร้าน (1–64 ตัวอักษร) เช่นเลขออร์เดอร์
descriptionstringไม่บังคับคำอธิบายรายการ (≤255)
return_urlstringไม่บังคับURL ให้ลูกค้ากลับหลังชำระ (ต้องเป็น http/https)

ตัวอย่าง

curl -X POST https://gateway.alphaquestcom.com/v1/payments \
  -H "X-Api-Key: gw_live_xxxxxxxx" \
  -H "Idempotency-Key: ORDER-10023" \
  -H "Content-Type: application/json" \
  -d '{"amount": 300.00, "merchant_ref": "ORDER-10023"}'

Response 201 Created (ยิงซ้ำ key เดิม = 200)

{
  "payment_id": "pay_01M1J9...",
  "status": "pending",
  "amount": 300,
  "currency": "THB",
  "checkout_url": "https://gateway.alphaquestcom.com/p/pay_01M1J9...",
  "qr_data_url": "data:image/png;base64,iVBOR...",
  "fee_amount": null,
  "net_amount": null
}

fee_amount / net_amount เป็น null จนกว่าจะชำระสำเร็จ (ค่าธรรมเนียมคำนวณตอนจ่ายจริง)

4. ดูสถานะรายการ

GET/v1/payments/{payment_id}
curl https://gateway.alphaquestcom.com/v1/payments/pay_01M1J9... \
  -H "X-Api-Key: gw_live_xxxxxxxx"

คืน object เดียวกับตอนสร้าง โดย status เป็นค่าใดค่าหนึ่ง:

pending รอชำระ · paid ชำระแล้ว · cancelled ยกเลิก · expired หมดอายุ (ไม่จ่ายใน 60 นาที)

5. ยกเลิกรายการ

POST/v1/payments/{payment_id}/cancel

ยกเลิกได้เฉพาะรายการที่ยังไม่ชำระ — ถ้าจ่ายไปแล้วจะได้ 409 already_paid

curl -X POST https://gateway.alphaquestcom.com/v1/payments/pay_01M1J9.../cancel \
  -H "X-Api-Key: gw_live_xxxxxxxx"

6. ดูยอดคงเหลือ

GET/v1/balance

ยอดสุทธิสะสมของร้าน (หลังหักค่าธรรมเนียม)

{ "balance": 1782.50, "currency": "THB" }

7. Webhook (แจ้งผล)

เมื่อสถานะรายการเปลี่ยน ระบบยิง POST ไปที่ webhook URL ของร้าน (ตั้งค่าตอนสมัคร) พร้อม headers:

Headerค่า
X-Gateway-Eventpayment.paid หรือ payment.cancelled
X-Gateway-Signaturesha256=<hex> — HMAC-SHA256 ของ raw body ด้วย webhook secret

Payload — payment.paid

{
  "event": "payment.paid",
  "payment_id": "pay_01M1J9...",
  "merchant_ref": "ORDER-10023",
  "amount": 300,
  "paid_amount": 300,
  "fee_amount": 3,
  "net_amount": 297,
  "currency": "THB",
  "paid_at": "2026-09-03T09:42:09.382Z"
}

Payload — payment.cancelled

{
  "event": "payment.cancelled",
  "payment_id": "pay_01M1J9...",
  "merchant_ref": "ORDER-10023",
  "amount": 300,
  "status": "cancelled"  // หรือ "expired"
}

ตรวจลายเซ็น (Node.js)

const crypto = require('crypto')

// rawBody = ตัว body ดิบ (Buffer/string) ก่อน JSON.parse
function verify(rawBody, signatureHeader, webhookSecret) {
  const expected = 'sha256=' +
    crypto.createHmac('sha256', webhookSecret)
          .update(rawBody, 'utf8').digest('hex')
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(signatureHeader))
}
การส่งซ้ำ (retry): ถ้า webhook ตอบไม่สำเร็จ (ไม่ใช่ 2xx) ระบบส่งซ้ำตามช่วงเวลา 30 วิ2 นาที10 นาที1 ชม. รวม 5 ครั้ง แล้วหยุด — endpoint ของร้านควร idempotent (รับ event เดิมซ้ำได้)
Whitelist: webhook ยิงมาจาก IP 18.136.50.160 เสมอ — เปิดรับได้เฉพาะ IP นี้ · ควรตอบ 200 ทันทีที่รับได้ แล้วค่อยประมวลผลเบื้องหลัง

8. รหัสข้อผิดพลาด

ข้อผิดพลาดคืน JSON รูปแบบ { "error": "...", "code": "..." }

HTTPcodeความหมาย
401invalid_api_keyAPI key ผิดหรือร้านถูกปิด
403merchant_suspendedร้านถูกระงับ
422missing_idempotency_keyไม่ได้แนบ Idempotency-Key
422invalid_amountamount ไม่ถูกต้อง (บวก ≤ 1,000,000 ทศนิยม ≤ 2)
409idempotency_conflictใช้ Idempotency-Key เดิมแต่ยอดเงินไม่ตรง
409already_paidยกเลิกรายการที่ชำระแล้วไม่ได้
404ไม่พบรายการ (route not found)
502ระบบชำระเงินปลายทางขัดข้องชั่วคราว