Solved

Issue for validating the hmac for webhook

windskystar
Visitor
2 0 1

Hi.

I am working on a Shopify app which will send an order notification to my app when an order is placed in the Shopify store. I was able to create the Webhooks (orders/create topic) through API. 

 

I need to validate the hmac with the secret key associated with the Webhooks. What I can't figure out is that when I create a Webhooks through API, how would I validate the hmac without asking a user to provide us with his/her secret key? 

I'd like to automate a whole process(registering Webhooks(order and products) when a user installs my Shopify app) so that a Shopify store owner does. not have to manually enter anything for us.

 

The reason is that when I manually create a Webhooks in my Shopify testing store, I see a message 'All your webhooks will be signed with 41c81bc7184c43a6xxxxxxxxxxxxxxxxx so you can verify their integrity And I can use this secret key to validate the hmac which is part of the request header.

 

But I am not sure how I can validate hmac for Webhooks created through the API.  I believe that Webhooks created through API are not showing up a Shopify setting/notification page, so obviously, there is no secret key associated with it.

 

I am not sure if I clarify my issue enough.

 

Accepted Solution (1)

vix
Shopify Staff
540 103 121

This is an accepted solution.

Hi @windskystar 

 

The webhooks created through the API will not display in the admin, that is intended behavior. Webhooks created through the API by a Shopify App are verified by calculating a digital signature. Each webhook request includes a base64-encoded X-Shopify-Hmac-SHA256 header, which is generated using the app's shared secret along with the data sent in the request.

 

You can read more on this here: 

To learn more visit the Shopify Help Center or the Community Blog.

View solution in original post

Replies 5 (5)

vix
Shopify Staff
540 103 121

This is an accepted solution.

Hi @windskystar 

 

The webhooks created through the API will not display in the admin, that is intended behavior. Webhooks created through the API by a Shopify App are verified by calculating a digital signature. Each webhook request includes a base64-encoded X-Shopify-Hmac-SHA256 header, which is generated using the app's shared secret along with the data sent in the request.

 

You can read more on this here: 

To learn more visit the Shopify Help Center or the Community Blog.

Leo_Huynh
Tourist
7 1 5

For those who are looking for code example, this is my implementation in Node.js (I'm using Koa.js - for Express it almost the same)

 

const crypto = require('crypto') // Built-in module of Node.js
const Router = require('koa-router')

const router = new Router({ prefix: '/webhooks' })

// Middleware to verify all webhooks call from Shopify
async function verifyShopifyWebhooks(ctx, next) {
	const topic = ctx.request.headers['x-shopify-topic']
	const shop = ctx.request.headers['x-shopify-shop-domain']
	const hmac = ctx.request.headers['x-shopify-hmac-sha256']

	if (!hmac || !shop || !topic) {
		return ctx.throw(401, "Webhook must originate from Shopify!")
	}

	const genHash = crypto
		.createHmac('sha256', process.env.SHOPIFY_API_SECRET)
		.update(JSON.stringify(ctx.request.body))
		.digest('base64')

	if (genHash !== hmac) {
		ctx.throw(401, "Couldn't verify incomming Webhook request!")
	}

	await next()
}

router.use(verifyShopifyWebhooks)

// Here go all your webhooks API handlers 

router.post("/customers/data_request", async (ctx) => {
	ctx.status = 200
	ctx.body = "Webhook processed!"
})

module.exports = router

 

 

Leo Huynh | Shopify Software Engineer @ Insights Studio
Email: leo@insights.is
Personal site: https://leohuynh.dev
theschoolofux
Shopify Partner
10 0 3

It's worth pointing out that SHOPIFY_API_SECRET is not the API secret key, but the one that you can find in <yourstore>.myshopify.com/admin/settings/notifications page under Webhooks section that says "All your webhooks will be signed with <key> so you can verify their identity."

 

Is that so?

Sergei Golubev | Devigner @ The School of UX | schoolofux.com
fnbuild
Shopify Partner
6 0 2

Super helpful, thanks Leo! I'll post my Sveltekit solution when I get approved

sch-parmeshwar
Shopify Partner
1 0 0

its not matching the hash