Verify webhook signatures

Verify the integrity of webhooks using HMAC signatures.


To protect your server from unauthorised webhooks, we strongly recommend that you verify the Hash-based message authentication code (HMAC) signature of every webhook that Datman sends. Each webhook includes a signature in a request header, calculated from the request body with a secret key that only you and Datman know. By verifying this signature, you confirm that the webhook was sent by Datman and was not modified during transmission.

Get your signing keys

Datman signs webhooks with the following keys:

KeyUsed forHeader
Webhook secretpaymentStatusHMACSignature
Transfer signing keyinternalTransferSucceeded and internalTransferFailedX-Datman-Signature

Datman gives you these keys. Store them securely on your server. Never put them in client-side code.

Note that Datman includes the HMACSignature header only when a webhook secret is set up for your account.

Verify using your own solution

Both headers use the same scheme. To verify a signature, follow these steps.

Step 1: Get the payload

Use the raw request body exactly as you received it, as a UTF-8 string. Do not deserialise the JSON and serialise it again before you calculate the signature, because a change in the order of the keys or in white space changes the signature.

Step 2: Calculate the HMAC signature

  1. Convert the raw request body to a binary representation, given the UTF-8 charset.
  2. Convert your key to a binary representation, given the UTF-8 charset. Use the key exactly as Datman gave it to you. Do not decode it from hexadecimal or Base64.
  3. Calculate an HMAC using:
    • The SHA256 function.
    • The binary representation of the payload.
    • The binary representation of the key.
  4. To get the final signature, hex-encode the result in lower case.

Step 3: Compare signatures

Get the signature from the request header: HMACSignature for paymentStatus, or X-Datman-Signature for transfer webhooks. Header names are case-insensitive, so your framework can show them as hmacsignature or x-datman-signature.

If the signature that you calculated in Step 2 matches the signature in the header, you know that the webhook was sent by Datman and was not modified during transmission. We recommend that you use a constant-time comparison function, so that the time taken to compare the signatures doesn't reveal anything about the expected value.

If the signatures don't match, do not process the webhook.

Example

Sample webhook secret:

example_webhook_secret_123

Sample paymentStatus request body, signed using the above webhook secret:

{"order_id":"ORD-100245","amount":"24.50","currency":"GBP","customer_id":"CUST-55021","xref":"O88213045M663412T4821937","status":"authorisation","success":"true","date":"2026-10-15 12:34:56+01:00"}

The HMACSignature header for this body is:

f70f8543043507af602a97679cfc4366d5152acc3dc239b78c2d80e5367da71b

Code samples

The following examples show how to verify a signature. Pass the raw request body, the value of the signature header, and the matching key.

import crypto from 'node:crypto';
import express from 'express';

// Returns true if the signature matches the raw request body
function isFromDatman(rawBody, signatureHeader, key) {
  const expected = crypto.createHmac('sha256', key).update(rawBody, 'utf8').digest('hex');
  const received = String(signatureHeader ?? '');
  return (
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))
  );
}

const app = express();

// Keep the raw body: don't use express.json() on this route
app.post('/webhooks/datman', express.raw({ type: 'application/json' }), (req, res) => {
  const rawBody = req.body.toString('utf8');
  if (!isFromDatman(rawBody, req.get('HMACSignature'), process.env.DATMAN_WEBHOOK_SECRET)) {
    return res.sendStatus(401);
  }
  // Store the webhook, then accept it
  res.sendStatus(200);
});

See also

On this page

Need help?

Questions about your integration, credentials or going live?

Contact supportRequest a sandbox