Oferta de lançamento: −50 % no seu primeiro pagamento, até 30 de novembro.Ver a oferta →
webhook·toolkit

Shopify webhook HMAC verification failing

Shopify puts a base64-encoded HMAC-SHA256 of the raw request body in X-Shopify-Hmac-Sha256. Three details break the check: comparing against a hex digest, hashing a parsed body, and using the wrong secret.

Open the Shopify webhook tester →

The check

Node.js
import crypto from 'node:crypto';

function verifyShopify(rawBody, hmacHeader, secret) {
  const digest = crypto.createHmac('sha256', secret).update(rawBody).digest('base64');
  const a = Buffer.from(digest);
  const b = Buffer.from(hmacHeader || '');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
PHP
$raw = file_get_contents('php://input');
$calc = base64_encode(hash_hmac('sha256', $raw, $secret, true));
$ok = hash_equals($calc, $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'] ?? '');
Python
import base64, hashlib, hmac

digest = base64.b64encode(hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()).decode()
ok = hmac.compare_digest(digest, request.headers.get('X-Shopify-Hmac-Sha256', ''))

Cause 1: base64, not hex

Most HMAC examples end with .digest('hex'). Shopify's header is base64. In PHP, the fourth argument of hash_hmac must be true (raw binary) before base64_encode.

Cause 2: the body was parsed

Hash the bytes of the request, before any JSON parsing. In Express use express.raw({ type: 'application/json' }) on the webhook route; in Next.js await req.text().

Cause 3: the wrong secret

Webhooks created by an app are signed with the app's client secret, not with an access token. Webhooks created in the Shopify admin (Settings → Notifications → Webhooks) are signed with the key shown on that page.

Perguntas frequentes

Can I test without creating a real order?

Yes: Webhook Toolkit's signer builds a payload with a valid X-Shopify-Hmac-Sha256 for your secret and sends it to your handler, and the admin's “Send test notification” button delivers a sample to any URL.

Other webhook guides

Oferta de lançamento · −50 %

Depurando uma integração de webhook esta semana?

O Pass 7 dias desbloqueia as explicações com IA e o código do handler pronto para colar, 25 URLs permanentes, 30 dias de histórico e o túnel Relay para localhost. Um único pagamento, sem assinatura.

€ 5 € 2,50 uma vez
Pagamento único · sem assinatura · reembolso em 14 dias · preço de lançamento até 30 de novembro
Shopify webhook HMAC (X-Shopify-Hmac-Sha256) verification failing — fix