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

Source: https://checkslip.com/docs

หน้านี้พาจากสมัครเสร็จไปถึงคำขอแรกที่ได้ผล ใช้เวลาอ่านไม่กี่นาที ส่วนรายละเอียดทุก route อยู่ใน[เอกสารอ้างอิง](https://checkslip.com/docs/reference)

## 1. ออก API key

1. [สมัคร](https://app.checkslip.com/sign-up?utm_source=site&utm_content=docs) และยืนยันเบอร์โทร บัญชีจะได้เครดิตทดลอง 50 เครดิต (ตรวจได้ 50 ใบ)
2. เปิด[หน้า API key](https://app.checkslip.com/keys) กดออก key แล้วเลือกสิทธิ์ slip:lookup (ถ้าจะอ่านประวัติด้วย เลือก slip:read เพิ่ม สิทธิ์หนึ่งไม่ได้รวมอีกสิทธิ์)
3. คัดลอก key เก็บไว้ทันที key ขึ้นต้นด้วย csk_ และแสดงครั้งเดียวตอนออก เปิดดูซ้ำไม่ได้ เพราะระบบไม่ได้เก็บตัว key ไว้ ถ้าทำหาย ให้ออก key ใหม่แล้วเพิกถอนตัวเก่า

เก็บ key ไว้ฝั่งเซิร์ฟเวอร์ของคุณ ห้ามใส่ในโค้ดหน้าเว็บหรือแอปมือถือ

## 2. ส่งคำขอแรก

อ่านข้อความใน QR บนสลิปด้วยเครื่องอ่าน QR ใดก็ได้ แล้วส่งมา

**cURL**

```bash
curl https://api.checkslip.com/api/slips/lookup \
  -H "Authorization: Bearer $CHECKSLIP_API_KEY" \
  -H "Idempotency-Key: order-1042-slip-1" \
  -H "Content-Type: application/json" \
  -d '{"qr":"00330006000001010306902126302105340875102TH9104F86F"}'
```

**Node.js**

```javascript
const res = await fetch("https://api.checkslip.com/api/slips/lookup", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CHECKSLIP_API_KEY}`,
    "Idempotency-Key": "order-1042-slip-1",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    qr: "00330006000001010306902126302105340875102TH9104F86F",
  }),
});
const data = await res.json();
```

**Python**

```python
import os

import requests

res = requests.post(
    "https://api.checkslip.com/api/slips/lookup",
    headers={
        "Authorization": f"Bearer {os.environ['CHECKSLIP_API_KEY']}",
        "Idempotency-Key": "order-1042-slip-1",
    },
    json={
        "qr": "00330006000001010306902126302105340875102TH9104F86F",
    },
)
data = res.json()
```

ค่า qr ในตัวอย่างใช้ดูรูปแบบเท่านั้น ให้ใช้ข้อความจาก QR บนสลิปที่ลูกค้าส่งให้คุณ ถ้าไม่มี QR ในมือ ส่งรูปสลิปแทนได้ด้วย multipart/form-data ฟิลด์ image

## 3. อ่านคำตอบ

ตัดสินจาก outcome ใน body ไม่ใช่จาก HTTP status

```json
{
  "request_id": "0192d4e0-7c1a-7b3e-9f00-1a2b3c4d5e6f",
  "outcome": "FOUND",
  "checked_at": "2026-10-29T10:41:02+07:00",
  "slip": {
    "trans_ref": "630210534087",
    "transferred_at": "2026-10-29T10:33:30+07:00",
    "amount": {
      "satang": 5000,
      "currency": "THB"
    },
    "sender": {
      "bank": {
        "code": "KKP",
        "bot_code": "069",
        "name_th": "ธนาคารเกียรตินาคินภัทร",
        "name_en": "Kiatnakin Phatra Bank"
      },
      "name_th": "นาย สมชาย ใ",
      "name_en": "MR. SOMCHAI J",
      "account": "0439"
    },
    "receiver": {
      "kind": "BANK_ACCOUNT",
      "bank": {
        "code": "GSB",
        "bot_code": "030",
        "name_th": "ธนาคารออมสิน",
        "name_en": "Government Savings Bank"
      },
      "name_th": "นางสาว สมหญิง ร",
      "name_en": "MISS SOMYING R",
      "account": "9681"
    }
  }
}
```

| `outcome` | ความหมายสำหรับร้าน | เครดิต |
| --- | --- | --- |
| `FOUND` | **พบรายการ** ธนาคารมีรายการนี้ เทียบยอดเงิน ผู้รับ และเวลา กับออเดอร์ของคุณ แล้วตัดสินใจรับเงินเอง | หัก 1 |
| `NOT_FOUND` | **ไม่พบรายการ** ธนาคารไม่มีรายการตาม trans_ref นี้ ณ เวลาที่เรียกดูข้อมูล ผลนี้บอกแค่ว่าไม่มีรายการ ไม่ได้บอกว่าเกิดจากอะไร ร้านเป็นคนตัดสินใจ เช่น ขอหลักฐานเพิ่มจากลูกค้า | ไม่หัก |
| `DUPLICATE` | **ซ้ำ** บัญชีของคุณเคยดึงข้อมูลรายการของสลิปนี้แล้ว duplicate_of.request_id ชี้ไปที่ครั้งแรก ถ้าครั้งแรกเป็นออเดอร์อื่น แปลว่าสลิปนี้เคยใช้กับร้านคุณแล้ว ถ้าเป็นออเดอร์เดียวกัน ดูข้อ 5 | ไม่หัก |
| `PENDING` | **รอธนาคาร** [ผลตรวจรายการโอน](https://checkslip.com/docs/outcomes) | ไม่หัก |
| `UNAVAILABLE` | **ติดต่อไม่ได้** [รหัสข้อผิดพลาด](https://checkslip.com/problems/unavailable) | ไม่หัก |
| `INVALID_QR` | **อ่าน QR ไม่ได้** [รหัสข้อผิดพลาด](https://checkslip.com/problems/invalid-qr) | ไม่หัก |
| `INVALID_FILE` | **อ่านไฟล์ไม่ได้** [รหัสข้อผิดพลาด](https://checkslip.com/problems/invalid-file) | ไม่หัก |
| `QR_TAMPERED` | **QR ไม่ตรง** [รหัสข้อผิดพลาด](https://checkslip.com/problems/qr-tampered) | ไม่หัก |
| `TOO_OLD` | **เกินช่วงย้อนหลัง** [รหัสข้อผิดพลาด](https://checkslip.com/problems/too-old) | ไม่หัก |

ใน API ผลตรวจหนึ่งครั้งยังใช้ชื่อว่า check ในรหัส [`CHECK_NOT_FOUND`](https://checkslip.com/problems/check-not-found) ชื่อเดิมคงไว้เพื่อความเข้ากันได้ และหมายถึงผลตรวจเดียวกัน

## 4. เงื่อนไขการหักเครดิต

หัก 1 เครดิตเฉพาะเมื่อผลเป็น FOUND ผลอื่นไม่หัก รวมถึง DUPLICATE และ NOT_FOUND

ถ้าผลเป็น PENDING (รอธนาคาร) ยังไม่หัก ระบบจะตรวจสอบซ้ำให้อัตโนมัติ ถ้าพบรายการภายหลังจะหัก 1 ตอนนั้น และส่งผลทาง webhook

ดูยอดเครดิตและรายการที่หักได้ใน[แอป](https://app.checkslip.com)

## 5. ส่ง Idempotency-Key ทุกคำขอ

การเชื่อมต่อขัดข้อง หรือ timeout ก่อนได้คำตอบ ให้ส่งคำขอเดิมซ้ำด้วย Idempotency-Key เดิม ภายใน 24 ชั่วโมง คุณจะได้คำตอบของครั้งแรกกลับมา (request_id เดิม ผลเดิม) ไม่เรียกดูจากธนาคารใหม่และไม่หักเครดิตเพิ่ม

ถ้าส่งซ้ำโดยไม่มีคีย์เดิม ระบบจะมองเป็นคำขอใหม่ เมื่อครั้งแรกได้ FOUND ไปแล้ว ครั้งใหม่จะได้ DUPLICATE แทน ไม่หักเครดิต แต่โค้ดของคุณอาจเข้าใจผิดว่าสลิปถูกใช้ซ้ำ แล้วปฏิเสธลูกค้าที่จ่ายจริง

ส่งสลิปใบเดียวกันพร้อมกันหลายคำขอโดยไม่มีคีย์ ก็หักแค่ 1 ครั้ง: คำขอหนึ่งได้ FOUND ที่เหลือได้ DUPLICATE แต่ระหว่างที่คำขอแรกยังไม่จบ ทุกคำขอจองเครดิตไว้ชั่วคราว ถ้าเครดิตเหลือน้อย คำขอที่เกินอาจได้ 402 แทน DUPLICATE (ไม่หักทั้งคู่)

ใช้คีย์ที่ผูกกับออเดอร์และสลิปใบนั้น เช่น order-1042-slip-1 คีย์เดิมกับ body ที่ต่างกันจะได้ข้อผิดพลาด [`idempotency-key-reused`](https://checkslip.com/problems/idempotency-key-reused) และถ้าคำขอแรกยังทำงานอยู่จะได้ [`idempotency-in-flight`](https://checkslip.com/problems/idempotency-in-flight) ให้รอแล้วส่งใหม่ด้วยคีย์เดิม

## 6. ตอนมีปัญหา

ข้อผิดพลาดทุกตัวเป็น application/problem+json (RFC 9457) อ่าน type เพื่อรู้ว่าเกิดอะไร แต่ละ type มี[หน้าคำอธิบายและวิธีแก้](https://checkslip.com/docs/errors)

แจ้งทีมงานพร้อมค่า instance จาก response (เลขเดียวกับ header X-Request-Id)

## ต่อไป

- [ธนาคารที่รองรับ](https://checkslip.com/docs/banks)
- [รหัสข้อผิดพลาดทั้งหมด](https://checkslip.com/docs/errors)
- [เอกสารอ้างอิงทุก route](https://checkslip.com/docs/reference)
