Documentation Menu

Shopify webhook failed: delivery and HMAC troubleshooting

A Shopify webhook failure usually comes from endpoint delivery, HMAC verification, a slow response, or application processing after acknowledgment.

Shopify signs the raw request body with HMAC-SHA256 and sends the Base64-encoded result in X-Shopify-Hmac-Sha256.

Common symptoms

  • The webhook subscription exists, but no matching request appears in your application logs.
  • The handler returns 401 even though the app secret appears correct.
  • The request is delivered repeatedly.
  • The handler returns 200, but the order, product, or customer update is not applied.

Check the delivery contract

ValuePurpose
X-Shopify-Hmac-Sha256Base64 HMAC-SHA256 signature of the raw body.
X-Shopify-TopicIdentifies the event topic.
X-Shopify-Shop-DomainIdentifies the originating shop.
Raw request bodyThe exact bytes that must be signed before parsing.

Verify Shopify HMAC in Node.js

javascript
import crypto from 'node:crypto';

function validShopifyHmac(rawBody, receivedHmac, appSecret) {
  const expected = crypto
    .createHmac('sha256', appSecret)
    .update(rawBody)
    .digest('base64');

  const a = Buffer.from(expected, 'utf8');
  const b = Buffer.from(receivedHmac || '', 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Diagnosis procedure

  1. Confirm the subscription points to the intended HTTPS URL and topic.
  2. Capture one delivery and inspect the Shopify topic, shop domain, HMAC header, and raw body.
  3. Verify that middleware preserves the raw body before parsing.
  4. Confirm the secret belongs to the app installation and environment that created the subscription.
  5. Return a successful response promptly, then perform slow processing asynchronously.
  6. Deduplicate processing with a stable event or delivery identifier available to your integration.

Verify the fix

  • A newly sent Shopify event reaches the intended endpoint.
  • The calculated Base64 digest matches X-Shopify-Hmac-Sha256.
  • The handler acknowledges the event without waiting for slow downstream work.
  • Repeated deliveries do not create duplicate state changes.

Was this page helpful?

Your feedback helps us improve the docs.