Delivery behaviour
Read from the vendor's own documentation, last checked 2026-08-06. Where the vendor states no number, this table carries none.
| Response budget | 5s |
|---|---|
| Retry | 8 attempts over 4 hours |
| Gives up | Subscription deleted after repeated failures within a 24-hour period |
| Source | https://shopify.dev/docs/apps/build/webhooks/troubleshooting-webhooks |
Signature
Verified against a working verifier proven by a test suite, not read from documentation. Last verified 2026-08-20.
| Algorithm | HMAC-SHA256 |
|---|---|
| Signed payload | raw body |
| Encoding | base64 |
| Header | x-shopify-hmac-sha256 |
| Tolerance | none enforced |
Verify it
The raw request body, byte for byte, before any JSON parsing. Every scheme on this page breaks the moment a framework re-serializes the 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 valid = crypto.timingSafeEqual(
Buffer.from(req.headers["x-shopify-hmac-sha256"]),
Buffer.from(expected),
);Two different secrets exist: admin-created webhooks sign with the shared secret under Settings → Notifications, app-created ones with the app's client secret. Match how the webhook was created.
What bites
Shopify does not disable the subscription, it deletes it. After repeated failures within 24 hours the webhook is gone, nothing throws, and orders simply stop arriving. Recovery is a reconciliation job against the Admin API, because the missed events were never sent.
Read more
AnyHook sits in front of endpoints that receive from Shopify: it answers inside the budget above, retries on its own schedule when your server is down, and keeps every event replayable. Change one URL, keep your code.