Shopify Webhooks
Shopify webhooks notify your app when shop data changes: orders, products, customers, fulfillment, inventory, app lifecycle events, and compliance workflows. They are useful, but they need fast acknowledgement, HMAC verification, duplicate handling, and a clear replay process.
FastHook can sit between Shopify and your internal services so the source accepts traffic, records headers and payloads, routes only relevant topics, retries temporary destination failures, and lets you replay safely after an outage.
Common Shopify webhook headers
| Header | Example | Use |
|---|---|---|
X-Shopify-Topic | orders/create | Route by webhook topic. |
X-Shopify-Shop-Domain | cool-store.myshopify.com | Separate traffic by merchant shop. |
X-Shopify-Hmac-SHA256 | <base64-hmac> | Verify the raw request body with the app client secret. |
X-Shopify-Webhook-Id | b54557e4-bdd9-4b37-8a5f-bf7d70bcd043 | Deduplicate one delivery. |
X-Shopify-Event-Id | 7b8c9d0a-1234-5678-90ab-cdef12345678 | Correlate deliveries from the same merchant action. |
X-Shopify-API-Version | 2026-04 | Track the API version used for the subscription. |
Shopify order webhook payload example
Order payloads can be large. Keep your first route focused on fields the destination actually needs, then inspect full payloads in FastHook when a handler behaves unexpectedly.
{
"id": 549755813,
"admin_graphql_api_id": "gid://shopify/Order/549755813",
"name": "#1001",
"email": "customer@example.com",
"currency": "USD",
"total_price": "49.00",
"financial_status": "paid",
"fulfillment_status": null,
"customer": {
"id": 207119551,
"email": "customer@example.com"
},
"line_items": [
{
"id": 466157049,
"title": "Webhook Reliability Hoodie",
"quantity": 1,
"price": "49.00"
}
]
}FastHook source for Shopify
Shopify HTTPS deliveries use a base64 HMAC-SHA256 signature over the raw request body. If you verify at the application layer, keep FastHook source auth open and validate before processing. If you verify at the source, configure the source with the same signing material your receiver would use.
curl -X POST "https://api.fasthook.io/v1/sources" \
-H "Authorization: Bearer fhp_xxx" \
-H "x-team-id: tm_3b5335b627084a838b" \
-H "Content-Type: application/json" \
-d '{
"name": "Shopify orders",
"description": "Shopify order and fulfillment webhook source",
"type": "WEBHOOK",
"status": "enabled",
"config": {
"auth_type": null,
"auth": null,
"allowed_http_methods": ["POST"]
}
}'Filter Shopify topics
Shopify topic headers are the cleanest first routing boundary. Use separate connections for billing, order, fulfillment, product catalog, and compliance workflows when they have different owners or replay risk.
{
"type": "filter",
"headers": {
"x-shopify-topic": {
"$in": [
"orders/create",
"orders/updated",
"orders/paid"
]
}
}
}Duplicate and retry handling
- Store
X-Shopify-Webhook-Idto deduplicate individual deliveries. - Use
X-Shopify-Event-Idto correlate deliveries from the same merchant action. - Return a 2xx response quickly and move slow work to a queue or downstream worker.
- Make order, fulfillment, inventory, and customer handlers idempotent before enabling replay.
- Use FastHook retries for temporary destination failures after Shopify ingress has already been accepted.
Debugging workflow
- Open the FastHook request and confirm topic, shop domain, HMAC header, and webhook ID.
- Check whether the destination failure is timeout, 4xx schema issue, or temporary 5xx response.
- Pause only the affected connection if a downstream service is unsafe.
- Fix the receiver, confirm idempotency, then retry the failed FastHook events.
Shopify documentation notes
Shopify documents HMAC verification, duplicate handling, response timing, and retry behavior in its verify webhook deliveries guide, and covers subscription management in managing webhook subscriptions.