Check the webhook signature
The owlpay-signature header included in each signed event contains a timestamp and one signature. The timestamp is prefixed by t=, and signature is prefixed by a scheme. Scheme start with v.
owlpay-signature:
t=1689066169,
v1=e997b87453fb8923ae9c02faf45fe5fff60148d7a244896e0b359c96aa4825a0
Note that newlines have been added for clarity, but a real owlpay-signature header is on a single line.
OwlPay generates signatures using a hash-based message authentication code (HMAC) with SHA-256.
We will provide official libraries to verify webhook signature, but before that you can create a custom solution by following these steps.
Step 1: Extract the timestamp and signatures from the header
Split the header, using the , character as the separator, to get a list of elements. Then split each element, using the = character as the separator, to get a prefix and value pair.
The value for the prefix t corresponds to the timestamp, and v1 corresponds to the signature.
Step 2: Prepare the signed_payload string
The signed_payload string is created by concatenating:
The timestamp (as a string)
The character .
The actual JSON payload (that is, the request body)
Step 3: Determine the expected signature
Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.
Step 4: Compare the signatures
Compare the signature (or signatures) in the header to the expected signature.
Code example for PHP:
$requestHeader = 't=1689066169,v1=e997b87453fb8923ae9c02faf45fe5fff60148d7a244896e0b359c96aa4825a0';
$explodedList = explode(',', $requestHeader);
$signaturesData = [];
foreach ($explodedList as $exploded) {
$signaturesData[] = explode('=', $exploded);
}
$t = $signaturesData[0][1];
$v = $signaturesData[1][1];
$request_json = '{"uuid":"att_c0d3d7cda1e2175faa701dfd4a9b85355a3c9630","api_version":"1.0.0","is_test":1,"observation":"owlpay.received_order","data":{"order":{"xxx"}}}';
$hash = \hash_hmac('sha256', "$t.$request_json", 'whs_xxxxxxx');
if ($hash === $v) {
// signature check pass.
}
Updated over 1 year ago