Cấu trúc Webhook Events, JSON Payload & Chữ ký HMAC
Bài viết này cung cấp cấu trúc dữ liệu JSON Payload của các sự kiện Webhook mà TrolyPage gửi tới URL Callback của bạn khi có biến động dữ liệu thời gian thực — kèm cách xác thực chữ ký HMAC để đảm bảo request thực sự đến từ TrolyPage.
1. Đăng ký Webhook URL
Phần tiêu đề “1. Đăng ký Webhook URL”Để nhận sự kiện, bạn cần cho TrolyPage biết callback URL của bạn và chọn sự kiện muốn nhận («cần xác nhận UI/endpoint đăng ký»):
- Tạo endpoint HTTPS công khai trên server của bạn (vd
https://api.yourshop.com/trolypage-webhook). - Đăng ký URL này + chọn event trong trang cấu hình webhook của TrolyPage (hoặc qua Developer API nếu có endpoint cấu hình).
- Lấy Webhook Signing Secret (bí mật dùng ký chữ ký — xem mục 5).
- Server của bạn phải phản hồi
HTTP 200trong 5 giây cho mọi POST từ TrolyPage.
2. Sự kiện Tin nhắn mới đến (message_received)
Phần tiêu đề “2. Sự kiện Tin nhắn mới đến (message_received)”Bắn ra khi có tin nhắn mới từ khách hàng gửi tới Facebook Messenger, Zalo OA hoặc Zalo Personal:
{ "event": "message_received", "timestamp": 1774889400, "tenant_id": 1042, "data": { "message_id": "msg_9f8a7b6c5d4e", "channel": { "type": "facebook_msg", "id": "page_123456789" }, "customer": { "id": 8520, "name": "Nguyễn Văn A", "phone": "0912345678", "avatar_url": "https://graph.facebook.com/12345/picture" }, "content": { "text": "Sản phẩm A giá bao nhiêu tiền shop?", "attachments": [] }, "ai_handled": true }}3. Sự kiện Đơn hàng cập nhật (order_updated)
Phần tiêu đề “3. Sự kiện Đơn hàng cập nhật (order_updated)”Bắn ra khi đơn hàng đổi trạng thái (pending → confirmed → shipping → completed):
{ "event": "order_updated", "timestamp": 1774889450, "tenant_id": 1042, "data": { "order_id": "DH-9821", "status": "confirmed", "total_amount": 350000, "currency": "VND", "payment_status": "paid", "customer": { "id": 8520, "name": "Nguyễn Văn A", "phone": "0912345678" }, "items": [ { "product_id": 101, "product_name": "Áo thun Polo Cotton", "quantity": 1, "price": 350000 } ] }}4. Sự kiện Thanh toán thành công (payment_completed)
Phần tiêu đề “4. Sự kiện Thanh toán thành công (payment_completed)”Bắn ra khi hệ thống SePay / VietQR khớp mã đối soát tiền nộp ~0.5s:
{ "event": "payment_completed", "timestamp": 1774889452, "tenant_id": 1042, "data": { "transaction_id": "sp_tx_881923", "order_id": "DH-9821", "gateway": "sepay_vcb", "amount_received": 350000, "reference_code": "DH9821", "status": "success" }}5. Xác thực chữ ký Webhook (HMAC) — BẮT BUỘC
Phần tiêu đề “5. Xác thực chữ ký Webhook (HMAC) — BẮT BUỘC”Mọi POST từ TrolyPage kèm header chứa chữ ký HMAC-SHA256 của body, ký bằng Webhook Signing Secret của bạn. Bạn phải verify trước khi xử lý để tránh request giả mạo.
Header chữ ký («cần xác nhận tên header + format»):
X-TrolyPage-Signature: sha256=75739d26e89c... # HMAC-SHA256 của raw bodyVerify bằng Node.js:
import crypto from "node:crypto";
function verifyTrolyPageWebhook(rawBody, signatureHeader, signingSecret) { const expected = crypto .createHmac("sha256", signingSecret) .update(rawBody, "utf8") .digest("hex"); const received = signatureHeader.replace(/^sha256=/, ""); // Dùng timingSafeEqual để chống timing attack const a = Buffer.from(expected, "hex"); const b = Buffer.from(received, "hex"); return a.length === b.length && crypto.timingSafeEqual(a, b);}Verify bằng PHP:
function verifyTrolyPageWebhook(string $rawBody, string $signatureHeader, string $signingSecret): bool { $expected = hash_hmac('sha256', $rawBody, $signingSecret); $received = preg_replace('/^sha256=/', '', $signatureHeader); return hash_equals($expected, $received); // hash_equals chống timing attack}6. Yêu cầu phản hồi HTTP 200 & Retry Schedule
Phần tiêu đề “6. Yêu cầu phản hồi HTTP 200 & Retry Schedule”- Máy chủ của bạn phải trả
HTTP 200 OKtrong vòng 5 giây. - Nếu trả mã lỗi (
4xx/5xx) hoặc timeout > 5s → sự kiện vào Retry Queue với Exponential Backoff.
Lịch retry dự kiến («cần xác nhận số chính xác»):
| Lần thử | Độ trễ sau lần trước |
|---|---|
| 1 (retry đầu) | ~1 phút |
| 2 | ~5 phút |
| 3 | ~30 phút |
| 4 | ~2 giờ |
| 5 (cuối) | ~12 giờ |
Sau ~24 giờ vẫn fail → sự kiện vào Dead-letter («cần xác nhận có DLQ + cách xem/khôi phục») và TrolyPage báo qua Trung tâm thông báo.
Bài viết liên quan
Phần tiêu đề “Bài viết liên quan”- Developer API Reference — REST API (Customers/Orders/Messages).
- Troubleshooting Webhook — Khắc phục lỗi webhook (trễ tin, 401, verify token).
- Tích hợp Zapier & Webhook — Tự động hóa No-code.
