Development discussions around Shopify APIs
Return management just got easier! We’ve launched Customer Self-Serve Returns to all Shopify merchants. Click here to learn more!
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'`
User | RANK |
---|---|
16 | |
7 | |
6 | |
6 | |
5 |
Learn these 5 things I had to learn the hard way with starting and running my own business
By Kitana Jan 27, 2023Would you love to unleash the unbridled power of the Google Shopping Channel into your sho...
By Gabe Jan 6, 2023How can you turn a hobby into a career? That’s what Emmanuel did while working as a wa...
By Skye Dec 30, 2022