Shopify orders webhook not firing
Shopify Orders Webhook Not Firing
Admaxxer is a DTC analytics platform with built-in Meta + Google ad ops. If Shopify order webhooks are not firing, Admaxxer cannot attribute revenue to ad spend and your blended MER, cohort LTV, and forecast pipes silently go wrong. TL;DR: verify the webhook subscriptions exist for `orders/create`, `orders/paid`, `orders/updated`, and `orders/refunded`; confirm HMAC verification on the receiving endpoint; and inspect Shopify's webhook delivery log for the last failed attempt.
## Symptoms
- Shopify purchases happen but revenue on the Admaxxer dashboard is $0 or dramatically undercounted.
- Attribution breakdown shows "direct / none" for known paid clicks because the purchase event never tied to a session.
- The Admaxxer connections page shows Shopify green (OAuth is fine) but the webhook health badge is amber or red.
- Shopify Admin -> Settings -> Notifications -> Webhooks lists fewer than four subscriptions for Admaxxer.
- Shopify's webhook delivery log shows 401, 403, or 5xx responses from your Admaxxer endpoint.
## Root cause
The Shopify install flow does two things: it finishes OAuth and it registers webhook subscriptions. Failures in either half break attribution. The common failure modes:
1. **Webhook registration silently failed** during install (network error, app scope change, Shopify rate-limiting the install flow).
2. **HMAC verification is rejecting the request** — either the webhook secret rotated on Shopify's side, or the body is being parsed before verification runs (Express needs the raw body to compute the HMAC).
3. **Outbound from Shopify is blocked** by a firewall, CDN rule, or staging environment that does not accept public traffic.
4. **The event exists but is filtered out** — test orders, draft orders, and orders with no line items are not always delivered on every topic.
## Fix
### Step 1: List current subscriptions
Shopify Admin -> Settings -> Notifications -> Webhooks. You should see four Admaxxer-owned webhooks: `orders/create`, `orders/paid`, `orders/updated`, `orders/refunded`. If any are missing, disconnect and reconnect Shopify from the Admaxxer connection card to re-register.
### Step 2: Inspect delivery attempts
In Shopify, click a webhook and open the delivery log. If you see consistent 401 responses, HMAC is failing. 5xx means the Admaxxer endpoint errored; copy the request id and check the Admaxxer logs.
### Step 3: Fix HMAC verification
Admaxxer verifies the `X-Shopify-Hmac-Sha256` header against the raw request body. If you introduced any middleware that parses JSON before the verification runs, the hash will not match. In Express, the webhook route must use a raw-body parser exclusively.
### Step 4: Re-test with a real order
Create a real-money test order (or a draft order that you then mark as paid). Shopify fires on paid transitions, not on draft creation, so a draft alone will not trigger `orders/paid`.
### Step 5: Check your firewall or CDN
If you run Admaxxer behind Cloudflare or similar, allow the Shopify webhook IP ranges or configure a bypass rule for the webhook endpoint. Shopify does not guarantee a stable source IP range, so a path-based rule is safer.
## Verify the fix
- Place a low-value live test order from a guest browser; in Admaxxer you should see the purchase show up in the realtime pane within about 60 seconds.
- Shopify webhook delivery log shows 200 OK for the latest delivery on all four topics.
- The order's revenue appears in the Admaxxer revenue pipe and is attributable to the UTM you arrived on (use `?utm_source=smoketest`).
- Blended MER drops slightly because the test order's spend is zero but revenue is non-zero — proving the revenue path is live.
## Prevent it next time
- **Monitor webhook health.** Admaxxer flags any connection whose webhook delivery success rate drops below 95% in a rolling 24 hour window.
- **Alert on webhook gaps.** Set an alert for "0 Shopify orders in 2 hours" during normal trading hours.
- **Do not share the webhook secret in logs.** If you ever paste it into a log line or ticket, rotate and reinstall.
- **Keep the app scope stable.** If you reduce Shopify scopes after install, webhooks tied to dropped scopes can go silent.
## Related guides
- [Verify revenue attribution after install](/guides/verify-revenue-attribution-after-install)
- [Duplicate payment events](/guides/duplicate-payment-events)
- [Shopify install guide](/documentation/install/shopify)
## FAQs
**Q: Do I need all four webhook topics?**
A: `orders/paid` is the minimum for revenue attribution. `orders/refunded` is required to subtract refunds from MER and LTV. `orders/create` and `orders/updated` help catch edge cases like post-hoc cancellation.
**Q: Will Shopify retry failed deliveries?**
A: Yes. Shopify retries failed webhooks for up to 48 hours with exponential backoff, then the webhook is removed and you must re-register.
**Q: Can I use the Shopify pixel instead of webhooks?**
A: The Admaxxer pixel captures client-side events, but server-side webhooks are authoritative for revenue because they survive ad blockers and client-side bounces.
Frequently Asked Questions
Do I need all four webhook topics?
orders/paid is the minimum for revenue attribution. orders/refunded is required to subtract refunds. orders/create and orders/updated help catch edge cases like post-hoc cancellation.
Will Shopify retry failed deliveries?
Yes. Shopify retries failed webhooks for up to 48 hours with exponential backoff, then the webhook is removed and you must re-register.
Can I use the Shopify pixel instead of webhooks?
The Admaxxer pixel captures client-side events, but server-side webhooks are authoritative for revenue because they survive ad blockers and client-side bounces.
Put This Knowledge Into Action
Bring Meta and Google ads into one self-hosted workspace.
Get Started Free