
Shopify fires webhooks for orders, products, customers, fulfillments, refunds, app lifecycle, and dozens of other store events. They're how integrations stay in sync with what's happening in a Shopify store without polling the API.
This guide covers what Shopify sends, how to verify it, and what production reliability requires beyond a basic handler — including the failure mode that silently kills your integration.
What Shopify sends
Shopify webhooks are JSON POSTs. An orders/paid event:
{
"id": 820982911946154508,
"email": "customer@example.com",
"created_at": "2026-04-24T14:30:00Z",
"currency": "USD",
"current_total_price": "29.99",
"financial_status": "paid",
"fulfillment_status": null,
"line_items": [
{ "id": 866550311766439020, "title": "T-Shirt", "quantity": 1, "price": "29.99" }
],
"customer": { "id": 115310627314723954, "email": "customer@example.com" }
}
The metadata is in headers, not the body:
X-Shopify-Topic: orders/paid
X-Shopify-Hmac-SHA256: <base64 signature>
X-Shopify-Shop-Domain: yourshop.myshopify.com
X-Shopify-API-Version: 2025-01
X-Shopify-Webhook-Id: 12345678-abcd-1234-abcd-1234567890ab
Shopify has 100+ webhook topics. Subscribe only to the ones your integration needs — fewer events means simpler handling.
Shopify's signature scheme
The signature is HMAC-SHA256 of the raw body using the webhook secret, base64-encoded:
X-Shopify-Hmac-SHA256: 5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd=
Verification:
- Read the raw body before any JSON parsing
- Compute
base64(HMAC-SHA256(secret, raw_body)) - Compare constant-time with the header value
There's no timestamp in the signature, so replay protection is your job — use the X-Shopify-Webhook-Id UUID for idempotency.
Shopify's retry policy (and the silent-removal trap)
Shopify retries failed webhook calls up to eight times over roughly four hours. This is useful, but it still has a hard cutoff.
The trap: if Shopify's retries fail too many times in a row to the same endpoint, Shopify will automatically remove the webhook subscription. Silent failure cascades into silent loss of integration. You have to monitor for it; Shopify won't tell you.
This means:
- Acknowledge fast. 5-second budget; do real work async.
- Be idempotent on
X-Shopify-Webhook-Id— duplicates will arrive during retries. - Monitor delivery success. If too many fail in a row, your subscription disappears without warning.
- Have a recovery story for events that exhaust Shopify's retry window.
DIY: minimal Shopify webhook handler in Node
import { createHmac, timingSafeEqual } from 'crypto'
const secret = process.env.SHOPIFY_WEBHOOK_SECRET!
export async function POST(req: Request) {
const sig = req.headers.get('x-shopify-hmac-sha256')!
const topic = req.headers.get('x-shopify-topic')!
const webhookId = req.headers.get('x-shopify-webhook-id')!
const body = await req.text()
const expected = createHmac('sha256', secret).update(body).digest('base64')
if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return new Response('Bad signature', { status: 401 })
}
// Idempotency on `webhookId`
// ...
const payload = JSON.parse(body)
queueWork(topic, payload)
return new Response('ok', { status: 200 })
}
Production needs more:
- A persistence layer for the
X-Shopify-Webhook-Ididempotency check - A queue for async work (5-second budget)
- A retry policy when
queueWorkfails - A replay path for events older than Shopify's retry window
- Monitoring that warns before Shopify silently unsubscribes you
- Filtering — large stores produce huge volumes of low-value events
- Multi-shop support — one signing secret per shop in a multi-tenant app
Hooksbase: receive Shopify webhooks without rebuilding the rest
Shopify isn't one of Hooksbase's five pre-verified provider packs (Stripe, GitHub, Clerk, Slack, Resend), and Hooksbase does not forward Shopify's original HMAC headers to your destination. If you need Shopify HMAC verification, verify it in a small pre-ingest forwarder, then post the verified raw body to Hooksbase with the bearer ingest secret.
Setup:
- Create a webhook in Hooksbase with your application URL as the destination
- Configure Shopify to send to your verification forwarder
- In the forwarder, verify
X-Shopify-Hmac-SHA256, then POST the same raw body to the Hooksbase ingest URL withAuthorization: Bearer <ingest secret>
You get:
- Idempotency for your destination — every dispatch includes a unique
webhook-idheader (Standard Webhooks-compatible) you can dedupe on across retries. If your handler needs Shopify's webhook ID, include it in the forwarded payload or verify/store it in the pre-ingest forwarder. - Retries with exponential backoff to your endpoint after Hooksbase accepts the event
- Acknowledge in milliseconds to Shopify regardless of how slow your downstream is — you don't lose the subscription to slow handlers
- Routing rules by
X-Shopify-Topicduring ingest — sendorders/paidto one destination,customers/createto another - Payload transforms — extract just the fields your downstream needs
- Deterministic replay — re-run a failed delivery with the same payload bytes while the payload is retained
- Delivery history and DLQ
- Failure-spike alerts (Pro+) — get warned when downstream delivery starts failing
Common Shopify webhook use cases for AI agents
- Order fulfillment agent —
orders/paidevents trigger an agent that decides fulfillment routing (warehouse, dropship, digital), updates the inventory system, and emails the customer - Refund triage agent —
refunds/createevents trigger an agent that classifies the refund reason and flags patterns for the merch team - Inventory alerting agent —
products/updateevents with low inventory trigger an agent that checks reorder rules and pings the buyer - Customer reactivation agent —
customers/createevents trigger an agent that enriches the profile and schedules a personalized welcome flow - App lifecycle agent —
app/uninstalledevents trigger an agent that runs your offboarding flow (data export, refund prorate, churn survey)
Where to go next
- How to receive Stripe webhooks reliably
- How to receive GitHub webhooks reliably
- Recover failed agent events for DLQ patterns
- How to build an AI agent
Start free at app.hooksbase.com.