Hello everyone, I generated a webhook using GraphQL in my custom app for filtering purposes, but now I’m stuck on how to validate it in Laravel. Does anyone have any suggestions on how to achieve this?
I have not tried this but hope this blog helps.
Hi, thanks but this is for webhook created in dashboard, my webhook is created using graphql.
The authentication method for webhooks is the same regardless of how you create them. ![]()
I have in laravel:
public function testwebhook(Request $request){
function validateWebhook($data, $hmacHeader, $sharedSecret) {
$calculatedHmac = base64_encode(hash_hmac('sha256', $data, $sharedSecret, true));
return hash_equals($calculatedHmac, $hmacHeader);
}
// Example usage
$data = file_get_contents('php://input'); // Raw request body
$hmacHeader = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256']; // HMAC header from Shopify
$sharedSecret = env('SHOPIFY_SHARED_SECRET'); // Your app's shared secret
if (validateWebhook($data, $hmacHeader, $sharedSecret)) {
Log::info("Shopify webhook working");
} else {
Log::info("Webhook doesn;t work");
}
}
Webhook generated with graphql:
{
"data": {
"webhookSubscriptionCreate": {
"webhookSubscription": {
"id": "gid://shopify/WebhookSubscription/1831320519038",
"topic": "PRODUCTS_UPDATE",
"filter": null,
"format": "JSON",
"endpoint": {
"__typename": "WebhookHttpEndpoint",
"callbackUrl": "https://example.com"
}
},
"userErrors": []
}
},
"extensions": {
"cost": {
"requestedQueryCost": 10,
"actualQueryCost": 10,
"throttleStatus": {
"maximumAvailable": 2000,
"currentlyAvailable": 1990,
"restoreRate": 100
}
}
}
}
And still doesn’t work, any ideas?
Are you creating a public app or custom app?
Everything looks okay, so I’d checked your secret value is correct.
Thanks for answering, yeah its a custom app from settings>apps>develop custom app
Thanks ![]()
Just to confirm your using the API Secret key from you app, and ensured there’s no spaces or anything around it?
Have you got any middleware or anything modifying the request beforehand?
Api secret key i’m using, no space or anything. I’ve disabled csrf token for this route and, i got the response from:
if (validateWebhook($data, $hmacHeader, $sharedSecret)) {
Log::info("Shopify webhook working");
} else {
Log::info("Webhook doesn't work");
}
Allways i’m getting: Log::info("Webhook doesn't work");
I would suggest also to double check the secret. Otherwise, I wonder if it could be an encoding problem: the $data read from the webhook request body should be handled as UTF-8: I’m not sure how it works in PHP, but the hash_hmac could give a different result with the wrong encoding.
I’d suggest making sure the data is encoded in UTF-8 when hashing it. I’m not a PHP expert but it looks like mb_convert_encoding could help. Also I wonder if hash_equals wouldn’t be better suited to compare the signature in the header and the computed hash.
Did you create the webhook using the same custom app, that the client secret is for?
I would take a step back and start from the beginning:
On your dev store, create a new custom app with the correct permissions.
Create the webhook using the Admin API token from your custom app.
Then the bottom secret from the custom app to verify the webhook.
Hi, thanks for fast response. The webhook was created from shopify app graphql in dashboard. This can be an issue?
Yeah, that’ll be it.
Just to clarify you mean using the Shopify iGraphQL App in Admin?
Your app can only authenticate webhooks created by itself. ![]()
So you’ll either need to create it using GraphQL with the Admin API Key of your custom app OR if you go into notifications in Shopify Admin settings, you can manually set these up and use the displayed token.
Yes, thats the app which i used to generate that webhook, thanks i will try to generate a webhook by a request graphql.
Great guys, thanks for patience. The issue it was i created the webhook from shopify dashboard Shopify iGraphQL App and that was the reason why wasn’t working to validation the of the webhook.
Thank you guys!