I need to validate Xero webhook
in PHP. Here’s My Code
$payload = file_get_contents("php://input");
$webhookKey = '-----Webhook Key-----';
$computedSignatureKey = base64_encode(hash_hmac('sha256', $payload, $webhookKey, true));
if ($computedSignatureKey === $_SERVER['HTTP_X_XERO_SIGNATURE']) {
return response(200);
}
return response(401);
suppose the xero signature is = aQGh6OxbmgB1NQnnKrQt0utlrqC4dbAJSC2/Aa2/IE4=
and above code return hashed value is = aQGh6OxbmgB1NQnnKrQt0utlrqC4dbAJSC2KAa2/IE4=
there’s a difference between both values, difference is slash (/)
signature coming from xero
include (/)
but after hashed it removes (/)
and replace it with alphabet
so I can’t validate Intent to receive
Webhook
it always return to this status
Intent to receive
required
Response to incorrectly signed payload not 401
. Learn more
2
Answers
With intent to receive, a mixture of correctly and incorrectly signed packages are sent to test the way you handle both.
Incorrectly signed packages typically only differ from the correct signature by 1 changed digit eg the /
Xero is expecting your server to send a 401 code when the signatures don’t match. Your PHP code above only has an if condition returning a code 200, there is no else condition returning a code 401.
Signature comes in header not in body so you have to get it from header, then you need to read payload and compute the signature and compare the signature and computedSignature.