const PORT = 3000; | |
const SECRET = 'APP_SHARED_SECRET'; | |
var http = require('http'), | |
crypto = require('crypto'), | |
server; | |
function verifyShopifyHook(req) { | |
var digest = crypto.createHmac('SHA256', SECRET) | |
.update(new Buffer(req.body, 'utf8')) | |
.digest('base64'); | |
return digest === req.headers['X-Shopify-Hmac-Sha256']; | |
} | |
function parseRequestBody(req, res) { | |
req.body = ''; | |
req.on('data', function(chunk) { | |
req.body += chunk.toString('utf8'); | |
}); | |
req.on('end', function() { | |
handleRequest(req, res); | |
}); | |
} | |
function handleRequest(req, res) { | |
if (verifyShopifyHook(req)) { | |
res.writeHead(200); | |
res.end('Verified webhook'); | |
} else { | |
res.writeHead(401); | |
res.end('Unverified webhook'); | |
} | |
} | |
server = http.createServer(parseRequestBody); | |
server.listen(PORT, function(){ | |
console.log("Server listening on: http://localhost:%s", PORT); | |
}); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Oh! Your code works! |
This comment has been minimized.
This comment has been minimized.
@winsandymyint Glad it could help! |
This comment has been minimized.
This comment has been minimized.
The new buffer object (line 10) saved me; my version wasn't working on real Shopify orders (but was on test webhooks!) until I added that part in. Much thanks! |
This comment has been minimized.
This comment has been minimized.
Thanks! |
This comment has been minimized.
This comment has been minimized.
Thanks for making this. Another thing to keep in mind is that various middleware (e.g. body-parser) can alter the body and that can lead to being unable to verify the webhook. Make sure you have a reference to the raw body of what shopify sent so you can run that through your verification code. |
This comment has been minimized.
This comment has been minimized.
@andjosh great work, I don't know why Shopify documentation is so poor and it takes 2 different ways to verify HMAC. @jmortensen and others: I got it worked well with Express and its middleware, you must use Use Replace line 10 with |
This comment has been minimized.
This comment has been minimized.
It is not working for me . The generated digest and received headers are different.. @tiendq can you please elaborate how to use body-parser.text() in above code ? more details here - https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/verify-shopify-webhook-integrity-node-express-js-512656 |
This comment has been minimized.
This comment has been minimized.
I hope this will help. |
This comment has been minimized.
This comment has been minimized.
@Kushan-'s solution works perfectly, while Shopify's own express middleware did not.. but they may be modifying the request somewhere... not sure, but this works. |
This comment has been minimized.
This comment has been minimized.
+1 for @tiendq's solution this.express = express()
.use(rawBodyGetter)
.use(bodyParser.text())
// .use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true })) const checkWebHookIntegrity = async (req: any, res: any, next: any) => {
let raw;
try {
raw = await rawBody(req);
const digest = crypto.createHmac('sha256', CONFIG.SHOPIFY_WEBHOOK_SECRET)
.update(raw)
.digest('base64');
if (digest === req.headers['x-shopify-hmac-sha256']) {
req.body = JSON.parse(raw.toString('utf-8'));
next();
} else {
console.log('Error with request', os.EOL, req.body);
return res.status(401).send();
}
} catch(e) {
console.log(e);
return res.status(500).send();
}
}; |
This comment has been minimized.
This comment has been minimized.
@Kushan- Thanks you! |
This comment has been minimized.
This comment has been minimized.
I tried this. But not working. Am I doing anything wrong?
|
This comment has been minimized.
This comment has been minimized.
It's been a long time i worked with shopify api, perhaps, uppercase |
This comment has been minimized.
This comment has been minimized.
thank you for your reply. tried the uppercase approach. did not work. got this error
|
This comment has been minimized.
Are you sure this works ? I tried it and it doesn't work for me. I tried this:
console.log("here");
get called but not theconsole.log("test");