Verify Shopify Webhook Signatures
Shopify signs webhooks with HMAC-SHA256 over the raw request body and sends a base64-encoded digest in the X-Shopify-Hmac-Sha256 header. The key is your app's API secret key (client secret). Paste the raw body, the secret and the header value.
Everything runs in your browser — the payload and secret never leave this page. Want to verify a different provider? See the webhook signature verifier hub or the generic HMAC generator.
How Shopify signs webhooks
- Take the raw request body exactly as delivered.
- Compute HMAC-SHA256 using your app's API secret key as the key.
- Base64-encode the digest and compare it to
X-Shopify-Hmac-Sha256with a constant-time check.
Reference: Shopify signature documentation.
Verify Shopify signatures in code
const crypto = require('crypto');
const digest = crypto
.createHmac('sha256', process.env.SHOPIFY_API_SECRET)
.update(rawBody, 'utf8') // raw request body
.digest('base64');
const received = req.headers['x-shopify-hmac-sha256'];
const valid = crypto.timingSafeEqual(
Buffer.from(digest), Buffer.from(received));import hmac, hashlib, base64
digest = base64.b64encode(hmac.new(
api_secret.encode(), raw_body, hashlib.sha256).digest()).decode()
received = request.headers['X-Shopify-Hmac-Sha256']
valid = hmac.compare_digest(digest, received)Frequently asked questions
Which secret signs Shopify webhooks?
Your app's API secret key (client secret) for app webhooks. Webhooks created in the Shopify admin are signed with a separate secret shown in Settings → Notifications.
Why must I use the raw body?
Shopify computes the HMAC over the exact bytes sent. Parsing and re-serializing the JSON changes whitespace and key order, which breaks the digest.
Verify other providers
Receiving Shopify webhooks on a server behind a firewall or on localhost? Webhook Relay can forward them to your internal service and even verify or transform them before delivery.
