Webhook notifications

UNIPaaS will notify your platform of important events using webhook notifications. There are notification endpoints available for each UNIPaaS products, such as onboarding, accepting payments and paying out.

Using webhook notifications with UNIPaaS

1. Identify the webhook notifications needed to run your application

Each UNIPaaS product fires different webhook notifications to your platform. For example, if you are using the UNIPaaS vendor onboarding product, you should listen to onboarding/update webhooks, which will update your application about every vendor's onboarding status change. Use the UNIPaaS product webhook guide to subscribe to the webhook notifications you need.

2. Subscribe to webhook notifications

Use our webhooks API endpoint to subscribe to the webhook notifications you need.

3. Capture and test webhook notifications on your server

Use the UNIPaaS sandbox environment to simulate events that will trigger webhook notifications. For example, take a payment as a vendor, or go through a vendor onboarding flow, while listening to the respective webhook notifications.

4. Return 200 response code

UNIPaaS will re-send any webhook notification unless a 200 response status code is received within 10 seconds. There will be 15 webhook notification retries sent until the webhook will be invalidated. UNIPaaS will send an email notification after each 5 failed retries.

5. Verifying webhooks

To verify that the request came from UNIPaaS, compute the HMAC digest according to the following algorithm and compare it to the value in the X-Hmac-SHA256 header. If they match, then you can be sure that the webhook was sent from UNIPaaS.

Webhooks created through the API are verified by calculating a digital signature. Each webhook request includes a base64-encoded X-Hmac-SHA256 header, which is generated using the <PLATFORM_SECRET_KEY> along with the data sent in the request.

const express = require('express')
const bodyParser = require('body-parser');
const { createHmac } = require('crypto');
const app = express();

const SECRET = '<PLATFORM_SECRET_KEY>';

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(bodyParser.raw());

app.post('/webhook', function (req, res) {
  const {headers, body} = req;
  const signedHeader = headers["x-hmac-sha256"];
  const hash = createHmac('sha256', SECRET)
    .update(JSON.stringify(body))
    .digest('hex');
  const buff = new Buffer(hash);
  const calculated =  buff.toString('base64');

  if (calculated === signedHeader) {
    console.log('hook verified successfully')
  }
  else {
    console.log('failed to verify hook!')
  }

  res.send('Hello World')
})

app.listen(8080)
using System;
using System.Text;
using System.Security.Cryptography;
										
public class HashC
{	
	public static string CreateHash(string data ,string sharedSecretKey)
{
    if (String.IsNullOrEmpty(data))
    {
        return String.Empty;
    }
	var keyBytes = Encoding.UTF8.GetBytes(sharedSecretKey);
    var dataBytes = Encoding.UTF8.GetBytes(data);
	var hmac = new HMACSHA256(keyBytes);
	var hmacBytes = hmac.ComputeHash(dataBytes);
	
	StringBuilder hash = new StringBuilder(hmacBytes.Length * 2);
    for (int i = 0; i < hmacBytes.Length; i++) {
		hash.Append(hmacBytes[i].ToString("x2"));
    }
	var hex = hash.ToString();
    //retun as base64 string.
    return System.Convert.ToBase64String(Encoding.UTF8.GetBytes(hex));
}

//createdHash and receivedHash need to be base64
    public static void compreHash(string createdHash , string signedHeader)
{
    bool isHashequal = createdHash.Equals(signedHeader);
    if (isHashequal == true)
    {
     Console.WriteLine("hook verified successfully");
    }
    else{
     Console.WriteLine("failed to verify hook");
    }
}
		
public static void Main()
	{
		string receivedHash = "NWM3ZDBiYzRiNzdjYTIwNDZlNzZmMjA5MTkzNTZlYjgzZGY2NmVhYTY5MjI1MzI1NzAxZGQ5NjM4Zjc0Nzc1ZQ=="; 
		string secret = "GO6DX3FIvIu5ucXwk9rmMQ==";
        string deserializeObject = "{\"vendorId\":\"6227285317bdf46531435a71\",\"vendorName\":\"Abbey Bickmarsh Caddington\",\"acceptPayments\":false,\"receivePayout\":false,\"status\":\"STARTED\",\"onboardingStatus\":\"STARTED\",\"type\":\"individual\",\"completionRate\":75,\"pendingFields\":[{\"alias\":\"business.accountHolderName\",\"status\":\"PENDING\",\"type\":\"TEXT_FIELD\",\"label\":\"Bank Account holder name\",\"required\":true,\"errors\":null,\"value\":null},{\"alias\":\"business.bankAccount\",\"status\":\"PENDING\",\"type\":\"TEXT_FIELD\",\"label\":\"Your Bank Account Number\",\"required\":true,\"errors\":null,\"value\":null},{\"alias\":\"business.sortCode\",\"status\":\"PENDING\",\"type\":\"TEXT_FIELD\",\"label\":\"Your Sort-code\",\"required\":true,\"errors\":null,\"value\":null}]}";
		string computedHash = HashC.CreateHash(deserializeObject , secret);
	    Console.WriteLine(computedHash);
				//example: NWM3ZDBiYzRiNzdjYTIwNDZlNzZmMjA5MTkzNTZlYjgzZGY2NmVhYTY5MjI1MzI1NzAxZGQ5NjM4Zjc0Nzc1ZQ==
		HashC.compreHash(computedHash , "12345");
				//failed to verify hook
		HashC.compreHash(computedHash , computedHash);
				//hook verified successfully
	}
}

Go Next

Understand which webhooks you should use