Getting Started
NOTE: This collection method is only available for Kenya and Nigeria.
To collect payments via bank transfer, you'll create a temporary virtual bank account for your customer. This account can be used to receive payments and is automatically reconciled with your Cashless account.
| Field | Type | Required | Description |
|---|---|---|---|
| amount | Number | ✅ | Amount to be charged to the virtual account (e.g. 1000) |
| currency | String | ✅ | Currency code (e.g. KES, NGN) |
| externalReference | String | ✅ | Your own unique ID for reconciliation (e.g. invoice number) |
| String | ✅ | Email address of the customer being charged |
To create a virtual account, send a request to the bank transfer endpoint with the required payment information.
Example Request:
JSON
{
"amount": 1000,
"currency": "NGN",
"externalReference": "invoice_5678",
"email": "[[email protected]](mailto:[email protected])"
}
Below is an example of the response:
{
"success": true,
"message": "Account created successfully.",
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"virtualAccount": {
"permanent": false,
"accountNumber": "1250837235",
"bankName": "78 Finance Company limited (Bank78)",
"createdAt": "2025-09-05T20:35:21+00:00",
"expiresAt": "2025-09-05T22:35:21.205979Z",
"note": "Please make a bank transfer to 78 Finance Company limited (Bank78)",
"amount": "1000",
"bankLogo": "<https://test.com">
}
}
}
Note: Use the returned transactionId (or your externalReference ) to track the transaction status. The virtual account is temporary and will expire at the time specified in expiresAt.
Once the virtual account is created, display the account details to your customer so they can complete the bank transfer. The response includes:
- Account Number: The unique account number for the transfer
- Bank Name: The name of the receiving bank
- Amount: The exact amount to transfer
- Note: Instructions for the customer
- Bank Logo: Visual identifier for the bank
Ensure your customer transfers the exact amount to the provided account details within the expiration time.
Always verify the payment status before providing value to your customer. Use the get transaction endpoint with either:
- The transactionId from the account creation response, or
- Your externalReference
Here's an example of transaction verification and response:
{
"success": true,
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"amount": 1000,
"type": "deposit",
"currency": "NGN",
"senderCurrency": "NGN",
"senderAmount": 1000,
"receiverCurrency": "NGN",
"receiverAmount": 1000,
"chargeStatus": "successful",
"status": "SUCCESSFUL",
"method": "bank",
"note": "Bank transfer received from account 1234567890",
"fullTimestamp": "2025-09-05T20:40:44+03:00",
"externalReference": "invoice_5678",
"thirdPartyReference": "BANK_REF_12345",
"accountNumber": "1250837235"
}
}
{
"success": true,
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"amount": 1000,
"type": "deposit",
"currency": "NGN",
"chargeStatus": "failed",
"status": "FAILED",
"method": "bank",
"fullTimestamp": "2025-09-05T22:40:44+03:00",
"externalReference": "invoice_5678",
"accountNumber": "1250837235"
}
}
`
Configure webhooks to receive real-time transaction updates instead of polling the status endpoint.
Setup
- Configure your webhook URL in your dashboard account.
- Implement webhook endpoint security and validation.
- Handle the webhook notifications in your application.
Here's a sample of the webhook response:
{
"event": "transaction_created",
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"status": "pending",
"type": "deposit",
"externalReference": "invoice_5678",
"method": "bank"
},
"timestamp": "2025-09-05T20:35:21.600Z"
}
{
"event": "transaction_updated",
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"status": "successful",
"type": "deposit",
"externalReference": "invoice_5678",
"method": "bank",
"amount": 1000,
"currency": "NGN"
},
"timestamp": "2025-09-05T20:40:44.600Z"
}
{
"event": "transaction_updated",
"data": {
"transactionId": "BFiR6ISntYyii9h1GUe6",
"status": "failed",
"type": "deposit",
"externalReference": "invoice_5678",
"method": "bank",
"amount": 1000,
"currency": "NGN"
},
"timestamp": "2025-09-05T22:40:44.600Z"
}
Virtual accounts created through the bank transfer endpoint are temporary and will expire at the time specified in the expiresAt field of the creation response. After expiration:
- The account can no longer receive new transfers
- Any transfers received after expiration may not be automatically reconciled
- You should create a new virtual account if the customer needs additional time to complete the transfer
If a transfer is received after account expiration, you may need to manually reconcile the transaction or contact support for assistance.
- Always verify transaction status before providing value to your customer, even if you receive a webhook notification
- Store the transactionId and externalReference for reconciliation and support purposes
- Monitor account expiration times and create new accounts if needed
- Implement proper error handling for failed transactions and expired accounts
- Use webhooks for real-time updates rather than continuously polling the status endpoint
Updated about 3 hours ago
