skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. 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.

    $signature = request()->header('x-xero-signature');
    $payload = file_get_contents("php://input");
    $webhookKey = '-----Webhook Key-----';
    $computedSignature = hash_hmac('sha256', $payload, $webhookKey);
    if ($computedSignature === $signature) {
         return response(200);
    }
    
    return response(401);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search