Webhook Signature

All webhooks sent from TransFi are signed with a dedicated secret that is known only by TransFi and Customers. This ensures the integrity of the data contained in the webhook.

📘

NOTE

Please connect with our tech support team to know your webhook dedicated secret key.

We are using HMAC (Hash-based Message Authentication Code) as the authentication method using two keys:

  • HTTP Request Body
  • Dedicated Secret Key

How does Webhook Signature work?

Use the following code snippet to generate the hash using dedicated_secret_key + request_body

Compare the generated hash with the signature received in the following header:

  • If the generated hash matches the value received from X-Transfi-Hmac-Hash, the webhook request is considered valid.
  • If the values do not match, the webhook request should be treated as invalid.
📘

Customers can skip these events.

Code Snippet

const crypto = require('crypto');
const dedicatedSecret = <DEDICATED_SECRET>;
const body = req.body.toString('utf8');
const signature = req.headers['X-Transfi-Hmac-Hash'];
const hash = crypto.createHmac('sha256', dedicatedSecret).update(body).digest('hex');
return hash === signature;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class VerifyHmacSha256 { public static void main(String[] args) throws
NoSuchAlgorithmException, InvalidKeyException { String webhookSecret =
<DEDICATED_SECRET> // Assign with your secret key String receivedHash =
req.headers['X-Transfi-Hmac-Hash']; String receivedMessage = <STRINGIFIED_BODY>
// Stringified body

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(webhookSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256_HMAC.init(secret_key);

        byte[] calculatedHash = sha256_HMAC.doFinal(receivedMessage.getBytes(StandardCharsets.UTF_8));

        // Convert the calculated hash to a hexadecimal string
        StringBuilder hexCalculatedHash = new StringBuilder();
        for (byte b : calculatedHash) {
            hexCalculatedHash.append(String.format("%02x", b));
        }

        if (hexCalculatedHash.toString().equals(receivedHash)) {
            System.out.println("Hashes match, message is authentic.");
        } else {
            System.out.println("Hashes do not match, message may be tampered.");
        }
    }
}
import hmac
import hashlib
import json
dedicated_secret = "<DEDICATED_SECRET>"  # Replace with your actual dedicated secret
body = request.get_json()  # Assuming you're using Flask or a similar framework
signature = request.headers.get('X-Transfi-Hmac-Hash')
# Generate HMAC hash
hash = hmac.new(
    dedicated_secret.encode('utf-8'), 
    json.dumps(body).encode('utf-8'), 
    hashlib.sha256
).hexdigest()
# Compare the generated hash with the signature
is_valid = hash == signature