- ในหน้า Integrations ส่วน Webhooks กด เพิ่ม Webhook (Project ต้องมีร้าน Business Apps ในเว็บ หรือเปิด Business Apps API หรือ Wi-Fi Hotspot API และคุณเป็น Owner หรือ Admin)
- ใส่ URL แบบ
https://ที่เข้าถึงได้จากอินเทอร์เน็ต และเลือกเหตุการณ์ที่ต้องการ (ไม่เลือก = ทุกเหตุการณ์) - คัดลอก Signing secret เก็บไว้ ระบบแสดงครั้งเดียว
- กด ทดสอบ เพื่อส่งเหตุการณ์
pingไปลองที่ URL ของคุณ
| เหตุการณ์ | เกิดเมื่อ |
|---|---|
order.created, order.updated, bill.closed, booking.created, shift.closed ฯลฯ | มีการเปลี่ยนแปลงในร้าน ทั้งร้านในเว็บและร้านแบบ API ไม่ว่าจะเปลี่ยนจากหน้าจัดการ แอปพนักงาน หรือ API (มี shopId) |
order.payment_claimed, booking.payment_claimed, booking.cancelled | ลูกค้าบนหน้าเว็บกดแจ้งว่าโอนเงินแล้ว หรือยกเลิกการจองเอง |
voucher.used | โค้ด Wi-Fi ถูกใช้ครั้งแรก (ไม่ส่งตัวโค้ด มี note ที่ใส่ตอนออกโค้ด เช่น เลขห้อง) |
guest.signed_in | ผู้ใช้กรอกอีเมลหรือเบอร์โทรที่หน้าล็อกอิน (returning บอกว่าเคยมาแล้วหรือไม่) |
box.offline, box.online | กล่อง Wi-Fi ขาดการติดต่อเกิน 2 นาที และเมื่อกลับมาออนไลน์ |
แต่ละเหตุการณ์ส่งเป็น POST แบบ JSON ระบบของคุณต้องตอบ 2xx ภายใน 10 วินาที ถ้าไม่ตอบ ระบบส่งซ้ำอัตโนมัติ (ห่างขึ้นเรื่อย ๆ จนถึงประมาณหนึ่งวัน) ดูประวัติการส่งได้ที่ปุ่ม ประวัติการส่ง
{"id":"evt_…","type":"order.created","createdAt":"2026-10-13T09:30:00Z","shopId":"…","data":{…}}ตรวจว่า Webhook มาจากเราจริง
ทุกครั้งมี header X-TH-Signature: t=<เวลา>,v1=<ลายเซ็น> ลายเซ็นคือ HMAC-SHA256 ของ <เวลา>.<body> ด้วย Signing secret ของคุณ ให้คำนวณจาก body ดิบที่ได้รับ ก่อนแปลงเป็น JSON
const crypto = require("crypto");
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map(p => p.split("=")));
const mac = crypto.createHmac("sha256", secret).update(parts.t + "." + rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(parts.v1));
}import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
mac = hmac.new(secret.encode(), parts["t"].encode() + b"." + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, parts["v1"])เหตุการณ์อาจมาถึงไม่ตรงลำดับ ให้เรียงตาม createdAt และใช้ id กันการประมวลผลซ้ำ เพราะเหตุการณ์เดิมอาจถูกส่งซ้ำได้
ถ้าเจอปัญหา
เพิ่ม Webhook แล้วขึ้นว่า URL ต้องเป็นที่อยู่บนอินเทอร์เน็ต
ใช้ URL แบบ https:// ที่เปิดจากภายนอกได้ ไม่ใช่ IP ภายใน หรือ localhost
ประวัติการส่งขึ้น “ส่งไม่สำเร็จ”
ดูรหัส HTTP ที่ URL ของคุณตอบ ระบบส่งซ้ำให้เองจนกว่าจะสำเร็จหรือครบรอบ แก้ฝั่งรับแล้วกด ทดสอบ เพื่อเช็ก