Bank account charge
Hey 👋. We recommend checking out the overview to understand the basics of direct charge first. This guide assumes you've read that.
Charging bank accounts
Direct account charge allows you to collect payments directly from your customers' bank accounts.
There are three "flavours" of direct bank account charge, depending on the bank account's currency/country:
- Direct debit (for Nigerian accounts): The customer authorizes the payment with their bank, and the money is debited from their account.
- UK and EU bank account: The customer is redirected to an interface where they select their bank and authorize the payment via their bank apps.
- ACH payment (for USD and ZAR accounts)
This guide covers NG accounts (direct debit). For the others, see the guides for UK and EU bank account and ACH payments.
Process
Direct bank account debit is currently only supported for the following banks:
- Access Bank (044)
- Guaranty Trust Bank (058)
- First Bank (011)
- Sterling Bank (232)
- UBA (033)
- Zenith Bank (057)
Charging a Nigerian bank account involves three main steps:
- Initiate the payment: You send the payment details to the bank account charge endpoint.
- Authorize the charge: The customer authorizes the payment with their bank. The means of authorization will depend on the bank.
- Verify the payment: As a failsafe, you'll call our API to verify that the payment was successful before giving value (via the verify transaction endpoint).
Direct debit is different from bank transfers. In direct debit, the customer enters their account details and authorizing info on your page; in bank transfers, you give them account details, and they make a transfer to you.
Initiating the payment
First, you'll need the customer's bank account details:
- their
account_number
, and - their
account_bank
(not the actual name, but instead the code for their bank which you can get with the get banks endpoint).
Combine those with the rest of the payment details to create the payload. You'll need to specify amount
, currency
, email
, fullname
, and a unique tx_ref
. You can also specify more details, such as the customer's phone_number
and custom meta
information. See the reference documentation for details.
The currency you specify must match the account's currency. This is currently restricted to NGN
accounts.
Send these payment details to the charge NG bank accounts endpoint. Here are some examples with our SDKs:
// 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 payload = {
amount: 7500,
currency: 'NGN',
email: 'developers@flutterwavego.com',
fullname: 'Flutterwave Developers',
phone_number: '+2349012345678',
tx_ref: 'UNIQUE_TRANSACTION_REFERENCE'
}
await flw.Charge.ng(payload);
// Installation: composer require flutterwavedev/flutterwave-v3
use Flutterwave\Util\Currency;
$data = [
"amount" => 7500,
"currency" => Currency::NGN,
"tx_ref" => "UNIQUE_TRANSACTION_REFERENCE",
"redirectUrl" => "https://example_company.com/success",
"additionalData" => [
"account_details" => [
"account_bank" => "044",
"account_number" => "0690000034",
"country" => "NG"
]
],
];
$accountpayment = \Flutterwave\Flutterwave::create("account");
$customerObj = $accountpayment->customer->create([
"email" => "developers@flutterwavego.com",
"full_name" => "Flutterwave Developers",
"phone" => "+2349012345678"
]);
$data['customer'] = $customerObj;
$payload = $accountpayment->payload->create($data);
$result = $accountpayment->initiate($payload);
# Install with: gem install flutterwave_sdk
require './flutterwave_sdk'
flw = Flutterwave.new(ENV["FLW_PUBLIC_KEY"], ENV["FLW_SECRET_KEY"], ENV["FLW_ENCRYPTION_KEY"])
account_payment = AccountPayment.new(flw)
payload = {
"account_bank": "044",
"account_number": "0690000037",
"amount": "7500",
"currency": "NGN",
"email": "developers@flutterwavego.com",
"fullname": "Flutterwave Developers",
"phone_number": "+2349012345678",
"tx_ref": "UNIQUE_TRANSACTION_REFERENCE",
"redirect_url": "https://example_company.com/success"
}
# Automatically uses the right endpoint based on the currency
response = account_payment.initiate_charge(payload)
curl --request POST \
--url https://api.flutterwave.com/v3/charges?type=debit_ng_account \
--header 'Authorization: Bearer FLW_SECRET_KEY' \
--header 'content-type: application/json' \
--data '{
"amount": 7500,
"currency": "NGN",
"email": "developers@flutterwavego.com",
"fullname": "Flutterwave Developers",
"phone_number": "+2349012345678",
"tx_ref": "UNIQUE_TRANSACTION_REFERENCE"
}'
Handling the response
If all goes well, you'll get a success response that gives you the details of the created transaction, and information on how to authorize that.
// Typically used by FirstBank and GTB
{
"status": "success",
"message": "Charge initiated",
"data": {
"id": 862960580,
"tx_ref": "UNIQUE_TRANSACTION_REFERENCE",
"flw_ref": "MPOG80201678720780553218",
"device_fingerprint": "N/A",
"amount": 7500,
"charged_amount": 7500,
"app_fee": 105,
"merchant_fee": 0,
"processor_response": "Pending validation",
"auth_model": "INTERNET_BANKING",
"currency": "NGN",
"ip": "N/A",
"narration": "Flutterwave Developers",
+ "status": "pending",
"auth_url": "https://api.ravepay.co/flwv3-pug/getpaid/api/short-url/SCN0eHPMN-",
"payment_type": "account",
"fraud_status": "ok",
"created_at": "2023-03-13T15:19:40.000Z",
"account_id": 35308,
"customer": {
"id": 407680026,
"phone_number": "2349012345678",
"name": "Flutterwave Developers",
"email": "developers@flutterwavego.com",
"created_at": "2022-08-11T15:32:30.000Z"
},
"meta": {
"authorization": {
+ "mode": "redirect",
+ "redirect": "https://api.ravepay.co/flwv3-pug/getpaid/api/short-url/SCN0eHPMN-",
+ "validate_instructions": ""
}
}
}
}
Some key details in the response:
status
is"success"
, meaning that the charge was initiated successfully.data.status
is"pending"
, meaning that the customer needs to authorize the transaction with their bank.meta.authorization
contains the important details to authorize the payment:- The
mode
is"redirect"
, this means the customer should be redirected to their bank for authorization. - You'll have a
redirect
field, which is where you should redirect your customer to.
- The
Authorizing the transaction
To authorize the payment, you need to redirect the customer to the URL in the redirect
field:
if (transaction.meta.authorization.mode == "redirect") {
return res.redirect(transaction.meta.authorization.redirect);
}
if ($transaction["meta"]["authorization"]["mode"] == "redirect") {
return redirect($transaction["meta"]["authorization"]["redirect"]);
}
if transaction["meta"]["authorization"]["mode"] == "redirect"
return redirect to: transaction["meta"]["authorization"]["redirect"]
end
Webhooks
When the payment is made by the customer, we'll send you a webhook notification. Here's what the payload looks like:
{
"event": "charge.completed",
"data": {
"id": 862960580,
"tx_ref": "UNIQUE_TRANSACTION_REFERENCE",
"flw_ref": "MPOG80201678720780553218",
"device_fingerprint": "N/A",
"amount": 7500,
"currency": "NGN",
"charged_amount": 7500,
"app_fee": 105,
"merchant_fee": 0,
"processor_response": "Approved by Financial Institution",
"auth_model": "INTERNET_BANKING",
"ip": "N/A",
"narration": "Flutterwave Developers",
"status": "successful",
"payment_type": "account",
"created_at": "2023-03-13T15:19:40.000Z",
"account_id": 35308,
"customer": {
"id": 407680026,
"name": "Flutterwave Developers",
"phone_number": "2349012345678",
"email": "developers@flutterwavego.com",
"created_at": "2022-08-11T15:32:30.000Z"
},
"account": {
"account_name": "undefined undefined"
}
}
}
Now your webhook endpoint can handle the event and complete the customer's order. For help setting up webhooks, see our guide to webhooks.
In your webhook handler, you can then verify the payment and credit your customer with whatever they paid for. See our guide to transaction verification for details.