Developer Guide API Reference Changelog
API Version: v2

Sendjai Open Platform

API สำหรับเชื่อมต่อระบบขนส่งพัสดุ สร้างออเดอร์ เช็คราคา ติดตามพัสดุ — ทั้งหมดผ่าน API เดียว

✅ Production Ready — API นี้ใช้งานจริงได้แล้ว รองรับ Flash Express, Kerry Express, J&T Express, ไปรษณีย์ไทย และอื่นๆ ผ่าน WeFast

Base URL

EnvironmentBase URLสถานะ
Productionhttps://api.sendjai.com/v2🟢 Active
Legacyhttps://app.sendjai.com/api/v1🟢 Active

Features

Featureคำอธิบาย
🚚 Multi-courierเชื่อมต่อขนส่งหลายเจ้าผ่าน API เดียว (Flash, Kerry, J&T, ไปรษณีย์ไทย)
💰 Check Priceเปรียบเทียบราคาค่าส่งทุกขนส่งอัตโนมัติ
📍 Real-time Trackingติดตามสถานะพัสดุแบบ real-time
🏦 COD Supportรองรับเก็บเงินปลายทาง
🖨️ Label Printingพิมพ์ใบปะหน้าพัสดุ A4/A6/A7
🔐 SecureHMAC-SHA256 signature ทุก request

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

เชื่อมต่อระบบของคุณกับ Sendjai ใน 3 ขั้นตอน

สมัครบัญชี Developer

สมัครที่ app.sendjai.com แล้วไปที่ ตั้งค่า → API Keys เพื่อรับ App ID และ Secret Key

ตั้งค่า API Key

ใช้ App ID + Secret Key สร้าง HMAC-SHA256 signature สำหรับทุก request

Headers:
  X-App-Id: YOUR_APP_ID
  X-Timestamp: 1712345678
  X-Signature: a1b2c3d4e5f6...

เรียก API

ส่ง request ไปที่ Base URL พร้อม signature

curl -X POST https://api.sendjai.com/v2/couriers/check-price \
  -H "X-App-Id: YOUR_APP_ID" \
  -H "X-Timestamp: 1712345678" \
  -H "X-Signature: a1b2c3..." \
  -H "Content-Type: application/json" \
  -d '{"src_zipcode":"10230","dst_zipcode":"50200","weight":500}'

Authentication

ทุก API request ต้องมี 3 headers สำหรับยืนยันตัวตน

Required Headers

HeaderTypeคำอธิบาย
X-App-IdstringApp ID ที่ได้จากหน้า API Keys
X-TimestampintegerUnix timestamp (วินาที) ต้องไม่เกิน 5 นาทีจากเวลาจริง
X-SignaturestringHMAC-SHA256 hash ของ sign string

วิธีสร้าง Signature

Sign String Format: {app_id}{timestamp}{request_body}

Node.js / TypeScript

const crypto = require("crypto");

const appId = "YOUR_APP_ID";
const secretKey = "YOUR_SECRET_KEY";
const timestamp = Math.floor(Date.now() / 1000);
const body = JSON.stringify({
  src_zipcode: "10230",
  dst_zipcode: "50200",
  weight: 500
});

const signString = `${appId}${timestamp}${body}`;
const signature = crypto
  .createHmac("sha256", secretKey)
  .update(signString)
  .digest("hex");

const response = await fetch("https://api.sendjai.com/v2/couriers/check-price", {
  method: "POST",
  headers: {
    "X-App-Id": appId,
    "X-Timestamp": String(timestamp),
    "X-Signature": signature,
    "Content-Type": "application/json",
  },
  body,
});

Python

import hmac, hashlib, time, json, requests

app_id = "YOUR_APP_ID"
secret_key = "YOUR_SECRET_KEY"
timestamp = str(int(time.time()))
body = json.dumps({"src_zipcode": "10230", "dst_zipcode": "50200", "weight": 500})

sign_string = f"{app_id}{timestamp}{body}"
signature = hmac.new(
    secret_key.encode(), sign_string.encode(), hashlib.sha256
).hexdigest()

resp = requests.post(
    "https://api.sendjai.com/v2/couriers/check-price",
    headers={
        "X-App-Id": app_id,
        "X-Timestamp": timestamp,
        "X-Signature": signature,
        "Content-Type": "application/json",
    },
    data=body,
)
print(resp.json())

PHP

$appId = "YOUR_APP_ID";
$secretKey = "YOUR_SECRET_KEY";
$timestamp = time();
$body = json_encode(["src_zipcode" => "10230", "dst_zipcode" => "50200", "weight" => 500]);

$signString = $appId . $timestamp . $body;
$signature = hash_hmac("sha256", $signString, $secretKey);

$ch = curl_init("https://api.sendjai.com/v2/couriers/check-price");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "X-App-Id: $appId",
    "X-Timestamp: $timestamp",
    "X-Signature: $signature",
    "Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

API Reference

เลือก endpoint จากเมนูด้านซ้าย

Create Shipment

สร้างพัสดุใหม่ ระบบจะเรียก API ขนส่งจริงและคืนเลข tracking

POST /v2/shipments

Request Parameters

FieldTypeRequiredคำอธิบาย
courier_namestringชื่อขนส่ง เช่น "Flash Express"
wefast_codestringรหัสขนส่ง เช่น "FlashExpressC"
sender_namestringชื่อผู้ส่ง
sender_phonestringเบอร์โทรผู้ส่ง
src_provincestringจังหวัดต้นทาง (ภาษาไทย)
src_citystringอำเภอ/เขต ต้นทาง
src_districtstringตำบล/แขวง ต้นทาง
src_postalstringรหัสไปรษณีย์ต้นทาง
src_detailstringที่อยู่ละเอียดต้นทาง
receiver_namestringชื่อผู้รับ
receiver_phonestringเบอร์โทรผู้รับ
dst_provincestringจังหวัดปลายทาง (ภาษาไทย)
dst_citystringอำเภอ/เขต ปลายทาง
dst_districtstringตำบล/แขวง ปลายทาง
dst_postalstringรหัสไปรษณีย์ปลายทาง
dst_detailstringที่อยู่ละเอียดปลายทาง
weightintegerน้ำหนัก (กรัม)
widthintegerกว้าง (ซม.) default: 20
lengthintegerยาว (ซม.) default: 30
heightintegerสูง (ซม.) default: 15
cod_amountintegerยอด COD (สตางค์) เช่น 50000 = ฿500, ส่ง 0 = ไม่เก็บเงิน
remarkstringหมายเหตุ

Response

{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "tracking_number": "TH01408JDBMR0B2",
    "sort_code": "16B-16461-01",
    "courier_name": "Flash Express",
    "sender_name": "สมชาย",
    "receiver_name": "บอส",
    "status": "pending",
    "cod_amount": 50000,
    "shipping_cost": 35.00,
    "weight": 500,
    "created_at": "2026-04-03T12:00:00.000Z"
  }
}
⚠️ หมายเหตุ: cod_amount เก็บเป็นสตางค์ (×100) เช่น ฿500 = 50000

List Shipments

ดึงรายการพัสดุทั้งหมดของคุณ

POST /v2/shipments/list

Request Parameters

FieldTypeRequiredคำอธิบาย
statusstringกรอง: pending in_transit delivered cancelled
pageintegerหน้า (default: 1)
limitintegerจำนวนต่อหน้า (default: 50, max: 100)

Response

{
  "data": [
    {
      "id": "uuid-xxx",
      "tracking_number": "TH01408JDBMR0B2",
      "courier_name": "Flash Express",
      "receiver_name": "สมชาย",
      "status": "in_transit",
      "cod_amount": 50000,
      "created_at": "2026-04-03T12:00:00Z"
    }
  ],
  "total": 150
}

Get Shipment Detail

POST /v2/shipments/detail
FieldTypeRequiredคำอธิบาย
tracking_numberstringเลข tracking

Cancel Shipment

POST /v2/shipments/cancel
FieldTypeRequiredคำอธิบาย
tracking_numberstringเลข tracking ที่ต้องการยกเลิก
⚠️ ยกเลิกได้เฉพาะพัสดุที่ status = pending เท่านั้น ถ้าขนส่งรับพัสดุแล้วจะยกเลิกไม่ได้

Check Price

เปรียบเทียบราคาค่าส่งจากทุกขนส่งที่รองรับ

POST /v2/couriers/check-price

Request Parameters

FieldTypeRequiredคำอธิบาย
src_zipcodestringรหัสไปรษณีย์ต้นทาง
dst_zipcodestringรหัสไปรษณีย์ปลายทาง
weightintegerน้ำหนัก (กรัม)
widthintegerกว้าง (ซม.)
lengthintegerยาว (ซม.)
heightintegerสูง (ซม.)

Response

{
  "data": [
    {
      "courier": "Flash Express",
      "code": "FlashExpressC",
      "price": 35.00,
      "est_days": "1-2 วัน",
      "cod_available": true
    },
    {
      "courier": "Kerry Express",
      "code": "KerryExpress",
      "price": 40.00,
      "est_days": "2-3 วัน",
      "cod_available": true
    }
  ]
}

List Couriers

ดูรายชื่อขนส่งทั้งหมดที่เปิดใช้งาน

POST /v2/couriers/list

ไม่ต้องส่ง request body

Track Shipment

ติดตามสถานะพัสดุแบบ real-time

POST /v2/tracking
FieldTypeRequiredคำอธิบาย
tracking_numberstringเลข tracking

Response

{
  "data": {
    "tracking_number": "TH01408JDBMR0B2",
    "status": "in_transit",
    "courier": "Flash Express",
    "timeline": [
      { "status": "pending", "timestamp": "2026-04-03T12:00:00Z", "note": "สร้างออเดอร์" },
      { "status": "picked_up", "timestamp": "2026-04-03T14:00:00Z", "note": "รับพัสดุแล้ว" },
      { "status": "in_transit", "timestamp": "2026-04-03T18:00:00Z", "note": "กำลังขนส่ง — ศูนย์คัดแยก กรุงเทพ" }
    ]
  }
}

Status Values

Statusคำอธิบาย
pendingรอรับพัสดุ
picked_upรับพัสดุแล้ว
in_transitกำลังขนส่ง
out_for_deliveryกำลังนำส่ง
deliveredจัดส่งสำเร็จ
returnedส่งกลับ
cancelledยกเลิก

Top Up via PromptPay QR

สร้าง PromptPay QR Code สำหรับเติมเครดิต ลูกค้าสแกนจ่ายผ่านแอปธนาคาร — เงินเข้าอัตโนมัติผ่าน Stripe

POST /v2/topup/promptpay

Request Parameters

FieldTypeRequiredคำอธิบาย
amountnumberจำนวนเงิน (บาท) ขั้นต่ำ ฿1

Response

{
  "code": "SUCCESS",
  "data": {
    "payment_intent_id": "pi_3abc123...",
    "qr_image_url": "https://stripe.com/qr/xxx.png",
    "qr_data": "00020101021...",
    "amount": 500,
    "currency": "THB",
    "expires_at": "2026-04-03T12:03:00Z"
  }
}
💡 การใช้งาน:
1. เรียก API → ได้ qr_image_url
2. แสดง QR ให้ลูกค้าสแกน
3. Poll /v2/topup/status ทุก 3 วินาทีเพื่อเช็คสถานะ
4. เมื่อ status = paid → เครดิตเข้าอัตโนมัติ
✅ ค่าธรรมเนียม: PromptPay QR — ฟรี ไม่มีค่าธรรมเนียม

Top Up via Card

สร้าง Stripe Payment Intent สำหรับเติมเครดิตด้วยบัตรเครดิต/เดบิต

POST /v2/topup/card

Request Parameters

FieldTypeRequiredคำอธิบาย
amountnumberจำนวนเงิน (บาท) ขั้นต่ำ ฿100

Response

{
  "code": "SUCCESS",
  "data": {
    "payment_intent_id": "pi_3abc123...",
    "client_secret": "pi_3abc123_secret_xxx",
    "amount": 500,
    "fee": 27,
    "charge_amount": 527,
    "currency": "THB"
  }
}
⚠️ ค่าธรรมเนียม: บัตรเครดิต/เดบิต — 3.48% + ฿10/ครั้ง
ตัวอย่าง: เติม ฿500 → fee ฿27 → charge ฿527

การ Confirm Payment ฝั่ง Frontend

// ใช้ Stripe.js confirm ด้วย client_secret
const stripe = Stripe("pk_live_xxx");
const { error } = await stripe.confirmCardPayment(client_secret, {
  payment_method: {
    card: cardElement,
    billing_details: { name: "Customer Name" },
  },
});
if (!error) {
  // Payment succeeded — poll /v2/topup/status
}

Check Top Up Status

เช็คสถานะการเติมเงิน — ใช้ poll ทุก 3 วินาทีหลังสร้าง QR หรือ Payment Intent

POST /v2/topup/status

Request Parameters

FieldTypeRequiredคำอธิบาย
payment_intent_idstringID ที่ได้จาก topup/promptpay หรือ topup/card

Response

{
  "code": "SUCCESS",
  "data": {
    "payment_intent_id": "pi_3abc123...",
    "status": "paid",
    "amount": 500,
    "currency": "THB",
    "method": "promptpay"
  }
}

Status Values

Statusคำอธิบาย
pendingรอชำระ — ยังไม่ได้สแกน QR หรือกรอกบัตร
awaiting_paymentQR ถูกสร้างแล้ว รอสแกนจ่าย
processingกำลังดำเนินการ
paidชำระสำเร็จ — เครดิตเข้าแล้ว
cancelledยกเลิก/หมดอายุ

Top Up History

ดูประวัติเติมเงินทั้งหมด

POST /v2/topup/history

Request Parameters

FieldTypeRequiredคำอธิบาย
limitnumberจำนวนต่อหน้า (default: 20, max: 100)
pagenumberหน้า (default: 1)

Response

{
  "code": "SUCCESS",
  "data": [
    {
      "id": 123,
      "type": "topup",
      "amount": 500.00,
      "balance_after": 1750.00,
      "note": "เติมเครดิต ฿500 ผ่าน PromptPay",
      "created_at": "2026-04-03T12:00:00Z"
    }
  ],
  "total": 25
}

Get Balance

เช็คยอดเครดิตคงเหลือ

POST /v2/balance

ไม่ต้องส่ง request body

Response

{ "data": { "balance": 1250.50, "currency": "THB" } }

Error Codes

เมื่อเกิดข้อผิดพลาด API จะคืน JSON ดังนี้:

{
  "error": "เครดิตไม่เพียงพอ — คงเหลือ ฿50.00 ต้องการ ฿35.00",
  "code": "INSUFFICIENT_BALANCE",
  "balance": 50.00
}

Error Code Reference

CodeHTTPคำอธิบาย
MISSING_FIELDS400ส่งข้อมูลไม่ครบ — ดู field ที่ขาดใน error message
INVALID_SIGNATURE401Signature ไม่ถูกต้อง — เช็ค sign string format
TIMESTAMP_EXPIRED401Timestamp เกิน 5 นาทีจากเวลาจริง
APP_NOT_FOUND401ไม่พบ App ID — เช็คว่าถูกต้อง
INSUFFICIENT_BALANCE403เครดิตไม่เพียงพอ — เติมเงินก่อน
ACCOUNT_SUSPENDED403บัญชีถูกระงับ — ติดต่อ support
EMAIL_NOT_VERIFIED403ยังไม่ยืนยันอีเมล
KYC_NOT_APPROVED403ยังไม่ยืนยันตัวตน (KYC)
USER_NOT_FOUND404ไม่พบผู้ใช้
SHIPMENT_NOT_FOUND404ไม่พบพัสดุ
RATE_LIMITED429เรียก API เร็วเกินไป — รอแล้วลองใหม่
COURIER_ERROR502ขนส่งตอบ error — ดู error message

Rate Limits

Endpoint GroupLimitWindow
ทุก endpoint100 requests1 นาที
Create Shipment30 requests1 นาที
Check Price60 requests1 นาที
💡 Tip: เมื่อถูก rate limit จะได้ HTTP 429 — รอ 60 วินาทีแล้วลองใหม่ ดู header X-RateLimit-Reset สำหรับเวลาที่ reset

Changelog

v2.0 — 3 เมษายน 2026

  • เปิด Open Platform open.sendjai.com
  • API v2 endpoints พร้อมใช้งาน
  • รองรับ HMAC-SHA256 authentication
  • เพิ่ม Check Price, Tracking, Balance APIs