Shopify Webhooks: The Complete Guide to Event-Driven App Architecture
Webhooks are the backbone of every production Shopify app. Learn how to register, verify, handle, and retry webhooks — with real patterns from apps serving thousands of stores.
If your Shopify app only uses HTTP requests (loaders and actions), you're missing half the picture. Webhooks are how Shopify tells your app about events: new orders, product updates, app uninstalls, and GDPR compliance requests. They're the difference between an app that polls for changes and one that reacts in real-time. Let's walk through the complete webhook architecture.
How Webhooks Work
When an event occurs in a merchant's store (e.g., an order is created), Shopify sends an HTTP POST request to your app's webhook endpoint with the event data as JSON. The request includes headers for verification: X-Shopify-Hmac-SHA256 (a signature you must verify), X-Shopify-Topic (the event type), and X-Shopify-Shop-Domain (which store triggered it). Your endpoint must respond with 200 OK within 5 seconds — if it doesn't, Shopify considers the delivery failed and will retry.
Registering Webhooks
There are two ways to register webhooks: via the shopify.app.toml configuration file (recommended) or via the GraphQL Admin API. The toml approach is simpler — you declare your topics and endpoint, and the Shopify CLI handles registration during app deploy. The API approach gives you more control but requires manual management. In ShopForge, we use the toml approach combined with a webhook registry pattern that auto-configures subscriptions from your registered handlers.
The Registry Pattern
Instead of scattering webhook handlers across your codebase, the registry pattern centralizes them. Developers register handlers with a single line: webhookRegistry.on('ORDERS_CREATE', handler). The registry then handles dispatching, retry, and error isolation. Built-in handlers for critical webhooks (APP_UNINSTALLED, APP_SUBSCRIPTIONS_UPDATE, GDPR topics) are pre-registered. This means adding a new webhook handler never requires touching the webhook route or understanding Shopify's webhook mechanics.
Retry and Error Handling
Webhooks can fail for many reasons: your server was deploying, the database was temporarily unavailable, or a third-party API timed out. Shopify retries failed webhooks with exponential backoff (up to 19 attempts over 48 hours). But you should also implement your own retry logic for transient failures. ShopForge's webhook registry includes automatic retry with configurable max retries and exponential backoff. If a handler fails after all retries, the error is logged but other handlers for the same topic continue executing — one failing handler doesn't block the rest.
The Three GDPR Webhooks You Cannot Skip
Shopify requires all apps to handle three mandatory webhooks: CUSTOMERS_DATA_REQUEST (a customer asks what data you store about them), CUSTOMERS_REDACT (a customer asks you to delete their data), and SHOP_REDACT (a shop uninstalls your app — you must delete ALL data). These are non-negotiable for App Store approval. SHOP_REDACT is the most critical — it requires hard-deleting all shop data including sessions, orders, and any stored information. There's no grace period. The ShopForge scaffold includes working GDPR handlers that you can extend if your app stores customer PII.
Webhook Security
Every webhook request includes an HMAC signature in the X-Shopify-Hmac-SHA256 header. You MUST verify this signature using your API secret before processing the webhook. Without verification, anyone can send fake webhook requests to your endpoint. The verification process: compute HMAC-SHA256 of the raw request body using your API secret, base64-encode it, and compare with the header value. ShopForge's webhook route handles this verification automatically — handlers only receive verified payloads.