There are several SO posts, but years old, and there is no documentation that I can find on how to use nodejs and express to validate a webhook from Shopify for nodejs in 2023. My issue, I know, is in getting the request body in the same format that Shopify used to create their hmac.
How do you correctly get the req
body to create the local hash to compare against the hmac from Shopify?
import express from 'express'
import cors from 'cors'
import * as crypto from 'crypto'
import bodyParser from 'body-parser'
const app = express()
app.use(cors({ origin: true }))
app.post('/order/create', bodyParser.text({ type: 'application/json' }), async (req, res) => {
try {
const hmac = req.header('X-Shopify-Hmac-Sha256')
const topic = req.header('X-Shopify-Topic')
const shop = req.header('X-Shopify-Shop-Domain')
const secret = await shopifySharedSecret()
if (!secret) {
throw Error('Check logs.')
}
const hash = crypto.createHmac('sha256', secret).update(req.body).digest('hex')
if (hash !== hmac) {
throw Error('hmac validation failed')
}
res.send({
processed: true,
})
} catch (error) {
res.send({})
}
})
2
Answers
Needed to add an augment to access
req.rawBody
.I believe the issue is that you use
digest('hex')
instead ofdigest('base64')
.The Shopify docs says :
So you need to use the same encoding.