Skip to main content

Introduction

Webhooks allow your application to be notified in real time when events occur. This guide shows how to receive and verify Deposit, Convert, and Transfer webhook events.

Receiving an Event

You need to expose an endpoint in your server to receive webhook events. Below are examples in TypeScript, Go, and Python.
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhook", (req, res) => {
  const {signature, data, event} = req.body

  console.log("Received event:", data);
  res.sendStatus(200);
});

app.listen(3000, () => console.log("Webhook server running on port 3000"));

Public Keys

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAv2ipgHLFFHgGHr9VpsPN8V1HIbCrlmTZRU/CYSDaoVX+xerJOMGX
qmwgQMQH5T81VaMw4rtIA8tT4DkJgjb+7G0x4CGK1OPdlvhEGP2mOFy02onkEnMv
uN3glVc4YKLvWDTG0KT7q9mARBIkO2Nrwy6IVHAl9pMXMJTRS22c0cIbuRmkYsGZ
trylUv50knbRSgy5EA6523+j3PPJB4TgsigGSJxJGuksaxnDQGRE558xnyw/0gJm
mAIdbxboQTGMqod/My/kAssRkUNu1QtqrsdhZmGYHS+pIPJSaxqHEy8eiTahoqqq
8KgNUfQfwduG+Kc4f/t5JHetSt1dgulmswIDAQAB
-----END RSA PUBLIC KEY-----

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAoGmOqVUxIGq92P8J5KqwJbwucsNeUwfS76saj0UPgT1IsK/mvceR
Ges7dsgE4EVx7Wsd5PPNeAfaNt8d0plBLhHRW64WFyv6jYcYp8eVdHUxWLA6p5gZ
9rGrZiwqKqunppTPlV04gdDC32rAbpAR3IMYmMJLuPy63Oumszl4qk69A1o60Son
r0KYBaRK7aQsFT9IFexicDUhrF1SohaNH/msTdvJb0SwSGiV92EhmmC2R8CL83/B
S8QC5c9PWtZ4a26CRLHe0IfaGGz8ClhlO8IFxz0cNrpoRa4JRsffezQ+RMQqCxhc
igC7wHfqZr5BtziQOYJjUknVzsd81HEYlwIDAQAB
-----END RSA PUBLIC KEY-----

Supported Events

{
  "event": "Deposit",
  "data": {
    "amount": 5001,
    "toUser": "chng",
    "currency": "NGN",
    "toAccount": "chng",
    "status": "completed",
    "sessionId": "3c58db9",
    "transactionMemo": "Mock Deposit"
  },
  "signature": "m9STu6pcsviYMfgu5JBjuR"
}

Verifying Event Source

Each webhook includes a signature that you must verify using your configured public key. Below is a verification handler pattern in TypeScript, Go, and Python.
import crypto from "crypto";

const pubKey =`-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAs7aTdI7X7yAE+9
-----END RSA PUBLIC KEY-----`

function verifySignature(pubkeyPem: string, data: string, signature: string): boolean {
  const verifier = crypto.createVerify("sha256");
  verifier.update(Buffer.from(data, "utf8"));
  verifier.end();

  return crypto.verify(
      "sha256",
      Buffer.from(data, "utf8"),
      {
        key: pubkeyPem,
        padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
      },
      Buffer.from(signature, "base64")
    );
}
const jsonData = JSON.stringify({...data})
const signature = "Sd5gurUiHNhHfPjMUT2V958xxL"
const isValid = verifySignature(pubKey, jsonData, signature)

I