hooks.bot Docs / Shopify

Shopify webhook signature verification

Shopify signs each webhook and sends the digest in X-Shopify-Hmac-Sha256. When your check fails, one of a small number of steps is wrong — and guessing which is the slow way to find out. Paste the payload, the secret and the header block into the debugger and it rebuilds the signature every way it could plausibly have been made, then names the step that differs. It runs in your browser: the secret never leaves the page.

The scheme

Exactly what Shopify signs

FieldValue
HeaderX-Shopify-Hmac-Sha256
Signed stringraw body
AlgorithmHMAC-SHA-256
Digest encodingbase64
KeyYour app's client secret (API secret key) — not the API key, not an access token.
Replay windownot timestamped

Official reference: https://shopify.dev/docs/apps/build/webhooks/subscribe/https#verify-the-webhook.

Causes

What actually goes wrong

Stripe and Svix both issue secrets that begin whsec_ and derive keys from them completely differently. Stripe uses the whole string, prefix included. Svix and Standard Webhooks strip the prefix and base64-decode the rest. This is the single commonest failure in the category.

Capture it

Get the real bytes, not a copy of a copy

If you are diagnosing from a logged payload you may be debugging the log rather than the webhook. Point Shopify at a disposable URL and work from what actually arrived:

curl -X POST https://www.hooks.bot/api/endpoints
# {"url":"https://www.hooks.bot/h/abc…"}

Paste that URL into your Shopify webhook settings, trigger an event, and the request appears at https://www.hooks.bot the moment it lands — headers, body and all. Press Diagnose this signature and add your secret.

Or let your agent do it

claude mcp add --transport http hooks-bot https://www.hooks.bot/mcp

Claude Code, Cursor and Codex can create the endpoint, block until the webhook lands, and diagnose it against the captured bytes without you copying anything.

Other providers

Stripe · GitHub · Svix / Standard Webhooks · Slack · Paddle Billing · Twilio