Cách Shopify gửi webhook

Năm giây để phản hồi, 8 lần thử lại trong 4 giờ, rồi Shopify xóa subscription. Số liệu đã kiểm chứng, định dạng chữ ký và code xác minh Node.

Hành vi gửi

Lấy từ tài liệu của chính hãng, kiểm tra lần cuối 2026-08-06. Hãng không nêu con số nào thì bảng này cũng không ghi.

Thời hạn phản hồi5 giây

1 giây để kết nối, 5 giây cho toàn bộ request

Kiểm tra handler của bạn có phản hồi kịp không

Thử lại8 lần thử lại trong 4 giờ
Ngừng gửiSubscription tạo qua Admin API bị xóa sau 8 lần thất bại liên tiếp, kèm email cảnh báo gửi tới liên hệ developer khẩn cấp của app
Nguồnhttps://shopify.dev/docs/apps/build/webhooks/subscribe/https

Chữ ký

Kiểm chứng bằng một bộ xác minh chạy thật, có bộ test chứng minh, chứ không đọc từ tài liệu. Kiểm chứng lần cuối 2026-08-20.

Thuật toánHMAC-SHA256
Payload được kýraw body
Encodingbase64
Headerx-shopify-hmac-sha256
Dung saikhông quy định

Xác minh

Dùng raw body của request, đúng từng byte, trước mọi bước parse JSON. Mọi cơ chế trên trang này đều hỏng ngay khi framework serialize lại payload.

const crypto = require("node:crypto");

// base64(HMAC-SHA256(secret, raw body))
const expected = crypto
  .createHmac("sha256", hmacSecret) // admin webhooks: Settings → Notifications
  .update(rawBody)
  .digest("base64");
const received = Buffer.from(req.headers["x-shopify-hmac-sha256"] ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
  received.length === wanted.length && crypto.timingSafeEqual(received, wanted);

Có hai secret khác nhau: webhook tạo trong admin được ký bằng shared secret ở Settings → Notifications, webhook do app tạo được ký bằng client secret của app. Chọn secret khớp với cách webhook được tạo.

Những chỗ dễ vấp

Shopify không vô hiệu hóa subscription mà xóa hẳn. Subscription tạo qua Admin API bị xóa sau 8 lần thất bại liên tiếp, chỉ có một email cảnh báo gửi tới liên hệ khẩn cấp cho developer của app; không có lỗi nào được ném ra, và đơn hàng cứ thế ngừng tới. Muốn khôi phục phải chạy một job đối soát với Admin API, vì các sự kiện bị lỡ chưa từng được gửi.

Đọc thêm

AnyHook đứng trước các endpoint nhận webhook từ Shopify: trả lời sau khoảng 1 giây, tự thử lại theo lịch riêng khi server của bạn ngừng hoạt động, và giữ mọi sự kiện để bạn phát lại được. Đổi một URL, giữ nguyên code.

Cách hoạt động →