Providers / April 24, 2026

How to receive Shopify webhooks reliably (orders, products, customers)

Shopify webhook delivery flow with topic routing and HMAC verification

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:

  1. Read the raw body before any JSON parsing
  2. Compute base64(HMAC-SHA256(secret, raw_body))
  3. 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-Id idempotency check
  • A queue for async work (5-second budget)
  • A retry policy when queueWork fails
  • 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:

  1. Create a webhook in Hooksbase with your application URL as the destination
  2. Configure Shopify to send to your verification forwarder
  3. In the forwarder, verify X-Shopify-Hmac-SHA256, then POST the same raw body to the Hooksbase ingest URL with Authorization: Bearer <ingest secret>

You get:

  • Idempotency for your destination — every dispatch includes a unique webhook-id header (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-Topic during ingest — send orders/paid to one destination, customers/create to 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 agentorders/paid events trigger an agent that decides fulfillment routing (warehouse, dropship, digital), updates the inventory system, and emails the customer
  • Refund triage agentrefunds/create events trigger an agent that classifies the refund reason and flags patterns for the merch team
  • Inventory alerting agentproducts/update events with low inventory trigger an agent that checks reorder rules and pings the buyer
  • Customer reactivation agentcustomers/create events trigger an agent that enriches the profile and schedules a personalized welcome flow
  • App lifecycle agentapp/uninstalled events trigger an agent that runs your offboarding flow (data export, refund prorate, churn survey)

Where to go next

Start free at app.hooksbase.com.

Related guides