Webhook
รับเหตุการณ์การเปิดใช้งานที่เซิร์ฟเวอร์แบบเรียลไทม์ ตรวจสอบส่วนหัว SmsGrab-Signature และทำความเข้าใจการลองใหม่ การส่งทดสอบ และการปิดอัตโนมัติ
ในหน้านี้
Webhook ส่งเหตุการณ์ไปยังเซิร์ฟเวอร์ของคุณทันทีที่เกิดขึ้น คุณจึงไม่ต้องคอยสอบถาม webhook หนึ่งตัวเป็นของคีย์ API หนึ่งคีย์ และรับเหตุการณ์ของหมายเลขที่ซื้อด้วยคีย์นั้น รวมถึงการแจ้งเตือนยอดเงินต่ำของบัญชี
เหตุการณ์
| เหตุการณ์ | เมื่อไร |
|---|---|
activation.created |
มีการซื้อหมายเลข |
activation.code_received |
ทุก SMS ใหม่ พร้อมข้อความทั้งหมดจนถึงตอนนั้น |
activation.completed |
คุณปิดงานเอง หรือหมดเวลาหลังได้รหัส |
activation.cancelled |
ยกเลิกก่อนได้รหัส คืนเงินแล้ว |
activation.expired |
ไม่มีรหัสทันเวลา คืนเงินแล้ว |
activation.refunded |
การคืนเงินใดๆ ของยอดที่หัก |
balance.low |
ยอดเงินต่ำกว่าเกณฑ์ที่คุณตั้งไว้ |
webhook.test |
การส่งทดสอบที่คุณเริ่มเอง |
สร้าง webhook
ใน บัญชี > นักพัฒนา เปิดคีย์แล้วเพิ่ม webhook พร้อม URL เหตุการณ์ที่ต้องการ และคำอธิบาย (ไม่บังคับ) คีย์แต่ละตัวมี webhook ได้สูงสุด 3 ตัว
URL ต้อง
- ขึ้นต้นด้วย
https:// - ใช้ชื่อโฮสต์ ไม่ใช่ที่อยู่ IP
- ชี้ไปยังที่อยู่สาธารณะ เครือข่ายส่วนตัว localhost และช่วงที่คล้ายกันจะถูกปฏิเสธ
คุณจะได้ความลับสำหรับการลงลายเซ็นที่ขึ้นต้นด้วย whsec_ ซึ่งแสดงครั้งเดียวเช่นเดียวกับคีย์ API คุณเปลี่ยนได้ภายหลัง ซึ่งต้องใช้รหัสผ่านเช่นกัน
หน้าตาของการส่ง
POST /your/endpoint HTTP/1.1
Content-Type: application/json
User-Agent: SmsGrab-Webhooks/1.0
SmsGrab-Event: activation.code_received
SmsGrab-Delivery: 9f7d6c1e-2b44-4c1a-8f0e-6a3d2c1b0e9f
SmsGrab-Signature: t=1790503200,v1=3b9a0c…
{ "id": "evt_4e1f…", "type": "activation.code_received", "created_at": "2026-09-27T10:06:12.004Z",
"api_version": "2026-09-27", "data": { "activation": { "id": "5c1d0c2e-…", "status": "CODE_RECEIVED" } } }
ตรวจสอบลายเซ็น
SmsGrab-Signature มีเวลาประทับ t และ v1 ซึ่งคือ HMAC-SHA256 ของ t จุด และเนื้อหาคำขอดิบ โดยใช้ความลับของคุณเป็นคีย์ ปฏิเสธการส่งที่เวลาประทับห่างจากนาฬิกาของคุณเกิน 300 วินาที และเปรียบเทียบลายเซ็นแบบเวลาคงที่
[$t, $v1] = (function (string $h): array {
parse_str(str_replace(',', '&', $h), $p);
return [(int) ($p['t'] ?? 0), (string) ($p['v1'] ?? '')];
})($_SERVER['HTTP_SMSGRAB_SIGNATURE'] ?? '');
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', $t.'.'.$body, getenv('SMSGRAB_WEBHOOK_SECRET'));
$ok = abs(time() - $t) <= 300 && hash_equals($expected, $v1);
import hmac, hashlib, time
def verify(header: str, body: bytes, secret: str) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts.get("t", "0"))
expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
return abs(time.time() - t) <= 300 and hmac.compare_digest(expected, parts.get("v1", ""))
import crypto from 'node:crypto';
export function verify(header, rawBody, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t ?? 0);
const expected = crypto.createHmac('sha256', secret).update(`${t}.`).update(rawBody).digest('hex');
const given = Buffer.from(parts.v1 ?? '', 'utf8');
return Math.abs(Date.now() / 1000 - t) <= 300 && given.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(expected, 'utf8'), given);
}
ตรวจสอบเนื้อหาดิบตามที่ได้รับทุกครั้ง ก่อนแยกวิเคราะห์ JSON
ตอบกลับให้เร็ว
ตอบด้วยสถานะ 2xx ใดก็ได้ภายใน 10 วินาที แล้วค่อยทำงานที่ใช้เวลานานภายหลัง เช่น ในคิว ระบบจะไม่ตามการเปลี่ยนเส้นทาง
การลองใหม่
การส่งที่ล้มเหลวจะลองใหม่หลัง 1 นาที 5 นาที 15 นาที 1 ชั่วโมง 3 ชั่วโมง 6 ชั่วโมง 12 ชั่วโมง และ 24 ชั่วโมง การลองใหม่ใช้ id ของเหตุการณ์เดิม จึงควรจำ id ที่ประมวลผลแล้วและข้ามรายการซ้ำ เหตุการณ์ของการเปิดใช้งานเดียวกันจะมาตามลำดับ
การปิดอัตโนมัติ
- การตอบ
410 Goneจะปิด webhook ทันที - หลังล้มเหลวติดกัน 50 ครั้งในช่วงอย่างน้อย 24 ชั่วโมง webhook จะถูกปิดและคุณจะได้รับการแจ้งเตือน แก้ endpoint แล้วเปิด webhook อีกครั้ง
- การเพิกถอนคีย์จะปิด webhook ของคีย์นั้น
ทดสอบและส่งซ้ำ
ส่งเหตุการณ์ webhook.test จากหน้าของ webhook เพื่อดูรหัสสถานะ เวลาตอบกลับ และข้อผิดพลาดได้ทันที รายการการส่งเก็บทุกการส่งไว้ 30 วัน และคุณส่งซ้ำรายการใดก็ได้
บทความนี้มีประโยชน์ไหม
ขอบคุณ ดีใจที่ช่วยได้