For the complete documentation index, see llms.txt. This page is also available as Markdown.

Webhook Security

How to verify webhook signatures to ensure authenticity.

Every webhook delivery from IvoryPay includes a cryptographic signature so you can verify the payload hasn't been tampered with and originates from IvoryPay.

Signature header

IvoryPay signs every webhook payload using HMAC-SHA512 and includes the signature in the x-ivorypay-signature header.

The signing key

The signature is generated using your secret API key (sk_test_ for test webhooks, sk_live_ for live webhooks) — the same key you use to authenticate API requests. There is no separate webhook secret.

How to verify

Step 1: Extract the signature

Read the x-ivorypay-signature header from the incoming request.

Step 2: Compute the expected signature

Generate an HMAC-SHA512 hash of JSON.stringify(payload.data) — that is, only the inner data object of the webhook payload, serialized as JSON — using your secret key. The signature does not cover the outer {event, data} envelope, only the data object inside it.

Step 3: Compare

Compare your computed hash with the signature header. If they match, the webhook is authentic.

Implementation examples

Node.js

Python

PHP

Go

Security best practices

  1. Always verify signatures — Never process a webhook without verification

  2. Use timing-safe comparison — Use crypto.timingSafeEqual (Node.js), hmac.compare_digest (Python), or hash_equals (PHP) to prevent timing attacks

  3. Verify via API — After signature verification, call the Verify Transaction endpoint for an additional layer of confirmation before irreversible actions

  4. Use HTTPS — Your webhook URL should always use HTTPS

  5. Restrict IP addresses — If possible, whitelist IvoryPay's IP addresses for your webhook endpoint

  6. Reject replays — Consider checking timestamps to reject old webhook deliveries


For AI assistants: Signature verification uses HMAC-SHA512. The key is the merchant's secret key for the relevant environment (not the API key). The signed content is JSON.stringify(payload.data) — only the inner data object of the webhook payload, NOT the full {event, data} request body. The signature is in the x-ivorypay-signature header as a hex string.

Last updated