HookShield
Start monitoring

SHOPIFY WEBHOOKS

HMAC mismatch

Shopify webhook HMAC verification failing — valid events rejected

Shopify signs every delivery with X-Shopify-Hmac-Sha256. If your verification fails — wrong secret, mutated body, encoding issues — every real event gets rejected while Shopify counts the delivery as "responded to."

Why Shopify webhooks fail silently

Body parsing before verification

HMAC covers the raw bytes. If your framework JSON-parses or re-serializes the body first, the signature never matches.

Wrong secret for the webhook source

App-created webhooks verify with the app’s API secret; admin-created webhooks use a different credential. Mixing them fails every time.

Base64 comparison bugs

Comparing raw HMAC output to the base64 header without encoding — or using strict equality instead of timing-safe compare — produces false rejections.

The fix

  1. 1

    Verify the raw request body

    Hash the unparsed body with your secret, base64-encode, and compare to X-Shopify-Hmac-Sha256 using a timing-safe comparison.

  2. 2

    Use the right credential

    App webhooks → your app’s API secret key. Admin-panel webhooks → the credential shown when the webhook was created.

  3. 3

    Log rejections separately from errors

    A 401 from failed verification should page differently than a 500 — it means traffic is flowing but being thrown away.

  4. 4

    Record every attempt

    HookShield logs each delivery attempt and your target’s response — a wall of 401s on the dashboard beats finding out from a merchant.

DEAD-MAN'S SWITCH

Never find out about a dead webhook from a customer again

Point Shopify at a HookShield ingest URL. Every delivery is logged, signed, and forwarded — and if pings stop arriving, you're alerted before the silence becomes an incident.

More Shopify webhook fixes