Topics covering webhook creation & management, event handling, Pub/Sub, and Eventbridge, in Shopify apps.
It seems like Shopify calculates their HMAC a bit differently than the presented way on their docs. We see some tiny differences like
`NbPnSrptamKvGes3_4uimjnqPgRzJc997iclJzhNk-c=` (from Shopify)
vs
`NbPnSrptamKvGes3/4uimjnqPgRzJc997iclJzhNk+c=` (generated with multiple langs, inc. PHP, Ruby, Node, following their code from https://shopify.dev/docs/apps/webhooks/configuration/https)
Has anyone spotted something like this?
it happens when receiving the
product_feeds/full_sync |
Which is pretty new (2023-07) which can explains this.
Apparently, the difference is that the new Shopify's hmac is calculated with base64 safe url.
The way to overcome this is to decode and re-encode to regular base64 OR have a fallback in your code to check against base64url hmac:
// Verify incoming webhook.
const verifyWebhook = (payload: string, hmac: string): boolean => {
const secret = shopify.api.config.apiSecretKey;
const genHash = createHmac('sha256', secret).update(payload).digest('base64');
return genHash === hmac || genHash === Buffer.from(hmac, 'base64').toString('base64');
};