Webhook signature verification

To ensure the authenticity and integrity of incoming webhook data, every request we send includes a signature header. This signature is a cryptographic hash generated using the webhook payload and a shared secret known only to you and our system.

Verifying this signature on your end helps confirm that the payload:

  1. Was not tampered with during transmission.
  2. Was genuinely sent from our system.
  3. Is safe to trust and process.

There are 2 essentials steps to follow to ensure a proper signature verification. They are as follows;

1. Generate HMAC

Generate a secure Hash-based Message Authentication Code (HMAC) signature by applying a cryptographic hash function to the payload using a shared secret, ensuring data integrity.

2. Verify webhook integrity

Verify the integrity of incoming data by comparing the computed HMAC signature with the received signature, ensuring a match to establish the authenticity of the webhook payload.

View sample code

The tab below contains sample code demonstrating how to calculate the HMAC signature and compare it with the signature sent via the webhook.

To compare and calculate examples are presented side-by-side for better comparison and understanding.

 package main
 import (
         "crypto/hmac"
         "crypto/sha256"
         "encoding/hex"
         "fmt"
 )

 func main() {
         signatureKey := "your_secret_key" // Replace with your actual signature key
         payload := map[string]interface{}{
                 "event_type": "some_event",
                 "requestId": "12345",
                 // ... other payload fields
         }
         timestamp := "1690646400" // Replace with actual timestamp

         hashingPayload := fmt.Sprintf("%s:%s:%s:%s:%s:%s:%s:%s",
                 payload["event_type"],
                 payload["requestId"],
                 payload["data"]["merchant"]["userId"],
                 payload["data"]["merchant"]["walletId"],
                 payload["data"]["transaction"]["transactionId"],
                 payload["data"]["transaction"]["type"],
                 payload["data"]["transaction"]["time"],
                 payload["data"]["transaction"]["responseCode"])

         message := fmt.Sprintf("%s:%s", hashingPayload, timestamp)

         mac := hmac.New(sha256.New, []byte(signatureKey))
         mac.Write([]byte(message))
         hashed := mac.Sum(nil)
         digest = base64.StdEncoding.EncodeToString(hashed)
}