App failing hmac verification for webhook

Topic summary

App’s mandatory Shopify webhooks are failing HMAC verification when using the Node template with shopify.processWebhooks and PrivacyWebhookHandlers.

Key guidance: verify the HMAC using the app’s client secret against the X-Shopify-Hmac-Sha256 header. Compute it over the raw HTTP request body (unparsed) and compare base64 strings. HMAC (hash-based message authentication code) confirms the payload is authentic and unaltered.

Implementation hints:

  • Use Express middleware to capture the raw body: express.raw({ type: ‘application/json’ }). Then JSON.parse it and keep both parsed and raw buffers (e.g., req.rawBody).
  • Calculate with crypto.createHmac(‘sha256’, apiSecret).update(rawBuffer).digest(‘base64’) and compare to the header value.

References: Shopify webhook docs and verification steps were linked. Code snippets are central to understanding the fix.

Open point: the OP asked if this raw-body approach works seamlessly with Shopify’s Node template (shopify.processWebhooks). No confirmation or resolution yet.

Summarized with AI on December 26. AI used: gpt-5.

Hi, My node app is failing the hmac verification for mandatary webhooks. Is there a solution for this problem.

this is the code for webhook in my app

app.post(
shopify.config.webhooks.path,
shopify.processWebhooks({ webhookHandlers: PrivacyWebhookHandlers })

);

I have looked almost everywhere and wasted a lot of time on this, Please help out if you know a solution or a workaround for this.

hi @vscode ,

To verify the payload sent from Shopify you need to match the hash of the request body from the webhooks payload.
Keep in mind the request body has to be the raw buffer from the HTTP request before getting parsed by body parser or any json parser. I made a middleware that passes the raw buffer along with the parsed body to my middleware layer. you need the client secret of your app to calculate the hash from the raw request body.
Shopify gives you the hash value you should expect in the header as “X-Shopify-Hmac-Sha256”. You need to compare your calculated hash value a the hmac given from Shopify end.

I’m sharing my hmac verification code below

Pass the raw body along with the parsed body

this.express.use(
            '/api/webhook',
            express.raw({ type: 'application/json' }),
            (req: RawBodyRequest, res: Response, next: NextFunction) => {
                req.rawBody = req.body;
                req.body = JSON.parse(req.body);
                next();
            }
        );

get hmac from request header

async function webhookMiddleware(
    req: RawBodyRequest,
    res: Response,
    next: NextFunction
): Promise

Varify hmac

```markup
function verifyHmac(bodyBuffer: Buffer, hmac: string, apiSecrate: string) {
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecrate)
        .update(bodyBuffer)
        .digest('base64');
    return calculatedHmac === hmac;
}

I’m adding Shopify’s documentation pages link below
Webhook docs - Shopify
Verify webhooks -Shopify

Does this work with shopify’s node template that uses shopify.processWebhooks({ webhookHandlers: PrivacyWebhookHandlers }) to process the webhooks?