Development discussions around Shopify APIs
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"] + ")"); return; }
}
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:
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?
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";
...
koaServer.use(koaBodyParser());
...
koaRouter.post(
"/webhooks/<yourwebhook>",
verifyShopifyWebhooks,
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>.myshopify.com/admin/settings/notifications) 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")
.digest("base64");
if (generateHash !== shopifyHmac) {
ctx.throw(401, "Couldn't verify Shopify webhook HMAC");
} else {
console.log("Successfully verified Shopify webhook HMAC");
}
await next();
}
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..?
Hi,
Did you ever happen to get this working? , I have the same problem
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')
.digest('base64');
const isEqual = crypto.timingSafeEqual(
Buffer.from(hash),
Buffer.from(shopifyHmac),
);
return isEqual;
};
The key was using providing only `utf8` to the `.update(shopifyPayload, 'utf8')`. Not '`base64' `or `'utf8', 'hex'`
Thanks to all Community members that participated in our inaugural 2 week AMA on the new E...
By Jacqui Mar 10, 2023Upskill and stand out with the new Shopify Foundations Certification program
By SarahF_Shopify Mar 6, 2023One of the key components to running a successful online business is having clear and co...
By Ollie Mar 6, 2023