Getting Started

NOTE: This collection method is only available for Kenya and Nigeria.

1 - Create Virtual Account

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.

FieldTypeRequiredDescription
amountNumberAmount to be charged to the virtual account (e.g. 1000)
currencyStringCurrency code (e.g. KES, NGN)
externalReferenceStringYour own unique ID for reconciliation (e.g. invoice number)
emailStringEmail 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

JSON
{  
  "amount": 1000,  
  "currency": "NGN",  
  "externalReference": "invoice_5678",  
  "email": "[[email protected]](mailto:[email protected])"  
}

Below is an example of the response:

Success
{  
  "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.

2 - Display Account Details to Customer

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.

3 - Get Transaction Status

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:

SuccessFailed
{  
  "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"  
  }  
}

`

4 - Handle Webhooks

Configure webhooks to receive real-time transaction updates instead of polling the status endpoint.

Setup

  1. Configure your webhook URL in your dashboard account.
  2. Implement webhook endpoint security and validation.
  3. Handle the webhook notifications in your application.

Here's a sample of the webhook response:

Transaction CreatedTransaction SuccessfulTransaction Failed
{  
  "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"  
}

5 - Handle Virtual Account Expiration

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.

Best Practices

  • 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