Shopify 如何傳遞 Webhook

回應時限五秒,4 小時內重試 8 次,之後 Shopify 會刪除訂閱。附經驗證的數字、簽章格式與 Node 驗證程式。

傳遞行為

取自服務商自己的文件,最後檢查於 2026-08-06。服務商沒寫數字的地方,這張表也不填。

回應時限5 秒

連線 1 秒,整個請求 5 秒

檢查你的處理程式能否及時回應

重試4 小時內重試 8 次
放棄透過 Admin API 建立的訂閱,連續失敗 8 次後會被刪除,並寄警告信給應用程式的緊急開發者聯絡人
出處https://shopify.dev/docs/apps/build/webhooks/subscribe/https

簽章

用一個經測試套件證明可運作的驗證程式核對過,不是照文件抄來的。最後驗證於 2026-08-20。

演算法HMAC-SHA256
簽章內容raw body
編碼base64
標頭x-shopify-hmac-sha256
容許時間差不強制

驗證簽章

要用原始請求主體(raw body),逐位元組原封不動,並在任何 JSON 解析之前取得。框架只要重新序列化 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);

有兩種不同的密鑰:在 Shopify 管理介面建立的 Webhook,用「設定 → 通知」(Settings → Notifications)底下的共用密鑰簽章;由應用程式建立的,用應用程式的用戶端密鑰簽章。依 Webhook 的建立方式選對密鑰。

容易踩的坑

Shopify 不是停用訂閱,而是直接刪除。透過 Admin API 建立的訂閱,連續失敗 8 次後就會被刪除,只寄一封警告信給 App 的緊急開發人員聯絡人;沒有任何錯誤拋出,訂單就這樣不再進來。復原只能靠對 Admin API 跑對帳作業,因為漏掉的事件從來沒有送出過。

延伸閱讀

AnyHook 架在接收 Shopify Webhook 的端點前面:大約 1 秒就回應,伺服器當機時依自己的排程重試,並讓每個事件都能重播。 換一個網址,程式碼不用動。

運作方式 →