Webhooks
Instead of constantly checking the API, use webhooks to receive instant HTTP notifications about events. This allows you to automate your workflows, such as updating an invoice as "Paid" when you get a mandate.debit.successful event, crediting a user's balance upon receiving an inwards.completed event, or triggering an alert if a transfer.failed.
Overview of Webhooks
Webhooks are used to notify your application in real-time when specific events occur in the API. Instead of polling the API for updates, you can set up a webhook URL where the API sends HTTP POST requests containing event details.
How to Set Up Webhooks
-
Register Your Webhook URL: You can update your webhook URL via the merchant dashboard, on the API Keys and Webhooks page (Home -> Settings -> API Keys and Webhooks). This can be done for the live and sandbox environments.
-
Handle Retries: Ensure your webhook endpoint is idempotent and capable of handling retries in case of delivery failures.
Webhook Event Structure
All webhook events share a common structure for consistency:
Webhook event structure
{
"event": "event_name",
"timestamp": "2024-12-06T14:00:00Z",
"data": {
"event-specific-payload"
}
}
Event Types
- Name
transfer.completed- Description
Triggered when a transfer is successfully completed.
- Name
transfer.failed- Description
Triggered when a transfer fails.
- Name
inwards.completed- Description
Triggered when an inward transfer is completed.
- Name
mandate.created- Description
Triggered when a mandate is created.
- Name
mandate.confirmed- Description
Triggered when a mandate is confirmed.
- Name
mandate.debit.initiated- Description
Triggered when a mandate debit is initiated.
- Name
mandate.debit.failed- Description
Triggered when a mandate debit fails.
- Name
mandate.debit.successful- Description
Triggered when a mandate debit is successful.
Example: Transfer Completed
{
"event": "transfer.completed",
"timestamp": "2024-12-06T14:00:00Z",
"data": {
"id": "7b129bdd-b3c1-4a33-b80e-76cee553466f",
"narration": "Payment for order",
"status": "Success",
"amount": 10000,
"fee": 0,
"externalReference": "order-12345",
"currency": "NGN",
"sessionId": null,
"senderName": "Merchant Name",
"senderBank": "Aella MFB",
"senderAccountNumber": "0242438865",
"receiverName": "JOHN DOE",
"receiverBank": "GTBANK PLC",
"receiverAccountNumber": "0480819436",
"receiverBankCode": "000013",
"environment": "LIVE",
"createdAt": "2025-03-25T10:17:00.380Z",
"updatedAt": "2025-03-25T10:17:00.380Z"
}
}
Sample Webhook Events
Transfer Completed (transfer.completed)
This event is triggered when a transfer is successfully completed.
Transfer Completed Payload
{
"event": "transfer.completed",
"timestamp": "2024-12-06T14:00:00Z",
"data": {
"id": "7b129bdd-b3c1-4a33-b80e-76cee553466f",
"narration": "Payment for order",
"status": "Success",
"amount": 10000,
"fee": 0,
"externalReference": "order-12345",
"currency": "NGN",
"sessionId": null,
"senderName": "Merchant Name",
"senderBank": "Aella MFB",
"senderAccountNumber": "0242438865",
"receiverName": "JOHN DOE",
"receiverBank": "GTBANK PLC",
"receiverAccountNumber": "0480819436",
"receiverBankCode": "000013",
"environment": "LIVE",
"createdAt": "2025-03-25T10:17:00.380Z",
"updatedAt": "2025-03-25T10:17:00.380Z"
}
}
Inwards Transfer (inwards.completed)
This event is triggered when an inward transfer is completed.
Inwards Completed Payload
{
"event": "inwards.completed",
"timestamp": "2025-06-26T11:37:51.894Z",
"data": {
"id": "9e8ed5c7-3faf-49e6-afd3-1bacc9090ec8",
"narration": null,
"status": "Success",
"amount": 100,
"fee": 0,
"externalReference": "payment-ref-123",
"currency": "NGN",
"sessionId": "090614447739340718791499120552",
"senderName": "GBOLUWAGA AFOLABI ADEYEMI",
"senderBank": "GTBANK PLC",
"senderAccountNumber": "0480819436",
"receiverName": "Merchant/Account Name",
"receiverBank": "Aella Microfinance Bank",
"receiverAccountNumber": "0376236159",
"receiverBankCode": "090416",
"environment": "LIVE",
"source": "DYNAMIC_VIRTUAL",
"sourceWallet": "9f9fe6c7-3faf-49e6-afd3-1bacc9090ec8",
"createdAt": "2025-06-26T11:37:51.446Z",
"updatedAt": "2025-06-26T11:37:51.446Z"
}
}
Mandate Debit Successful (mandate.debit.successful)
This event is triggered when a mandate debit is successful.
Mandate Debit Successful Payload
{
"event": "mandate.debit.successful",
"timestamp": "2025-06-26T11:37:51.894Z",
"data": {
"mandate": {
"id": "9e8ed5c7-3faf-49e6-afd3-1bacc9090ec8",
"confirmationStatus": "CONFIRMED",
"status": "ACTIVE",
"bankAccount": {
"id": "9e8ed5c7-3faf-49e6-afd3-1bacc9090ec8"
},
"createdAt": "2025-06-26T10:37:51.894Z"
},
"transaction": {
"id": "9e8ed5c7-3faf-49e6-afd3-1bacc9090ec8",
"amount": 200,
"status": "successful",
"finalResponseCode": "00",
"narration": "Subscription payment",
"providerId": "23421e0b-d23c-4145-2355-cc2e47023e91",
"mandateId": "4e71cbf2-9a6c-4168-8070-2c982e65f3ce",
"sessionId": null,
"responseCode": "00",
"createdAt": "2025-08-26T16:20:55.862Z",
"fee": 2.14
}
}
}
Webhook Best Practices
-
Validate Payload: Decrypt and validate the webhook payload using the secret key provided on your merchant dashboard.
-
Respond Quickly: Respond with a
2xxstatus code to acknowledge receipt. Avoid lengthy processing in the webhook handler. -
Log Events: Maintain a log of all webhook events for troubleshooting and auditing.
-
Idempotency: Ensure your webhook handler is idempotent to handle duplicate deliveries gracefully.