How To Validate Webhooks

Merchants will be able to validate webhooks received from the Fincra platform using this feature. A signature is included in the headers of every webhook sent, which is the webhook data encrypted with the merchants.

Validating On The Merchant’s End

Merchant can run the same data encryption on their end using their secret key and comparing the result with the signature that was sent. If they match, then the merchant can go ahead to process. If it isn't a match, the merchant is expected to discard and not process the Webhook.

import crypto from "crypto";

const encryptedData =  crypto
      .createHmac("SHA512", merchantWebhookSecretKey)
      .update(JSON.stringify(payload)) 
      .digest("hex");
const signatureFromWebhook = req.headers['signature'];

if(encryptedData === signatureFromWebhook) {
  console.log("process");
}
else {
  console.log("discard");
}
import hmac
import hashlib
import json

def encrypt_webhook_data():
    webhook_secret_key = "The webhook secret key"
    payload = "The webhook payload"
    
    #encode the webhook key and save it in a variable
    key = webhook_secret_key.encode("utf-8")
    
    #convert the payload into serialized json 
    message = json.dumps(payload, separators=(',', ':')).encode("utf-8")

    #encrypt the payload
    encrypted_data = hmac.new(key, message, hashlib.sha512).hexdigest()

    #get the signature from the header
    signature = req.headers['signature'];
    
    #check signature authencity
    if signature == encrypted_data:
        print("process")
    else:
        print("discard!")
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import org.json.*;

public class WebhookEncrypter {
    public static void encryptWebhookData() {
        String webhookSecretKey = "The webhook secret key";
        String payload = "The webhook payload";

        // encode the webhook key and save it in a variable
        byte[] key = webhookSecretKey.getBytes(StandardCharsets.UTF_8);

        // convert the payload into serialized JSON
        String message = new JSONObject(payload).toString();

        // encrypt the payload
        Mac sha512Hmac;
        try {
            sha512Hmac = Mac.getInstance("HmacSHA512");
            SecretKeySpec secretKey = new SecretKeySpec(key, "HmacSHA512");
            sha512Hmac.init(secretKey);
            byte[] hmacData = sha512Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8));
            String encryptedData = bytesToHex(hmacData);

            // get the signature from the header
            String signature = req.getHeader("signature");

            // check signature authenticity
            if (signature.equals(encryptedData)) {
                System.out.println("process");
            } else {
                System.out.println("discard!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }
}

NOTE

  • The payload is an object that contains the event and data fields of the webhook notification. Please see a sample payout webhook notification data for more details on the structure of our webhooks.
  • Fincra events (Payouts, Conversions, Virtual Account,and Collections) carry a signature header. The event payload is a HMAC SHA512 signature signed with your webhook secret key is the value of this header. Before processing the event, confirm the header signature.

Get Webhook Secret Key

The webhook secret key can be obtained from the Fincra platform, Please see below for Merchants to view and obtain their secret key.

3360