Webhook Authentication
MunoPay signs all webhook requests, allowing you to verify their authenticity. While optional, this provides an additional layer of security for applications handling sensitive data.
Verifying Request Signatures
Webhook POST requests include a MunoPay-Signature
header. To verify the request, generate a signature using your
webhook key and compare it with the header value.
Webhook Authentication Key
Your webhook key is automatically generated when you create a business account. You can view or reset it in your account settings.
Signature Generation Steps
To verify a webhook request in your application:
- Construct the webhook URL exactly as registered, including any query parameters.
- Extract the timestamp (
t
) and signature (v
) from theMunoPay-Signature
header. Reject requests with outdated timestamps to prevent replay attacks. - Append the timestamp to the webhook URL.
- Sort POST variables alphabetically and concatenate each
key-value pair to the URL string. Include only the required
fields:
status
,reference_id
,transaction_id
. - Compute an HMAC-SHA256 hash of the string using your webhook key to generate the signature.
- Compare your computed signature with the one in the
MunoPay-Signature
header. Accept the request only if they match.
Sample PHP implementation to generate verification signature:
/**
* @param string $webhookKey The webhook's authentication key.
* @param string $timestamp The signature timestamp.
* @param array $params The request's POST parameters.
*/
// Only include these from POST data
$params = [
'status' => 'Approved',
'reference_id' => '52750b30ffbc7de3b36',
'transaction_id' => 'shafbc7de352b30ffbc73b36'
];
$webhookKey = '<--- Your Webhook Key ---->';
$signature = $_SERVER['HTTP_MunoPay_SIGNATURE'];
preg_match('/t=([0-9]+),v=([a-f0-9]{64})/', $signature, $matches);
if (count($matches) !== 3) {
echo 'Invalid signature format';
exit;
}
$receivedTimestamp = $matches[1];
$receivedSignature = $matches[2];
function generateSignature($webhookKey, $timestamp, $params) {
$signed_data = $timestamp;
ksort($params);
foreach ($params as $key => $value) {
$signed_data .= strval($key) . strval($value);
}
return hash_hmac('sha256', $signed_data, $webhookKey, false);
}
$generatedSignature = generateSignature($webhookKey, $receivedTimestamp, $params);
if (!hash_equals($generatedSignature, $receivedSignature)) {
echo 'Invalid signature';
exit;
}