phpauthorize.netauthorize.net-webhooks

How do i debug an invalid webhook payload using stymiee/authnetjson


Im using stymiee/authnetjson library to consume and verify an authorize.net webhook in the sandbox environment.

I can verify my headers include

X-ANET-Signature: sha512=C3CC15F7801AA304C0840C85E4F0222A15338827EE3D922DC13A6BB99DF4BFE7D8E235A623480C0EAF3151F7B008E4DFBFDC6E9F493A6901961C5CFC10143289

And my json body is

{"notificationId":"c5933ec1-2ef6-4962-a667-10552d19c481","eventType":"net.authorize.payment.authcapture.created","eventDate":"2018-01-20T20:36:54.9163559Z","webhookId":"66cf7109-f42f-45b9-bf36-f1ade83eac48","payload":{"responseCode":1,"authCode":"37ATT8","avsResponse":"Y","authAmount":550.00,"entityName":"transaction","id":"60038744863"}}

I have a signature key set up and it all seems correct and similar to the one in the tests for the library

My code looks like this:

$signature_key = "...";
$headers = getallheaders();
$payload = file_get_contents("php://input");

$webhook = new JohnConde\Authnet\AuthnetWebhook($signature_key, $payload, $headers);

if ( ! $webhook->isValid() ) {
    error_log("Payload not valid");
}

I have also tried removing the $headers argument from the constructor args

When I execute a test transaction, it is not valid so I get 'Payload not valid' in the logs. How can I debug this problem?

Thanks! NFV


Solution

  • This issue was caused by the X-ANET-Signature being case sensitive. I orinigally was looking for it exactly as you see it but another user reached to me with the same issue but they were getting X-Anet-Signature instead which the code was not expecting. When I was doing my debugging I saw the same issue and figured either I somehow made an error when I first coded this or Authnet made a change and I needed to adapt.

    Apparently that is not the issue. I am unsure why we are seeing inconsistent cases for this header but I will reach out to Authorize.Net to see if I can find out what the story is.

    But the fix is easy: Update the library to use version 3.1.4 which is case agnostic when checking this header's value.

    For the sake of answering the literal title of this question, here's a sample script for dubugging this issue:

    <?php
    
    namespace myapplication;
    
    use JohnConde\Authnet\AuthnetWebhook;
    
    // Include a configuration file with the Authorize.Net API credentials
    require('./config.inc.php');
    
    // Include my application autoloader
    require('./vendor/autoload.php');
    
    $errorCode = null;
    $errorText = null;
    $isValid   = null;
    
    try {
        $headers = getallheaders();
        $payload = file_get_contents("php://input");
        $webhook = new AuthnetWebhook(AUTHNET_SIGNATURE, $payload, $headers);
        $isValid = 'false';
        if ($webhook->isValid()) {
            $isValid = 'true';
        }
        $hashedBody = strtoupper(hash_hmac('sha512', $payload, AUTHNET_SIGNATURE));
        $hash = explode('=', $headers['X-Anet-Signature'])[1];
        $valid = strtoupper(explode('=', $headers['X-Anet-Signature'])[1]) === $hashedBody;
    }
    catch (\Exception $e) {
        $errorCode = $e->getCode();
        $errorText = $e->getMessage();
    }
    finally {
        ob_start(); 
        var_dump([
            'errorCode'  => $errorCode,
            'errorText'  => $errorText,
            'isValid'    => $isValid,
            'headers'    => $headers,
            'payload'    => $payload,
            'hashedBody' => $hashedBody,
            'hash'       => $hash,
            'valid'      => $valid
        ]);
        $dump = ob_get_clean();
        file_put_contents('webhooks.txt', $dump, FILE_APPEND | LOCK_EX);
    }