Collection webhooks
The Collection Webhook is used by LedgerBlock to notify your application when a collection transaction is received and its status changes. This allows your system to update the customer's balance, wallet, order, or transaction record automatically without repeatedly querying the collection API.
When a customer transfers money to a LedgerBlock collection account, LedgerBlock processes the incoming payment and sends a webhook request to the webhook URL configured by the merchant.
How a Collection Webhook Works
The collection flow is:
- A customer sends money to a LedgerBlock collection account.
- The payment is received and processed by LedgerBlock.
- LedgerBlock determines the transaction status.
- LedgerBlock sends a
POSTrequest to your configured webhook URL. - The request contains transaction information in the JSON body.
- LedgerBlock includes an
x-ledgerblock-signatureheader with the request. - Your server verifies the signature before processing the webhook.
- After successful verification, your application updates the corresponding transaction or user account.
Collection Webhook Request
A collection webhook is sent as an HTTP request with a JSON payload.
From the webhook request captured in the example:
{
"account_number": "0749711214",
"wallet_id": "LBNGNG...",
"tx_ref": "Q-live_0012",
"amount": 100,
"payment_status": "SUCCESSFUL",
"payment_channel": "BANK_TRANSFER",
"sender": {
"accountNumber": "15",
"bankCode": "090405",
"bankName": "Moniepoint Microfinance Bank",
"name": "TESLIM AYANTOLA"
}
}Request Headers
The webhook request contains headers that provide information about the request and, most importantly, allow your application to verify that the webhook came from LedgerBlock.
Example:
Content-Type: application/json
x-ledgerblock-signature: <signature>The x-ledgerblock-signature should be verified before your application processes any information in the webhook payload.
Collection Webhook Payload
| Field | Type | Description |
|---|---|---|
account_number | String | Collection account number that received the payment. |
wallet_id | String | LedgerBlock wallet associated with the collection account. |
tx_ref | String | Unique reference identifying the collection transaction. |
amount | Number | Amount received for the transaction. |
payment_status | String | Current status of the collection transaction. |
payment_channel | String | Channel through which the payment was received. In the example, this is BANK_TRANSFER. |
sender | Object | Contains details of the account that initiated the payment. |
sender.accountNumber | String | Account number of the sender. |
sender.bankCode | String | Bank code of the sender's financial institution. |
sender.bankName | String | Name of the sender's bank or financial institution. |
sender.name | String | Name associated with the sender's bank account. |
Payment Status
The payment_status field tells your application the current state of the collection transaction.
For example:
"payment_status": "SUCCESSFUL"When the status is SUCCESSFUL, your application can treat the collection as successfully received, subject to your normal transaction validation and reconciliation rules.
Your application should not rely only on the HTTP request arriving successfully. The webhook signature should be verified first.
Transaction Reference
The tx_ref is particularly important when handling collections.
"tx_ref": "Q-live_0012"Use this reference to identify the corresponding transaction in your system. This allows your application to reconcile the webhook with the transaction that was originally created or expected.
For example, your application can use tx_ref to:
- Find the pending transaction.
- Confirm the amount received.
- Update the transaction status.
- Record the payment channel.
- Trigger the appropriate business logic.
Wallet Identification
The wallet_id identifies the LedgerBlock wallet associated with the collection.
"wallet_id": "LBNGNG..."This allows your application to determine which wallet should be credited or which wallet the incoming collection belongs to, depending on your integration.
Collection Account
The account_number identifies the LedgerBlock collection account that received the payment.
"account_number": "0749711214"This is useful when multiple collection accounts are being used. Your application can use the account number to determine which customer, wallet, or account the payment should be associated with.
Sender Information
LedgerBlock also provides information about the account that sent the money:
"sender": {
"accountNumber": "15",
"bankCode": "090405",
"bankName": "Moniepoint Microfinance Bank",
"name": "TESLIM AYANTOLA"
}This information can be used for payment reconciliation and displaying payer details in your application.
Verifying the Collection Webhook
Before processing the collection payload, your server should verify the x-ledgerblock-signature.
The recommended processing flow is:
Receive webhook
↓
Read raw request body
↓
Read x-ledgerblock-signature
↓
Generate expected signature
↓
Compare signatures
↓
Signatures match?
↙ ↘
Yes No
↓ ↓
Process Reject request
webhookThe important point is that the raw request body should be used when generating the signature. Parsing and re-serializing the JSON before verification can change the payload representation and cause signature verification to fail.
Processing a Successful Collection
Once the webhook signature has been verified and the transaction status is SUCCESSFUL, your application can process the payment.
A typical flow would be:
Webhook received
↓
Verify signature
↓
Check tx_ref
↓
Find transaction
↓
Confirm payment status
↓
Confirm amount
↓
Update transaction
↓
Credit/update user balance
↓
Return 2xx responseYour application should also ensure that the same transaction is not processed twice. The tx_ref can be used as a transaction identifier when implementing this protection.
Example
Suppose a customer sends ₦100 to the collection account:
{
"account_number": "0749711214",
"wallet_id": "LBNGNG...",
"tx_ref": "Q-live_0012",
"amount": 100,
"payment_status": "SUCCESSFUL",
"payment_channel": "BANK_TRANSFER",
"sender": {
"accountNumber": "15",
"bankCode": "090405",
"bankName": "Moniepoint Microfinance Bank",
"name": "TESLIM AYANTOLA"
}
}Your backend receives the webhook, verifies the x-ledgerblock-signature, finds transaction Q-live_0012, confirms that the payment status is SUCCESSFUL, and then updates the relevant customer or wallet record.
Webhook Response
After receiving and successfully processing the webhook, your application should return a successful HTTP response to LedgerBlock.
For example:
200 OKThe acknowledgement tells LedgerBlock that your application received the webhook successfully.
Important Considerations
Verify the signature before processing the payload. Never assume a request is genuine simply because it was sent to your webhook URL.
Use tx_ref for reconciliation. Match the webhook transaction against the transaction in your own system before updating balances.
Validate the amount. Do not credit an account based solely on the transaction reference; confirm that the received amount matches the expected transaction.
Handle duplicate notifications safely. Your application should be idempotent so that receiving the same webhook more than once does not credit the customer multiple times.
Return a successful response after processing. This confirms that your application received the notification.
One thing I would keep separate in the final LedgerBlock documentation is the exact signature-generation formula. The screenshot confirms that x-ledgerblock-signature is being sent, but it does not expose enough information to accurately document whether LedgerBlock uses HMAC-SHA256, plain hashing, what secret is used, or the exact string-to-sign. That part should come from the actual LedgerBlock webhook implementation rather than being assumed.
Updated 26 days ago

