Webhook Signature Verification
To ensure that webhook requests originate from our platform and have not been modified during transmission, every webhook request is signed using an HMAC-SHA256 signature.
Headers
Each webhook request includes the following HTTP headers:
| Header | Description |
|---|---|
X-Timestamp | Unix timestamp (seconds) indicating when the signature was generated. |
X-Signature | HMAC-SHA256 signature generated using your webhook secret. |
Signature Generation
The signature is generated using the following formula:
signature = HMAC_SHA256(timestamp + "." + request_body, webhook_secret)
Where:
timestampis the value of the X-Timestamp header.request_bodyis the exact raw HTTP request body.webhook_secretis the shared secret configured for your webhook endpoint.
Code Samples
<?php
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? null;
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? null;
$encoded = json_encode($_POST, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
$hash = hash_hmac('sha256', $timestamp . '.' . $encoded, $secretKey);
if (hash_equals($hash, $signature)) {
// YOUR CODE HERE
} else {
echo "Invalid signature";
}
Preventing Replay Attacks
We strongly recommend validating the timestamp before verifying the signature. Reject requests whose timestamp is outside an acceptable window (for example, 5 minutes).
<?php
if (time() - (int) $timestamp > 300) {
echo "Request expired";
}Important Notes
- Always use the raw request body exactly as received.
- Perform the comparison using a constant-time comparison function (for example, PHP's hash_equals()).
Updated about 2 months ago
Did this page help you?
