Webhook
Nhận sự kiện kích hoạt tại máy chủ theo thời gian thực, xác minh header SmsGrab-Signature và hiểu cơ chế thử lại, gửi thử và tự động tắt.
Trên trang này
Webhook gửi sự kiện đến máy chủ của bạn ngay khi chúng xảy ra, nên bạn không cần hỏi liên tục. Mỗi webhook thuộc về một khóa API. Nó nhận sự kiện của các số mua bằng khóa đó, cùng cảnh báo số dư thấp của tài khoản.
Sự kiện
| Sự kiện | Khi nào |
|---|---|
activation.created |
Đã mua một số |
activation.code_received |
Mỗi SMS mới, kèm mọi tin nhắn tính đến lúc đó |
activation.completed |
Bạn đã hoàn tất, hoặc hết giờ sau khi có mã |
activation.cancelled |
Hủy trước khi có mã, đã hoàn tiền |
activation.expired |
Không có mã kịp lúc, đã hoàn tiền |
activation.refunded |
Bất kỳ khoản hoàn nào của khoản trừ |
balance.low |
Số dư xuống dưới ngưỡng bạn đặt |
webhook.test |
Một lần gửi thử do bạn khởi tạo |
Tạo webhook
Trong Tài khoản > Nhà phát triển, mở một khóa và thêm webhook với URL, các sự kiện bạn muốn và mô tả tùy chọn. Mỗi khóa có tối đa 3 webhook.
URL phải:
- bắt đầu bằng
https://; - dùng tên máy chủ, không dùng địa chỉ IP;
- dẫn đến địa chỉ công khai. Mạng riêng, localhost và các dải tương tự bị từ chối.
Bạn nhận một bí mật ký bắt đầu bằng whsec_. Giống khóa API, bí mật chỉ hiển thị một lần. Bạn có thể đổi sau, việc này cũng yêu cầu mật khẩu.
Một lần gửi trông thế nào
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" } } }
Xác minh chữ ký
SmsGrab-Signature chứa dấu thời gian t và v1, là HMAC-SHA256 của t, một dấu chấm và thân yêu cầu thô, với khóa là bí mật của bạn. Hãy từ chối các lần gửi có dấu thời gian lệch quá 300 giây so với đồng hồ của bạn, và so sánh chữ ký trong thời gian cố định.
[$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);
}
Luôn kiểm tra thân yêu cầu thô đúng như khi nhận, trước khi phân tích JSON.
Trả lời nhanh
Trả lời bằng bất kỳ trạng thái 2xx nào trong 10 giây và làm phần việc chậm sau đó, ví dụ trong hàng đợi. Chuyển hướng không được theo dõi.
Thử lại
Lần gửi thất bại sẽ được thử lại sau 1 phút, 5 phút, 15 phút, 1 giờ, 3 giờ, 6 giờ, 12 giờ và 24 giờ. Lần thử lại giữ nguyên id của sự kiện, nên hãy nhớ các id đã xử lý và bỏ qua bản trùng. Sự kiện của một lượt kích hoạt đến theo thứ tự.
Tự động tắt
- Trả lời
410 Gonesẽ tắt webhook ngay. - Sau 50 lần thất bại liên tiếp trong ít nhất 24 giờ, webhook bị tắt và bạn nhận thông báo. Hãy sửa endpoint rồi bật lại webhook.
- Thu hồi khóa sẽ tắt các webhook của khóa đó.
Gửi thử và gửi lại
Gửi sự kiện webhook.test từ trang của webhook để xem ngay mã trạng thái, thời gian phản hồi và mọi lỗi. Danh sách gửi lưu mỗi lần gửi trong 30 ngày, và bạn có thể gửi lại bất kỳ lần nào.
Bài viết này có hữu ích không?
Cảm ơn! Rất vui vì bài viết hữu ích.