Skip to main content

Webhook integration

Validate webhook notification signature

If HMAC is generated while creating a webhook - which is strongly advised - a signature will be generated and included in the payload for each notification. This allows integrators to validate that the request comes from Enviso, and has not been tampered with before processing it.

Procedure to verify the signature:
  1. Concatenate the values for id, tenant, event, and timestamp in the format id|tenant|event|timestamp

  2. Create a SHA256 hash of this concatenated value.

  3. Compare this value with the signature of the payload. If they are equal, then the notification can be considered valid, and the notification can be processed.

Sample code for C# .Net

Sample code that demonstrates how to generate a signature of the notification payload.

using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System;

public static class Generator
{
    private const string SignaturePayloadSeparator = "|";
    private const string HmacKey = "<HMAC key>"; // Hmac key which was generated while creating webhook

    public static void Main(string[] args)
    {
        var notificationId ="<notification id>"; // 'id' from response payload
        var tenantkey = "<tenant key>"; // 'tenant' from response payload
        var eventName = "<event name>"; // 'event' from response payload
        var timestamp = "<timestamp>"; // 'timestamp' from response payload

        var payload = CreateSignaturePayload(notificationId, tenantkey, eventName, timestamp);
        var data = CreateSignature(payload);
        var signature = Convert.ToBase64String(data);
        Console.WriteLine($"signature is : {signature}");
    }

    private static string CreateSignaturePayload(string notificationId, string tenant, string eventName, string timestamp)
    {
        var interpolatedStringHandler = new DefaultInterpolatedStringHandler(3, 4);
        interpolatedStringHandler.AppendFormatted(notificationId);
        interpolatedStringHandler.AppendLiteral(SignaturePayloadSeparator);
        interpolatedStringHandler.AppendFormatted(tenant);
        interpolatedStringHandler.AppendLiteral(SignaturePayloadSeparator);
        interpolatedStringHandler.AppendFormatted(eventName);
        interpolatedStringHandler.AppendLiteral(SignaturePayloadSeparator);
        interpolatedStringHandler.AppendFormatted(timestamp);
        return interpolatedStringHandler.ToStringAndClear();
    }

    private static byte[] CreateSignature(string payload)
    {
        // Convert the HEX key to a byte array that can be used as key for HMACSHA256
        var key = Encoding.UTF8.GetBytes(HmacKey);

        // Convert the payload to byte array that can be used as input to compute the hash
        var buffer = Encoding.UTF8.GetBytes(payload);

        // Create new HMACSHA256 object and compute the hash
        var hmac = new HMACSHA256(key);
        var hash = hmac.ComputeHash(buffer);

        // Base64 encode the hash and return the result
        return Encoding.UTF8.GetBytes(Convert.ToBase64String(hash));
    }
}

Sample test notification payload

{
  "id": "8172849c-e676-4c2a-8be8-2824cf41efa0",
  "tenant": "********",
  "event": "ORDER_CREATED",
  "timestamp": "2023-08-11T14:09:41.933Z",
  "data": {
    "id": "test"
  },
  "signature": "K0Z4V2lkM2pIaHpZdUNES3ZPRHJhcWNIaVFIN1R1SXpuZUgvSXBmMUtEQT0="
}

Sample real notification payload

{
  "id": "8172849c-e676-4c2a-8be8-2824cf41efa0",
  "tenant": "**********",
  "event": "ORDER_CREATED",
  "timestamp": "2023-08-11T14:09:41.933Z",
  "data": {
    "id": "1001"
  },
  "signature": "K0Z4V2lkM2pIaHpZdUNES3ZPRHJhcWNIaVFIN1R1SXpuZUgvSXBmMUtEQT0="
}