Validation of Webhook Requests
Before you respond to a Webhook request, you must validate if the request was sent from TaxBandits.
Follow the below steps to verify the authenticity:
Step 1: Read the headers - Signature & TimeStamp to obtain their values.
Step 2: Concatenate User's ClientId + \n + TimeStamp from the header. Compute a hash (HMACSHA256 algorithm) of the above-concatenated string with the User's ClientSecret as the key
Step 3: Convert the computed hash into a base64 string.
Step 4: Compare this base64 string with the Signature from the header
-
If there is a match, parse the JSON data for further processing and should return 200.
-
If there is no match, send the Response as 401 and stop processing.
Sample Code:
- NodeJs
- C#
- Ruby
- Java
- Python
- PHP
- Go
const crypto = require('crypto');
const computeHash = (clientSecret, message) => {
const key = Buffer.from(clientSecret, 'utf8');
const hmac = crypto.createHmac('sha256', key);
const hash = hmac.update(message, 'utf8').digest('base64');
return hash;
}
const timeStamp = "<<Timestamp>>" // Timestamp from Webhook Headers
const clientId = "<<TaxBandits Client Id>>" // Taxbandits consite site - Client Id
const clientSecret = "<<TaxBandits Client Secret>>"; // Taxbandits consite site - Client Secret
const message = clientId + '\n' + timeStamp;
// Compare this Signature with the Webhook Header Signature
console.log("Signature: ", computeHash(clientSecret, message));
using System.Security.Cryptography;
using System.Text;
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
string timeStamp = "<<Timestamp>>"; // Timestamp from Webhook Headers
string clientId = "<<TaxBandits Client Id>>"; // Taxbandits consite site - Client Id
string clientSecret = "<<TaxBandits Client Secret>>"; // Taxbandits consite site - Client Secret
string message = string.Join("\n", clientId, timeStamp);
dynamic key = Encoding.UTF8.GetBytes(clientSecret);
string hashString;
using (dynamic hmac = new HMACSHA256(key))
{
dynamic hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
// Compare this Signature with the Webhook Signature
Console.WriteLine(String.Format("Signature: {0}", hashString));
}
}
require 'openssl'
require 'base64'
def compute_hash(client_secret, message)
key = client_secret.encode('utf-8')
hmac = OpenSSL::HMAC.new(key, 'sha256')
hmac.update(message)
Base64.strict_encode64(hmac.digest)
end
time_stamp = "<<Timestamp>>" # Timestamp from Webhook Headers
client_id = "<<TaxBandits Client Id>>" # Taxbandits consite site - Client Id
client_secret = "<<TaxBandits Client Secret>>" # Taxbandits consite site - Client Secret
message = "#{client_id}\n#{time_stamp}"
# Compute the hash and print it
signature = compute_hash(client_secret, message)
# Compare this Signature with the Webhook Header Signature
puts "Signature: #{signature}"
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class ComputeHash {
public static String computeHash(String clientSecret, String message) throws Exception {
byte[] keyBytes = clientSecret.getBytes(StandardCharsets.UTF_8);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] rawHash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(rawHash);
}
public static void main(String[] args) {
String timeStamp = "<<Timestamp>>"; // Timestamp from Webhook Headers
String clientId = "<<TaxBandits Client Id>>"; // Taxbandits consite site - Client Id
String clientSecret = "<<TaxBandits Client Secret>>"; // Taxbandits consite site - Client Secret
String message = clientId + "\n" + timeStamp;
try {
// Compute the hash and print it
String signature = computeHash(clientSecret, message);
// Compare this Signature with the Webhook Header Signature
System.out.println("Signature: " + signature);
} catch (Exception e) {
e.printStackTrace();
}
}
}
import hashlib
import hmac
import base64
def compute_hash(client_secret, message):
key = client_secret.encode('utf-8')
hmac_hash = hmac.new(key, message.encode('utf-8'), hashlib.sha256)
return base64.b64encode(hmac_hash.digest()).decode('utf-8')
# Replace these placeholders with your actual values
time_stamp = "<<Timestamp>>" # Timestamp from Webhook Headers
client_id = "<<TaxBandits Client Id>>" # Taxbandits consite site - Client Id
client_secret = "<<TaxBandits Client Secret>>" # Taxbandits consite site - Client Secret
message = f"{client_id}\n{time_stamp}"
# Compute the hash and print it
signature = compute_hash(client_secret, message)
# Compare this Signature with the Webhook Header Signature
print(f"Signature: {signature}")
<?php
function computeHash($clientSecret, $message) {
$key = $clientSecret;
$hash = hash_hmac('sha256', $message, $key, true);
return base64_encode($hash);
}
// Replace these placeholders with your actual values
$timeStamp = "<<Timestamp>>"; // Timestamp from Webhook Headers
$clientId = "<<TaxBandits Client Id>>"; // Taxbandits consite site - Client Id
$clientSecret = "<<TaxBandits Client Secret>>"; // Taxbandits consite site - Client Secret
$message = $clientId . "\n" . $timeStamp;
// Compute the hash and print it
$signature = computeHash($clientSecret, $message);
# Compare this Signature with the Webhook Header Signature
echo "Signature: " . $signature . "
";
?>
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
)
func computeHash(clientSecret string, message string) string {
key := []byte(clientSecret)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func main() {
timeStamp := "<<Timestamp>>" // Timestamp from Webhook Headers
clientId := "<<TaxBandits Client Id>>" // Taxbandits consite site - Client Id
clientSecret := "<<TaxBandits Client Secret>>" // Taxbandits consite site - Client Secret
message := fmt.Sprintf("%s\n%s", clientId, timeStamp)
// Compute the hash and print it
signature := computeHash(clientSecret, message)
// Compare this Signature with the Webhook Header Signature
fmt.Println("Signature:", signature)
}