{
	"event": "payout",
	"data": {
		"sessionId": null,
		"debitAccountNumber": "0097411531",
		"creditAccountNumber": "0003433020",
		"debitAccountName": "Olufunso Olunaike",
		"creditAccountName": "OLUNAIKE OLUFUNSO ABRAHAM",
		"amount": 500.0,
		"currency": "NGN",
		"status": "Success",
		"paymentReference": "668931654633533785081478974241",
		"deliveryStatusMessage": null,
		"deliveryStatusCode": null,
		"dateOfTransaction": "0001-01-01T00:00:00"
	}
}

Overview

Webhooks allow your system to receive real-time updates from our platform. Instead of constantly checking (polling) for updates, we notify your system as soon as something happens — like a payment being made or a user completing a form. It’s like getting a text message when a delivery arrives, instead of refreshing the tracking page every 5 minutes!

How It Works

  1. You configure your webhook URL (an API endpoint on your server).
  2. We send a POST request to that URL when a payment/collection is successfully processed on behalf of you or your customer.
  3. You verify the authenticity of the webhook by using your apikey to hash the notification payload and compare with the signature attached in the headers of the webhook.
  4. If, verification is successful process the transaction data on your end — e.g., mark an order as paid - and respond to the notfication with a light response like 00 Success.
If we receive an error response from your webhook url, our system would automatically retry sending you that notification 4 times.
Here is simple example of a webhook URL
app.post('/your-url/webhook', (req, res) => {
  const event = req.body;
    // Handle the event
  res.status(200).send('OK');
});
The below is the field name of the signature header to verify the authenticity of the request. This is important for security, ensuring that the data comes from us and hasn’t been tampered with.**x-embedly-signature : sha512(notification payload, api_key)**

Sample code for payload verification

app.post("/webhook", jsonParserWithRaw, (req, res) => {
	const signature = req.headers["x-embedly-signature"];
	const rawBody = req.rawBody; 
	if (!signature || !rawBody) {
		return res.status(400).json({ error: "Missing signature or body" });
	}

    const hmac = crypto.createHmac("sha512", api_key);
    hmac.update(rawBody, "utf8");
    const computedSignature = hmac.digest("hex");


    if (computedSignature !== signature) {
    	return res.status(401).json({
    		status: "error",
    		message: "Invalid signature",
    	});
    }

    res.status(200).json({
    	status: "success",
    	message: "Webhook received and verified",
    	data: req.body,
    	timestamp: new Date().toISOString(),
    });

});

Field NameDescription
AccountNumberThe wallet account that received the payment. This belongs to your customer or business.
transactionReferenceA unique ID for the transaction. Use this to avoid duplicate processing.
TransactionAmountThe amount paid (in NGN).
FeeTransaction fee (if any). In most cases this may be 0.
SenderNameThe name of the person who sent the money.
SenderBankThe sender’s bank name.
DateOfTransactionThe timestamp of the transaction (in ISO format).
SourceThe payment channel used (e.g., NIP for real-time transfers).
DescriptionThe transfer message or narration, if any.
DC”C” for credit (money in), “D” for debit (money out). In this context, it will usually be “C”.
{
	"event": "payout",
	"data": {
		"sessionId": null,
		"debitAccountNumber": "0097411531",
		"creditAccountNumber": "0003433020",
		"debitAccountName": "Olufunso Olunaike",
		"creditAccountName": "OLUNAIKE OLUFUNSO ABRAHAM",
		"amount": 500.0,
		"currency": "NGN",
		"status": "Success",
		"paymentReference": "668931654633533785081478974241",
		"deliveryStatusMessage": null,
		"deliveryStatusCode": null,
		"dateOfTransaction": "0001-01-01T00:00:00"
	}
}