What is Collections?
Collections solves a specific problem: how do you know who paid you? If you give all your customers one bank account number to transfer money into, you end up with a list of incoming debits and no automatic way to match each credit to a specific customer. You’d have to manually compare names and amounts — error-prone and unscalable. Collections gives every customer their own unique account number. When money arrives, it is already sorted. You know immediately who paid, how much, and for what — because the account number itself carries that information.Real-World Use Cases
Wallet Top-Up
Assign one permanent (static) collection account per customer when they sign up. Their account number never changes. Whenever they want to add money, they transfer to the same number from their bank.
Invoice Payment
When you generate an invoice, create a dynamic collection account linked to that invoice. Set it to expire in 48 hours. When the customer pays, the webhook tells you exactly which invoice was settled.
Event Tickets / Orders
When a customer places an order or buys a ticket, generate a dynamic account for that order. It expires once paid or after a timeout. No manual reconciliation needed.
How It Works End to End
Create a collection account
You call our API to create a virtual account. For a static account, you do this once per customer. For a dynamic account, you do this once per invoice or order.See the Virtual Accounts guide for the full create API — collections use the same endpoint. Pass your customer ID or order reference in the
reference field so it comes back in the webhook.Share the account number with your customer
Display the account number, bank name (Union Bank of Nigeria), and account name to your customer. They can then initiate a transfer from any Nigerian bank — mobile app, internet banking, USSD, or at a branch.
Customer transfers money
Your customer sends the money from their own bank. The transfer travels through the Nigerian Interbank Settlement System (NIBSS) — the same network behind every bank transfer in Nigeria.
We receive the credit
The money arrives in your master Union Bank account and is attributed to the virtual account number your customer transferred to.
Your webhook receives a notification
Within seconds of the credit landing, we send an HTTP POST request to your registered webhook URL. The payload contains everything you need: who paid, how much, from which bank, and the reference you attached.
The Webhook Payload
When money arrives in a collection account, your webhook endpoint receives a POST request with this body:| Field | What it means |
|---|---|
event | The type of event. Always check this — your endpoint may receive multiple event types. |
data.accountNumber | The collection account number that received the money. Use this to find which customer or order it belongs to. |
data.amount | The amount received, in Naira. |
data.senderName | The account holder name at the sending bank. |
data.senderAccountNumber | The account number the sender transferred from. |
data.senderBankCode | The CBN bank code of the sender’s bank (e.g. 058 = GTBank). |
data.narration | The description the sender included on the transfer. |
data.transactionRef | Our unique reference for this transaction. Store this — use it for reconciliation and disputes. |
data.timestamp | When the credit was confirmed, in ISO 8601 format with timezone offset. |
Verify Webhook Authenticity
You must verify every webhook before acting on it. Anyone who knows your webhook URL could send you fake payment notifications. TheX-Signature header lets you confirm the request genuinely came from us.
We compute the signature by running an HMAC-SHA256 hash over the raw request body using your webhook secret. You reproduce the same computation on your side and compare the results.
- JavaScript (Node.js)
- Python (Flask)
Why
express.raw instead of express.json? You must verify the signature against the exact raw bytes of the body. If Express parses the JSON first and then re-stringifies it, the bytes may differ (e.g. key ordering, whitespace) and your signature check will fail. Always read the raw body for webhook verification.View Transaction History
Pull a list of all credits received across your collection accounts, or filtered to a single account:Reversal Handling
Occasionally a credit that arrived in a collection account may be reversed. This happens when the sending bank discovers an error on their end (e.g. the sender’s account had insufficient funds but the transfer was processed optimistically, or a fraud flag is raised). When a reversal happens, you will receive acollection.reversal webhook event:
- Check your records using
originalTransactionRefto find the credit you previously processed. - Reverse any action you took — for example, deduct the credited amount from the customer’s wallet.
- Notify the customer that the payment was reversed and they need to retry.
- Do not re-credit until a new
collection.creditevent arrives for a fresh payment.
Reversals are relatively rare in the Nigerian interbank system but do happen. Building reversal handling from the start will save you painful manual corrections later.