Webhook Signature

All webhooks sent from Coinify are signed with a shared secret that is known only by you and Coinify. This ensures the integrity of the data contained in the webhook, and also proves that Coinify is the sender of the webhook (provided the shared secret is not known by anyone else).

Specifically, the signature uses HMAC-SHA256, using the shared secret as the key and the full HTTP request body (UTF-8 encoded) as the message. The resulting signature is provided in lowercase hexadecimal format in the X-Coinify-Webhook-Signature HTTP header.

Signature example

Use the following example to test that your signature validation function is working correctly

Shared secret: my-shared-secret,

Payload: {"examplePayload":true}

Expected signature: bcdbb89e3031905f3cc1a20d16b5f969a17a7d8fa0c26e4a807c2193402d66f4


JavaScript code to validate a webhook event signature

const crypto = require('crypto');

const sharedSecret = 'shared-secret';

// Express example
const body = req.body;
const signature = req.headers['X-Coinify-Webhook-Signature'];

const hash = crypto.createHmac('sha256', sharedSecret)
  .update(JSON.stringify(body))
  .digest('hex');

return hash === signature;

Python code to validate a webhook event signature

import hashlib, hmac

shared_secret = 'the_shared_secret'

# Get the raw HTTP POST body (JSON object encoded as a string)
body = get_body()

# Get the signature from the HTTP or email headers
signature = get_header("X-Coinify-Webhook-Signature")

expected_signature = hmac.new(shared_secret, msg=body, digestmod=hashlib.sha256).hexdigest()
return signature == expected_signature