Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

validating webhook using HMAC in PHP

validating webhook using HMAC in PHP

emn
Shopify Partner
9 0 7
$body = file_get_contents("php://input");

$ourhmac = base64_encode(hash_hmac('sha256', $body, 'my-DOUBLE-CHECKED-secret', true));
$theirhmac = $app->request->headers->get('X-Shopify-Hmac-Sha256');

// $ourhmac == OGNlMmMyOTI2OWVjMDAyOTE3MTQ4NDQ0ZTE5YTIxZjg4YWZhMTZkOWE0NmE3Mzg2ZjdjMTc1M2EzODdhZWI1YQ==
// $theirhmac == Dj/bSPIDPyhYpjzodjhH/RxxdXTmvKddJJdxhcJ9vNM=

Hi, the example provided in your docs is not working for me, could you please update it or let me know how to validate the webhook?

 

Thanks.

Replies 6 (6)

Appifiny
Shopify Partner
166 2 55

The following works for me. Check your error log to see if it works for you.

 

function verify_webhook($data, $hmac_header) {
	$calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_SECRET, true));
	return ($hmac_header == $calculated_hmac);
}

if (isset($_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'])) {
	$hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
	$data = file_get_contents('php://input');
	$verified = verify_webhook($data, $hmac_header);
	error_log('Webhook verified: '. var_export($verified, true)); //check error.log to see the result
} else {
	error_log('Request not from shopify');
}

 

Try the best recent order app for Shopify free for 7 days: https://apps.shopify.com/recently

John_Haley
Excursionist
20 0 4

I'm having the same problem.  Here's my PHP code (pretty much copied and pasted from the API docs)

function verifyWebhook($data, $hmacHeader)
{
    $calculatedHmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_SECRET, true));
    error_log('$hmacHeader = ' . $hmacHeader);
    error_log('$calculatedHmac = ' . $calculatedHmac);
    return ($hmacHeader == $calculatedHmac);
}


$hmacHeader = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256'];
$data = file_get_contents('php://input');

$verified = verifyWebhook($data, $hmacHeader);

if (false === $verified)
{
    error_log('HMAC HASH not verified, exiting.'); //check error.log to see the result
    exit;
}

Here's what my error log outputs:

[04-Sep-2015] $hmacHeader = xr0Ycgs/jmADJgPKi0qNCMbYl/J47E6AJx/UAZF/+sU=
[04-Sep-2015] $calculatedHmac = i2HdJvOj8LF8ycdn3SPwI2EXgXQR8l04XAburqsCdhg=
[04-Sep-2015] HMAC HASH not verified, exiting.

Completely different.  I'm using PHP 5.6.2 if that's relevant.

Any idea what it could be that I'm missing?

Appifiny
Shopify Partner
166 2 55

Have you defined SHOPIFY_SECRET?

Have you tried my code above instead of using the code from the docs?

Try the best recent order app for Shopify free for 7 days: https://apps.shopify.com/recently

John_Haley
Excursionist
20 0 4

Yes SHOPIFY_SECRET is defined.  I use it all the time to make API requests which work no problem.

Your code is exactly the same as the example code in the API docs (https://docs.shopify.com/api/webhooks/using-webhooks#verify-webhook) except for one difference - the IF statement checking the header has been set.  

For what it's worth, I added that check to my code but it didn't help because I can see the header is being sent from Shopify correctly.  If you look at my code you can see I output both the hmac header and the calculated hmac.  And you can see they do not match.

I've no doubt it works for you, so I wonder what mistake I'm making?  Such a small amount of code it's crazy that I'm getting different results.  It must be something else...

Appifiny
Shopify Partner
166 2 55

Other than verifying that the shopify hmac header is set I see no difference.

Try the best recent order app for Shopify free for 7 days: https://apps.shopify.com/recently

John_Haley
Excursionist
20 0 4

Okay, sometimes knowing I'm on the right track is good enogh!  Thanks for the help, I'll track this sucker down eventually 🙂