Icone PayDocsVerifying Webhooks
Every webhook is signed so you can confirm it genuinely came from Icone Pay.
The Signature Header
Each request includes an X-IconePay-Signature header:
t— the UNIX timestamp (seconds) when the request was signed.v1— HMAC-SHA256 of{t}.{raw_body}, keyed with the route's Signing Secret (found under Route info → Webhook signing secret, starting withwhsec_).
Verify with the SDK
The TypeScript SDK does all of this in one call — pass the raw request body, the signature header, and your route's Signing Secret. It returns a typed event, and throws WebhookVerificationError if the signature is missing, wrong, or too old.
Install the SDK
npm i icone-pay-sdk — the verifier runs anywhere Node-style node:crypto is available.Verify Manually
Not using the SDK? Recreate the same check in any language:
- Read the raw request body — do not re-serialize the JSON.
- Parse
tandv1from the header. - Recompute
HMAC_SHA256(secret, t + "." + body)and compare tov1using a constant-time comparison. - Reject requests whose timestamp is older than a few minutes.
Use the raw body
Frameworks that auto-parse JSON (Express
express.json(), etc.) discard the original bytes. Capture the raw body first, or the signature will not match.Replay Protection
The timestamp lets you reject replayed requests — discard anything older than ~5 minutes. Rotate a route's signing secret from Route info → Webhook signing secret if it is ever exposed, and update that route's verifier with the new value.