skip to Main Content

I am trying to match the GoCardless webhook supplied signature to the computed version that I generate in PHP.
I’m using the following code but can’t get $computed_signature to match $signature_header.
Here’s the code i’m using:

$webhook_endpoint_secret = getenv("Secret");
$request_body = file_get_contents('php://input');

$request_body_clean = preg_replace("/(s{2,}|t|r|n)/i",'',$request_body);

$headers = getallheaders();
$signature_header = $headers["Webhook-Signature"];

$payload = json_decode($request_body, true);

$computed_signature = hash_hmac("sha256", $request_body_clean, $webhook_endpoint_secret);

var_dump ($signature_header);
var_dump ($computed_signature);

I’ve tried without the preg_replace, in fact I don’t think that does anything as they must send minified anyway.
I’ve tried this the other way around like:
$computed_signature = hash_hmac("sha256", $webhook_endpoint_secret, $request_body_clean);
Gave a different signature (as it should) but still not correct.

Everything else is working fine, I can get the webhook info, I just can’t seem to match signatures.

Am I doing something stupid here?
Any help appreciated, many thanks.

2

Answers


  1. Chosen as BEST ANSWER

    As I was in my test environment and using the GoCardless sandbox, I was placing the secret directly into the following:

    $webhook_endpoint_secret = getenv("ugbo84d2rb7gcrbgcfpoiub9487gc74");
    

    This didn't return anything (as it was looking for an environment variable), so the generated signature was wrong. I changed the test code to (fake secret for example):

    $webhook_endpoint_secret = "ugbo84d2rb7gcrbgcfpoiub9487gc74";
    

    and the signatures now match. This won't be set up like this in my production code, but just in case anyone else was testing as I was. It was just something silly.


  2. GoCardless provide form library method what will do this job for you:

    // We recommend storing your webhook endpoint secret in an environment variable
    // for security
    $webhook_endpoint_secret = getenv("GOCARDLESS_WEBHOOK_ENDPOINT_SECRET");
    $request_body = file_get_contents('php://input');
    
    $headers = getallheaders();
    $signature_header = $headers["Webhook-Signature"];
    
    try {
        $events = GoCardlessProWebhook::parse($request_body,
                                                $signature_header,
                                                $webhook_endpoint_secret);
    
        // Process the events...
    
        header("HTTP/1.1 204 No Content");
    } catch(GoCardlessProCoreExceptionInvalidSignatureException $e) {
        header("HTTP/1.1 498 Invalid Token");
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search