Can't verify Webhooks in Node.js! (serverless AWS lambda)

Shopify Partner
46 1 8

That exclamation point used in the title is not an accident. 


1. The official doc doesn't have an example for Node.js 


2. On this Shopify Partners' blog post, it says: 


exports.handler = (event, context, callback) => {
  var client_secret = event.client_secret;
  delete event.client_secret;

  //calculate the hash
  var calculated_hash = crypto.createHmac("sha256", client_secret).update(new Buffer(event.body, "base64")).digest("base64");

  //reject the message if the hash doesn't match
  if (event["X-Shopify-Hmac-SHA256"] != calculated_hash) {
    console.log("calculated_hash: (" + calculated_hash + ") != X-Shopify-Hmac-SHA256: (" + event["X-Shopify-Hmac-SHA256"] + ")");

This post was specifically for an AWS lambda function. But when I generate the hash like this:



var calculated_hash = crypto.createHmac("sha256", client_secret).update(new Buffer(event.body, "base64")).digest("base64");

It's still different from the `X-Shopify-Hmac-Sha256` header value. 


3. I tried it with the following different ways: 

  • update(Buffer.from(event.body, "base64"))
  • update(Buffer.from(JSON.stringify(event.body), 'utf8', 'hex'))
  • update(event.body)

4. I replaced `client_secret` with the following values: 

  • "API secret key" from → Apps → App
  • "API key" from → Apps → App
  • "Access token" I got from the store when we installed the app

All the docs say it's either "client secret" or "shared secret". But I can't find any value with that exact name. Am I using the wrong secret? Or am I using a wrong method to generate the hash? 


Working remotely from Mongolia ~
Replies 23 (23)
Shopify Partner
10 0 3

Had the same issue. Using request.rawBody instead of request.body helped:


import Router from "koa-router";
import koaBodyParser from "koa-bodyparser";
import crypto from "crypto";



    async (ctx) => {
      try {
        ctx.res.statusCode = 200;
      } catch (error) {
        console.log(`Failed to process webhook: ${error}`);


async function verifyShopifyWebhooks(ctx, next) {
  const generateHash = crypto
    .createHmac("sha256", process.env.SHOPIFY_WEBHOOKS_KEY) // that's not your Shopify API secret key, but the key under Webhooks section in your admin panel (<yourstore> where it says "All your webhooks will be signed with [SHOPIFY_WEBHOOKS_KEY] so you can verify their integrity
    .update(ctx.request.rawBody, "utf-8")

  if (generateHash !== shopifyHmac) {
    ctx.throw(401, "Couldn't verify Shopify webhook HMAC");
  } else {
    console.log("Successfully verified Shopify webhook HMAC");
  await next();


Sergei Golubev | Devigner @ The School of UX |
New Member
6 0 0

Hi, I have the same problem. but i am not using "crypto", I'm using "crypto-js" Search the module "'crypto" but I did not find it and the module "crypto-js"doesn't have the func "createHmac"..



could you tell me how to find the module "crypto" and upload a lambda aws..? 

New Member
6 0 0



Did you ever happen to get this working? , I have the same problem

Shopify Partner
46 1 8

Hi @Luis45,


I made it work with this method: 



const verifyHMAC = (shopifyHmac, shopifyPayload) => {
  const hash = crypto
    .createHmac('sha256', process.env.SHOPIFY_PUBLIC_APP_SECRET)
    .update(shopifyPayload, 'utf8')

  const isEqual = crypto.timingSafeEqual(

  return isEqual;

The key was using providing only `utf8` to the `.update(shopifyPayload, 'utf8')`. Not '`base64' `or `'utf8', 'hex'`


Working remotely from Mongolia ~