On every inbound request, extract the raw body before any JSON parsing and compute HMAC-SHA256 using your app's client secret as the key; compare the base64-encoded result to the `X-Shopify-Hmac-SHA256` header value using a constant-time comparison.
Immediately return HTTP 200 to Shopify before processing; Shopify retries deliveries that do not receive a 2xx within its timeout window, which can cause duplicates.
Deduplicate by storing the `X-Shopify-Webhook-Id` header value in a cache or database; skip processing if the ID already exists, and use `X-Shopify-Event-Id` to correlate events from the same merchant action.
Enqueue verified, deduplicated payloads to an internal queue (e.g., SQS, Pub/Sub) for asynchronous processing so your endpoint stays fast.
Implement a reconciliation job that periodically polls Shopify REST/GraphQL APIs for the relevant resource (orders, products, inventory) to fill gaps caused by missed or dropped webhooks.
Monitor webhook delivery health via the `webhookSubscription` query's `endpoint.callbackUrl` and the Partner Dashboard event logs; set up alerts for sustained non-2xx response rates.
Known gotchas
Using a body-parser middleware (e.g., express.json()) before HMAC verification will consume the raw body, making the signature check always fail; read the raw buffer first.
Shopify's built-in deduplication fires at most one webhook per resource per 10-second window for high-frequency events — your system may still see bursts during that window, so idempotent processing is required.
Webhook subscriptions created via the API require active re-registration if the app is uninstalled and reinstalled; do not assume persistent subscriptions survive reinstalls.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp