SlipGate API

เอกสาร API

ระบบตรวจสอบสลิปสำหรับนักพัฒนา เริ่มใช้งานได้ภายใน 5 นาที รองรับการตรวจ QR สลิปทุกธนาคารและ TrueMoney พร้อม Webhook ส่งกลับเข้าสู่แอปของคุณ

1. เริ่มต้นใช้งาน

ใช้งาน SlipGate API ได้ใน 3 ขั้นตอน:

  1. สมัครบัญชีฟรี ที่ SlipGate (ไม่ต้องผูกบัตรเครดิต)
  2. สร้าง API key ที่หน้า /dashboard/api-keys จะได้ key ขึ้นต้นด้วย sk_live_ หรือ sk_test_
  3. เรียก API โดยส่ง header Authorization: Bearer <API_KEY> ในทุก request

ตัวอย่างการเรียก endpoint ตรวจสอบยอดเครดิตเพื่อทดสอบ key:

curl https://api.slipgate.io/v1/account \
  -H "Authorization: Bearer sk_live_xxx"

2. Authentication

ทุก request ต้องส่ง HTTP header Authorization แบบ Bearer token ตัว API key เป็นตัวระบุทั้งบัญชีและโหมดการใช้งาน:

Authorization: Bearer sk_live_8c2f9b1d4a7e6f5c0b3a2d9e8f7c6b5a
# หรือสำหรับ sandbox / แผน Free ที่ต้องการทดลอง
Authorization: Bearer sk_test_d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8
  • sk_live_* – production keys ใช้ตรวจสลิปจริง หักเงินจากเครดิตหรือใช้โควต้าฟรี
  • sk_test_* – sandbox keys คืนข้อมูลสลิป mock data, ไม่หักเครดิต
  • เก็บ API key ฝั่ง server เท่านั้น อย่าฝังลงโค้ดฝั่ง browser หรือแอปมือถือ
  • หาก key หลุดให้กดปุ่ม revoke ที่หน้า /dashboard/api-keys ระบบจะ invalidate ทันที

3. Rate Limits & Pricing

ราคา ฿0.20 ต่อสลิป หักจากเครดิตในบัญชี ผู้ใช้ทุกคนได้โควต้าฟรี 100 สลิป/เดือน ก่อนเริ่มหักเงินจริง โควต้าฟรี reset ทุกวันที่ 1 ของเดือน

โหมดค่าใช้จ่ายRate limit
sk_live_*฿0.20/สลิป (หลังใช้โควต้าฟรีหมด)60 req/นาที
sk_test_*ไม่หักเงิน, ไม่ใช้โควต้า120 req/นาที

เมื่อเครดิตและโควต้าฟรีหมด ระบบจะตอบ HTTP 402 NO_CREDIT ให้เติมเครดิตที่หน้า /dashboard/billing

4. Base URL

ทุก endpoint ในเอกสารนี้อยู่ภายใต้ base URL เดียวกัน:

https://api.slipgate.io/v1

ทั้งโหมด production และ sandbox ใช้ host เดียวกัน ระบบแยกโหมดจาก prefix ของ API key (sk_live_ หรือ sk_test_)

5. POST /v1/slip/verify

ส่งภาพสลิปเข้ามาตรวจสอบทีละใบ ระบบจะลอง decode QR EMVCo บนสลิปก่อน หาก QR เสียจะ fallback ไป OCR อ่านยอดและผู้โอนแทน

POST/v1/slip/verify

Request

ส่งเป็น multipart/form-data โดยมีฟิลด์ดังนี้:

  • file (required) – ภาพสลิป JPEG/PNG/WebP ขนาดไม่เกิน 5 MB
  • webhook (optional) – ส่ง 1 เพื่อให้ระบบยิง event slip.verified เข้า webhook ที่ลงทะเบียนไว้ด้วย

ตัวอย่างโค้ด

curl -X POST https://api.slipgate.io/v1/slip/verify \
  -H "Authorization: Bearer sk_live_xxx" \
  -F "file=@slip.jpg" \
  -F "webhook=1"

Response (200 OK)

{
  "ok": true,
  "data": {
    "trans_ref": "01420059142554XPTKZ4UB91A2",
    "amount": 250.00,
    "currency": "THB",
    "sender": {
      "name": "นาย ธนากร ใจดี",
      "bank": "KBANK",
      "account_last4": "1234"
    },
    "receiver": {
      "name": "บริษัท สลิปเกต จำกัด",
      "bank": "SCB",
      "account_last4": "5678"
    },
    "transferred_at": "2026-06-06T10:32:00+07:00",
    "verified_via": "qr",
    "duplicate": false
  },
  "credit": {
    "charged": 0.20,
    "remaining": 99.80,
    "free_quota_used": 0
  }
}

Error codes

HTTPCodeคำอธิบาย
401UNAUTHORIZEDไม่พบหรือใช้ API key ผิด
402NO_CREDITเครดิตหมดและใช้โควต้าฟรีครบแล้ว
413FILE_TOO_LARGEไฟล์เกิน 5 MB
422INVALID_SLIPไม่สามารถอ่านข้อมูลจากสลิปได้

6. POST /v1/slip/bulk

ส่งหลายสลิปพร้อมกัน (สูงสุด 50 ไฟล์ต่อ request) ระบบ pre-check เครดิตก่อน—หากเครดิต+โควต้าฟรีไม่พอจ่ายทั้งชุด จะตอบ 402 NO_CREDIT โดยไม่ประมวลผลใด ๆ แต่ละไฟล์มีผลลัพธ์ของตัวเองใน array results แม้บางใบจะ verify ไม่ผ่านก็ไม่กระทบใบอื่น

POST/v1/slip/bulk

Request

ส่งเป็น multipart/form-data โดยใส่ฟิลด์ file ได้หลายครั้ง (สูงสุด 50 ครั้ง) แต่ละไฟล์ขนาดไม่เกิน 5 MB

ตัวอย่างโค้ด

curl -X POST https://api.slipgate.io/v1/slip/bulk \
  -H "Authorization: Bearer sk_live_xxx" \
  -F "file=@slip-1.jpg" \
  -F "file=@slip-2.jpg" \
  -F "file=@slip-3.jpg"

Response (200 OK)

{
  "ok": true,
  "results": [
    {
      "index": 0,
      "ok": true,
      "data": { "trans_ref": "0142...A2", "amount": 250.00 }
    },
    {
      "index": 1,
      "ok": false,
      "error": { "code": "DUPLICATE", "message": "Slip already verified" }
    },
    {
      "index": 2,
      "ok": true,
      "data": { "trans_ref": "0142...B7", "amount": 120.00 }
    }
  ],
  "credit": {
    "charged": 0.40,
    "remaining": 99.40,
    "free_quota_used": 0
  }
}

ฟิลด์ credit.charged เป็นผลรวมของไฟล์ที่ verify สำเร็จเท่านั้น ไฟล์ที่ตอบ ok: false จะไม่ถูกหักเครดิต

7. GET /v1/account

ดูยอดเครดิตคงเหลือและสถานะโควต้าฟรีของบัญชี ใช้สำหรับแสดงผลในแดชบอร์ดของเว็บคุณหรือไว้ alert เมื่อใกล้หมด

GET/v1/account

ตัวอย่างโค้ด

curl https://api.slipgate.io/v1/account \
  -H "Authorization: Bearer sk_live_xxx"

Response (200 OK)

{
  "ok": true,
  "account_id": "acc_01HZQK8W6V",
  "balance": 142.60,
  "currency": "THB",
  "free_quota": {
    "limit": 100,
    "used": 23,
    "remaining": 77,
    "resets_at": "2026-07-01T00:00:00+07:00"
  },
  "plan": "free",
  "mode": "live"
}

8. Customer Webhooks

ลงทะเบียน URL ของระบบคุณเพื่อรับ event แบบ real-time เมื่อสลิปถูก verify สำเร็จหรือมีเหตุการณ์ที่ต้องการแจ้งกลับ ทุก request จาก SlipGate จะเซ็นด้วย HMAC-SHA256 คุณจึงตรวจสอบได้แน่ใจว่ามาจาก SlipGate จริง

ลงทะเบียน webhook

POST/v1/webhooks
curl -X POST https://api.slipgate.io/v1/webhooks \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/slipgate",
    "events": ["slip.verified", "slip.duplicate"]
  }'

หลังลงทะเบียนสำเร็จระบบจะคืนค่า secret ใช้สำหรับ verify signature เก็บค่านี้ไว้เป็นความลับและตั้งใน env ของเว็บคุณ (เช่น SLIPGATE_WEBHOOK_SECRET)

โครงสร้าง payload

Event ถูกส่งเป็น HTTP POST body แบบ JSON พร้อม header X-SlipGate-Signature: sha256=<hex> โดยค่า hex คือ HMAC-SHA256 ของ raw body ใช้ secret ที่ระบบให้ตอนลงทะเบียน

{
  "id": "evt_01HZQM5R7K",
  "type": "slip.verified",
  "created_at": "2026-06-06T10:33:01+07:00",
  "data": {
    "trans_ref": "01420059142554XPTKZ4UB91A2",
    "amount": 250.00,
    "sender_name": "นาย ธนากร ใจดี"
  }
}

ตรวจสอบ signature

เปรียบเทียบค่าใน header กับ HMAC ที่คำนวณจาก body โดยใช้ฟังก์ชัน timing-safe comparison เพื่อกัน timing attack:

import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.SLIPGATE_WEBHOOK_SECRET;

app.post(
  "/webhooks/slipgate",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const header = req.header("X-SlipGate-Signature") ?? "";
    const expected =
      "sha256=" +
      crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");

    const ok =
      header.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));

    if (!ok) return res.status(401).send("invalid signature");

    const event = JSON.parse(req.body.toString("utf8"));
    // handle event.type === "slip.verified", etc.
    res.json({ received: true });
  }
);

หาก endpoint ของคุณตอบกลับเป็น status code อื่นที่ไม่ใช่ 2xx ระบบจะ retry ด้วย exponential backoff สูงสุด 5 ครั้งในช่วง 24 ชั่วโมง

9. Sandbox

ใช้ API key ที่ขึ้นต้นด้วย sk_test_ เพื่อทดสอบการเชื่อมต่อโดยไม่เปลือง quota และไม่หักเงิน ระบบจะคืน mock data ที่มีโครงสร้างเหมือน production ทุกประการ เหมาะสำหรับใช้ใน CI/CD หรือ local development

  • คืนผลลัพธ์ deterministic — ภาพเดิมให้ผลเดิมเสมอ
  • เพิ่ม ?force_error=NO_CREDIT ที่ท้าย URL เพื่อจำลอง error response ทุกชนิดที่ตารางในหัวข้อ Errors ระบุไว้
  • Webhook ใน sandbox ส่งจริง ระบบจะยิงไป URL ที่ลงทะเบียนเหมือนกับ production แต่ข้อมูลใน payload เป็น mock
  • Response เพิ่ม field "mode": "test" ให้ระบบของคุณแยกได้

10. Errors

ทุก error response มีโครงสร้างเดียวกัน:

{
  "ok": false,
  "error": {
    "code": "NO_CREDIT",
    "message": "Insufficient credit. Top up at /dashboard/billing",
    "request_id": "req_01HZQK8W6V"
  }
}

ส่งค่า request_id มาด้วยเมื่อแจ้งทีมงานเพื่อให้ตรวจสอบ log ได้เร็วขึ้น

ตารางสรุป error codes

HTTPCodeคำอธิบาย
400BAD_REQUESTพารามิเตอร์ไม่ถูกต้องหรือขาดฟิลด์ที่จำเป็น
401UNAUTHORIZEDไม่พบ Authorization header หรือ API key ไม่ถูกต้อง
402NO_CREDITเครดิตไม่พอและใช้โควต้าฟรีหมดแล้ว เติมเครดิตที่ /dashboard/billing
403FORBIDDENAPI key นี้ไม่มีสิทธิ์เรียก endpoint ดังกล่าว
404NOT_FOUNDไม่พบ resource ที่อ้างถึง
409DUPLICATEสลิปนี้เคยถูก verify ไปแล้ว
413FILE_TOO_LARGEไฟล์เกิน 5 MB (verify) หรือเกิน 50 ไฟล์ (bulk)
415UNSUPPORTED_MEDIAรองรับเฉพาะ image/jpeg, image/png, image/webp
422INVALID_SLIPอ่าน QR หรือ OCR สลิปไม่สำเร็จ
429RATE_LIMITEDเรียกถี่เกินขีดจำกัด (60 req/นาที สำหรับแผน Free)
500INTERNAL_ERRORเกิดข้อผิดพลาดที่ฝั่งระบบ ลองใหม่อีกครั้งหรือติดต่อทีมงาน
503UPSTREAM_DOWNระบบ verify ฝั่งธนาคารไม่ตอบสนองชั่วคราว