Reputation: 348
I cannot able to validate the webhook response from the shopify by using the "shopify-node-api". and i am using the following code to validate the signature.
Below code is on app.js
app.use(bodyParser.json({
type:'application/json',
limit: '50mb',
verify: function(req, res, buf, encoding) {
if (req.url.startsWith('/webhook')){
req.rawbody = buf;
}
}
})
);
app.use("/webhook", webhookRouter);
Below on webhook.router.js
router.post('/orders/create', verifyWebhook, async (req, res) => {
console.log('🎉 We got an order')
res.sendStatus(200)
});
Below for the verification function
function verifyWebhook(req, res, next) {
let hmac;
let data;
try {
hmac = req.get("X-Shopify-Hmac-SHA256");
data = req.rawbody;
} catch (e) {
console.log(`Webhook request failed from: ${req.get("X-Shopify-Shop-Domain")}`);
res.sendStatus(200);
}
if (verifyHmac(JSON.stringify(data), hmac)) { // Problem Starting from Here
req.topic = req.get("X-Shopify-Topic");
req.shop = req.get("X-Shopify-Shop-Domain");
return next();
}
return res.sendStatus(200);
}
Verify signature function
function verifyHmac(data, hmac) {
if (!hmac) {
return false;
} else if (!data || typeof data.data !== "object") {
// I am Getting Error HERE
console.log('Error in data', data);
return false;
}
const sharedSecret = config.shopify_shared_secret;
const calculatedSignature = crypto
.createHmac("sha256", sharedSecret)
.update(Buffer.from(data), "utf8")
.digest("base64");
console.log('calculatedsecret', calculatedSignature);
return calculatedSignature === hmac;
};
and the body I am getting it as undefined. suggest me how to fix this problem in shopify webhook API
Upvotes: 6
Views: 6818
Reputation: 348
Instead of using the bodyparser.json()
use bodyparser.raw
to fetch the all the payload to process the shopify webhook
verification.
router.use(bodyparser.raw({ type: "application/json" }));
// Webhooks
router.post("/", async (req, res) => {
console.log("Webhook heard!");
// Verify
const hmac = req.header("X-Shopify-Hmac-Sha256");
const topic = req.header("X-Shopify-Topic");
const shop = req.header("X-Shopify-Shop-Domain");
const verified = verifyWebhook(req.body, hmac);
if (!verified) {
console.log("Failed to verify the incoming request.");
res.status(401).send("Could not verify request.");
return;
}
const data = req.body.toString();
const payload = JSON.parse(data);
console.log(
`Verified webhook request. Shop: ${shop} Topic: ${topic} \n Payload: \n ${data}`
);
res.status(200).send("OK");
});
// Verify incoming webhook.
function verifyWebhook(payload, hmac) {
const message = payload.toString();
const genHash = crypto
.createHmac("sha256", process.env.API_SECRET)
.update(message)
.digest("base64");
console.log(genHash);
return genHash === hmac;
}
Upvotes: 7