I have created a webhook in the Shopify Admin under notification settings that calls an endpoint to my BackEnd application. I am using NestJS and I’m attempted to verify the webhook using the provided HMAC x-shopify-hmac-sha256 header.
import {
Injectable,
NestMiddleware,
UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Request, Response, NextFunction } from 'express';
import * as crypto from 'crypto';
@Injectable()
export class ShopifyWebhookMiddleware implements NestMiddleware {
private readonly SHOPIFY_SECRET: string;
constructor(private configService: ConfigService) {
this.SHOPIFY_SECRET = this.configService.get<string>(
'SHOPIFY_WEBHOOK_SECRET',
);
}
use(req: Request, res: Response, next: NextFunction) {
console.log('---------here----------------');
const hmac = req.headers['x-shopify-hmac-sha256'] as string;
if (!this.verifyShopifyWebhook(req.body, hmac)) {
throw new UnauthorizedException('Invalid Shopify webhook signature');
}
next();
}
private verifyShopifyWebhook(body: unknown, hmac: string): boolean {
if (!hmac || !this.SHOPIFY_SECRET) {
return false;
}
const message = JSON.stringify(body);
const generated_hash = crypto
.createHmac('sha256', this.SHOPIFY_SECRET)
.update(message, 'utf8')
.digest('base64');
console.log('generated_hash', generated_hash);
console.log('hmac', hmac);
return crypto.timingSafeEqual(
Buffer.from(generated_hash, 'utf8'),
Buffer.from(hmac, 'utf8'),
);
}
}
I am using the secret provided on the webhooks page in the Shopify Admin notification settings. No matter what I do, the values are not matching.
Anyone can help me? Thanks very much