Debug Shopify webhooks locally

Guides / Providers

Shopify signs webhooks with X-Shopify-Hmac-Sha256, a base64 HMAC-SHA256 of the raw body using your app's client secret. There is no timestamp, so an exact replay of a captured Shopify webhook still carries a valid signature.

Receive Shopify webhooks on localhost

hwcli listen shop-events --forward :3000/webhooks/shopify --include-sensitive --append-path

Register the endpoint URL for each topic in your app's configuration or with the Admin API. With --append-path, a URL like …/<endpoint>/orders/create is delivered to localhost:3000/webhooks/shopify/orders/create. HookWatcher recognizes Shopify requests from their X-Shopify-Topic, X-Shopify-Shop-Domain and X-Shopify-Webhook-Id headers and labels them with the topic.

Replay orders

hwcli replay evt_7be20c11                      # exact, signature still valid
hwcli replay evt_7be20c11 --duplicate 3        # Shopify retries up to 8 times
hwcli replay evt_c3 evt_a1 --target :3000/webhooks/shopify/orders/updated

Modifying the body invalidates the HMAC. HookWatcher can generate test signatures for Stripe and GitHub secrets, but not yet for Shopify, so test modified Shopify payloads with verification against a test secret, or use them to check your rejection path.

Things to test for Shopify

  • Duplicates: key on X-Shopify-Webhook-Id, which stays the same across retries of one delivery.
  • Ordering: orders/updated can arrive before orders/create. Compare updated_at before overwriting.
  • Response time: Shopify expects a response within 5 seconds. Every replay records how long your handler took.

Create an endpoint and capture your first webhook. No signup needed.

Start Free