Generate Webhook Signature Hash
Overview:
A Signature Hash is a cryptographic mechanism used to authenticate API requests and ensure that the payload has not been altered during transmission. It is generated using a secret key and a hashing algorithm, commonly HMAC-SHA256, to create a signature that proves the integrity and authenticity of the request.
Usage:
The Signature Hash is included in the headers of the API request (i.e., x-signature) to allow your server to verify that the request comes from (Miden) and that the payload has not been tampered with. Your server computes its own hash using your webhook hash and compares it to the hash sent by Miden. If they match, the request is validated.
How to Generate:
To guarantee secure, cross-language verification of webhook messages, signatures must be computed using the exact value from the webhook request with formating
Steps to Generate a Signature
1
Concatenate the eventId & eventTime properties
Concatenate the eventId and eventTime proerties string cancatString = $"{eventId}&{eventTime}";.
2
Convert Raw JSON to Bytes
Convert the cancatenated string to a sequence of bytes using UTF-8 encoding.
3
Compute the Signature
- Use the HMAC-SHA256 algorithm (or the algorithm specified by your API) with your shared secret key and the raw JSON byte sequence.
- The output will be a sequence of bytes (the signature).
4
Format the Signature
- Convert the signature bytes to a lowercase hexadecimal string (remove any dashes or spaces between bytes).
- This final string is the signature hash.
Steps to Verify a Signature (on Receiver Side)
1
Read the Raw HTTP Header
Obtain the value for x-signature in the HTTP request header.
2
Compare Signatures
- Convert your computed signature to a lowercase hexadecimal string.
- Compare this value with the signature received in the request header.
- If they match exactly, the webhook is verified and untampered.
Sample:
string webhookHash = "mySecret";
webhookPayload = {
"cardId": "217172FB-119B-4DC7-833E-08DDBFAB49D0",
"eventId": "26184906",
"eventTime": "2025-07-24 13:32:55",
"eventType": "purchase.card.withdrawal",
"eventClass": "CardWithdrawal",
"data": {
"cardId": "217172FB-119B-4DC7-833E-08DDBFAB49D0",
"amount": 1,
"reason": "Test withdrawal - F97172FB-119B-4DC7-833E-08DDBFAB49D0 Withdrawal",
"oldBalance": 610,
"newBalance": 610,
"transactionReference": "3e040fcbee624ae98e52",
"cardTransactionId": 26184906
},
"processed": false,
"uniqueKey": "6f10350b-1d00-4370-80f3-fc7b7a352e4d",
"ignoreWebhook": false,
"allowCardNegativeBalance": false,
"messageTypeName": "WebhookMessage"
}
xSignature = 97b24d88261f899f4b8a63c0b1c6dc6f58cd64e36d01c6c6f0f86c0a5bc19a08
How to set your webhook hash
Webhook hash is generated from your Miden Dashboard. Kindly for the steps below, to fetch your webhook hash:
1
Login
Log in to your account using your email address, password and 2fa Token.


2
Go to ‘Settings’ Page
From your Dashboard, click on your Settings button, on the top-right corner of your Dashboard screen.

3
Navigate to ‘Developer’ Page
From your Settings page (Profile), click on your Developer module to set your webhook hash.

- This field allows for alphanumeric characters.
- After inputting these characters, click on the Update Application button to submit these entry.

- Copy the hash after submission, for your usage.
Sample Code:
This section provides code samples demonstrating signature generation for API requests in five different programming languages: C#, JavaScript (Node.js), JAVA, PHP, and Go. Each code snippet showcases the logic for constructing the base string and generating the signature based on your API's requirements. Snippets are below:
using System;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Nodes;
class Program
{
static void Main()
{
string webhookHash = "mySecret";
string webhookPayload = @"
{
""cardId"": ""217172FB-119B-4DC7-833E-08DDBFAB49D0"",
""eventId"": ""26184906"",
""eventTime"": ""2025-07-24 13:32:55"",
""eventType"": ""purchase.card.withdrawal"",
""eventClass"": ""CardWithdrawal"",
""data"": {
""cardId"": ""217172FB-119B-4DC7-833E-08DDBFAB49D0"",
""amount"": 1,
""reason"": ""Test withdrawal - F97172FB-119B-4DC7-833E-08DDBFAB49D0 Withdrawal"",
""oldBalance"": 610,
""newBalance"": 610,
""transactionReference"": ""3e040fcbee624ae98e52"",
""cardTransactionId"": 26184906
},
""processed"": false,
""uniqueKey"": ""6f10350b-1d00-4370-80f3-fc7b7a352e4d"",
""ignoreWebhook"": false,
""allowCardNegativeBalance"": false,
""messageTypeName"": ""WebhookMessage""
}";
// Parse the JSON
var json = JsonNode.Parse(webhookPayload);
string eventId = json?["eventId"]?.ToString() ?? "";
string eventTime = json?["eventTime"]?.ToString() ?? "";
string concatString = $"{eventId}&{eventTime}";
string signature = ComputeWebhookSignature(eventId, eventTime, webhookHash);
Console.WriteLine($"Concat String: {concatString}");
Console.WriteLine($"Signature: {signature}");
}
public static string ComputeWebhookSignature(string eventId, string eventTime, string sharedSecret)
{
string cancatString = $"{eventId}&{eventTime}";
var payloadBytes = Encoding.UTF8.GetBytes(cancatString);
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(sharedSecret));
var signature = hmac.ComputeHash(payloadBytes);
return BitConverter.ToString(signature).Replace("-", "").ToLowerInvariant();
}
}
const crypto = require('crypto');
// Your webhook payload as a JS object
const webhookPayload = {
cardId: "217172FB-119B-4DC7-833E-08DDBFAB49D0",
eventId: "26184906",
eventTime: "2025-07-24 13:32:55",
eventType: "purchase.card.withdrawal",
eventClass: "CardWithdrawal",
data: {
cardId: "217172FB-119B-4DC7-833E-08DDBFAB49D0",
amount: 1,
reason: "Test withdrawal - F97172FB-119B-4DC7-833E-08DDBFAB49D0 Withdrawal",
oldBalance: 610,
newBalance: 610,
transactionReference: "3e040fcbee624ae98e52",
cardTransactionId: 26184906
},
processed: false,
uniqueKey: "6f10350b-1d00-4370-80f3-fc7b7a352e4d",
ignoreWebhook: false,
allowCardNegativeBalance: false,
messageTypeName: "WebhookMessage"
};
// Extract eventId and eventTime
const eventId = webhookPayload.eventId;
const eventTime = webhookPayload.eventTime;
// Concatenate as per your hash algorithm
const concatString = `${eventId}&${eventTime}`;
console.log("Concat String:", concatString);
const secret = "mySecret";
// Generate HMAC-SHA256 signature
const hmac = crypto.createHmac('sha256', secret);
hmac.update(concatString, 'utf8');
const signature = hmac.digest('hex');
console.log("Signature:", signature);
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
public class WebhookSignature {
public static void main(String[] args) throws Exception {
// Hardcoded values from your JSON
String eventId = "26184906";
String eventTime = "2025-07-24 13:32:55";
String secret = "mySecret";
String concatString = eventId + "&" + eventTime;
System.out.println("Concat String: " + concatString);
String signature = computeWebhookSignature(concatString, secret);
System.out.println("Signature: " + signature);
}
public static String computeWebhookSignature(String message, String secret) throws Exception {
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256Hmac.init(secretKey);
byte[] hashBytes = sha256Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8));
// Convert to lowercase hex string
StringBuilder hexString = new StringBuilder(2 * hashBytes.length);
for (byte b : hashBytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
}
// Your values extracted from the JSON payload
$eventId = "26184906";
$eventTime = "2025-07-24 13:32:55";
$secret = "mySecret";
// Concatenate eventId and eventTime with &
$concatString = $eventId . "&" . $eventTime;
echo "Concat String: $concatString\n";
// Generate HMAC-SHA256
$signature = hash_hmac('sha256', $concatString, $secret);
echo "Signature: $signature\n";
?>
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
eventId := "26184906"
eventTime := "2025-07-24 13:32:55"
secret := "mySecret"
concatString := eventId + "&" + eventTime
fmt.Println("Concat String:", concatString)
signature := computeWebhookSignature(concatString, secret)
fmt.Println("Signature:", signature)
}
func computeWebhookSignature(message, secret string) string {
h := hmac.New(sha256.New, []byte(secret))
On this page
- Generate Webhook Signature Hash