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