Bank transfer

Hey👋. We recommend checking out the overview to understand the basics of direct charge first. This guide assumes you've read that.

Direct charge via bank transfer allows you to generate account details (account number and bank) on demand to receive payments from customers via bank transfer.

Bank transfer is currently only supported for NGN transactions.


Collecting payments via bank transfer charge is straightforward:

  • You call the bank transfer charge endpoint to create a charge and generate account details for the customer to pay into
  • The customer transfers to the generated account
  • We send you a webhook notifying you that we've received the payment
  • You verify the payment and complete the customer's order.

Initiating the charge

To initiate the charge, you'll call the bank transfer charge endpoint, which is supported in some of our backend SDKs. You'll need to specify:

  • email: the customer's email
  • currency (currently always "NGN")
  • amount
  • tx_ref: a unique reference code for this transaction
// Install with: npm i flutterwave-node-v3

const Flutterwave = require('flutterwave-node-v3');
const flw = new Flutterwave(process.env.FLW_PUBLIC_KEY, process.env.FLW_SECRET_KEY);
const details = {
    tx_ref: "MC-1585230950508",
    amount: "1500",
    email: "",
    currency: "NGN",
const response = await flw.Charge.bank_transfer(details);
# Install with: gem install flutterwave_sdk

require 'flutterwave_sdk'

charge_transfer =
details = {
    tx_ref: "MC-1585230950508",
    amount: "1500",
    email: "",
    currency: "NGN",
response = charge_transfer.initiate_charge details
curl --request POST \
   --url \
   --header 'Authorization: Bearer YOUR_SECRET_KEY' \
   --header 'content-type: application/json' \
   --data '{
      "tx_ref": "MC-1585230950508",
      "amount": "1500",
      "email": "",
      "currency": "NGN"

You can also specify a list of subaccounts to split the payment into:

  "tx_ref": "MC-1585230950508",
  "amount": "1500",
  "email": "",
  "currency": "NGN",
+ "subaccounts": [
+   {
+     "id": "RS_D87A9EE339AE28BFA2AE86041C6DE70E"
+   }
+ ]

See split payments for details.

There are more options available when initiating a bank transfer charge, such as the customer's phone_number and additional meta. See the endpoint docs for details.

If the charge is created successfully, you'll get a success response containing the generated account details.

  "status": "success",
  "message": "Charge initiated",
  "meta": {
    "authorization": {
      "transfer_reference": "N/A",
      "transfer_account": "7825397990",
      "transfer_bank": "WEMA BANK",
      "account_expiration": "N/A",
      "transfer_note": "N/A",
      "transfer_amount": 1500,
      "mode": "banktransfer"

Completing the payment

The meta.authorization object contains the account details for the transfer: the bank name (transfer_bank), account number (transfer_account), and amount (transfer_amount). Pass the details on to your customer, and they can make a transfer into the account (for instance, from their bank app).

Testing tip

In Test Mode, all bank transfers will automatically be paid after a few seconds.

When payment is made, we'll send you a webhook with a payload like this:

  "event": "charge.completed",
  "data": {
    "id": 407347576,
    "tx_ref": "MC-1585230950508",
    "flw_ref": "000016210415121239000082517439",
    "device_fingerprint": "7852b6c97d67edce50a5f1e540719e39",
    "amount": 1500,
    "currency": "NGN",
    "charged_amount": 10,
    "app_fee": 0.14,
    "merchant_fee": 0,
    "processor_response": "success",
    "auth_model": "AUTH",
    "ip": "N/A",
    "narration": "Globus Technologies",
    "status": "successful",
    "payment_type": "bank_transfer",
    "created_at": "2021-04-15T11:13:10.000Z",
    "account_id": 82913,
    "customer": {
      "id": 254967086,
      "fullname": "Anonymous Customer",
      "phone_number": null,
      "email": "",
      "created_at": "2021-04-14T16:39:17.000Z"
    "meta": {
      "originatoraccountnumber": "000*******44",
      "originatorname": "tester",
      "bankname": "TEST BANK",
      "originatoramount": "N/A"

if you specified a tx_ref when creating the account, the reference field will be set to that value. If you didn't set one, we'll generate a random value for that.

Now your webhook endpoint can handle the event and complete the customer's order. For help setting up webhooks, see our guide to webhooks.