I created a webhook for notifications to be posted when a transaction happens on Triple-a.io. here is their doc: https://developers.triple-a.io/docs/triplea-api-doc/4c87b81419436-webhook-notifications#sample-nodejs-code
They pass a signature in the header, that I can verify with a hmac-sha256 algorithm.
I built it all.
But the signature never matches.
Their directions are pretty simple, they are to do this:
**To verify the header signature:
the developer will take the timestamp concatenate it with the raw request body using a period . as a separator example: . apply the hmac-sha256 algorithm with notify_secret**
So here is what I programmed, with notes:
$_rawdata = file_get_contents('php://input');// Here is the raw data dump
$data = json_decode($_rawdata); // this is where I am going to have the code look through it later.
$headers = getallheaders(); // this is so I can find the security header: triplea-signature
$_authKeyHeader = $headers['triplea-signature']; // now $_authKeyHeader has their signature line with the timestamp and the v1...
$_payment_reference = $data->payment_reference; // I need the payment reference so I can go find the database and get the secret I need (I created it when I created the order page when I sent them to pay the small platform fee)
if(isset($_payment_reference) && $_payment_reference != "") { /// I have to check for this, otherwise I don't have the ability to get the secret, so will just have to error out...
//inside here I do a database pull to populate: $_secretKey with the secret key we used for the order form.
$_headerlines = explode(",", $ _authKeyHeader );
$_timestampside = $_headerlines[0];// this has the t=<timestamp>
$_sigside = $_headerlines[1];// This has the v1=sig
$timestamparray = explode("=", $_timestampside); // split the timestamp to get rid of t=...
$_timestamp2use = $timestamparray[1];// $_timestamp2use now has JUST the timestamp...
$_sigsidearray = explode("=", $_sigside);// make the signature line into an array with v1 and sig...
$_signatureside = $_sigsidearray[1]; // $_signatureside now has ONLY their Signature line...
$_securitydump = $_timestamp2use.".".$_rawdata; // $_securitydump is the timestamp and dot and raw data line together. (Their line 3 instruction: <unix-timestamp>.<raw-request-body>)
$signature = base64_encode(hash_hmac('sha256', $_securitydump, $_secretKey, true)); // here is where I do the base64_encode...
$authKey = $_signatureside;// I am going to compare $authKey to the signature line they sent...
if($signature === $authKey) {
// match go process everything and then end with 200:
/* data all done... */
http_response_code(200);
exit;
// Done.
} else {
/* no secret... exit without success */
http_response_code(401);
exit;
}
But that signature never matches the authkey. I printed them to a log file to see what was happening, here are some of the log file, so I could track what it was doing and where and seeing if it would execute code after it matched and it never did, instead of executes where it does not match. the else... So here are some of the log entries it made:
Checking at line: '36' and secretkey='JgphH7OQfrTszfKQK5yM3HlwgBtw2AtxJGXSB0zVZCy6AGXVgGZ1TSYeFfkUQMPN'
Checking at line: '39' header-sig='t=1658991282,v1=00f6869b5173b80e32c16b1509dd5a22f5a3ff571aca399c33a451936a55e29e'
Checking at line: '42' timestampside='t=1658991282'
Checking at line: '47' timestamp='1658991282' - should be just the timestamp now
Checking at line: '53' sig='APaGm1FzuA4ywWsVCd1aIvWj/1cayjmcM6RRk2pV4p4='
made it at line: '56' and keys: APaGm1FzuA4ywWsVCd1aIvWj/1cayjmcM6RRk2pV4p4= === 00f6869b5173b80e32c16b1509dd5a22f5a3ff571aca399c33a451936a55e29e
I had it print the lines it was at and various data so I could pinpoint what was happening.
The line 56 is where it does: if($signature === $authKey) { so it just logs: $signature === $authKey... so I could see them.
they do not match.
Can you tell me what I did wrong, aside from my terrible coding? lol. I know I'm a novice at coding, so probably did a LOT wrong, but I'm just trying to make this work for the guy.