Topics covering webhook creation & management, event handling, Pub/Sub, and Eventbridge, in Shopify apps.
I am unable to successfully verify any webhooks. I am doing the following:
publicfunctionverifyWebhook($request, $secret) {$signature = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];$calculated_hmac = base64_encode(hash_hmac('sha256', $request->input(), $secret, true));if($signature != $calculated_hmac) {thrownewException('Webhook is not valid');}returntrue;}
Alright, I figured it out. The webcatcher had an option to "format json" and "word wrap" which was obviously adding some formatting characters.
Therefore be sure to check that you are testing with the response body in its absolute raw format.
I hope this helps a few others!
Thanks.
Had the same issue. Using request.rawBody instead of request.body helped. Also note that the secret key you should use for verification is 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".
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)
.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();
}