Concept
This guide will walk you through the core concepts needed to integrate Flutterwave into your Node.js server. You’ll learn how to:
- Set up your server app:
Install dependencies and configure your Node.js environment to handle API requests.
- Get bank code:
Retrieve a list of bank codes from Flutterwave’s API for initiating transactions.
- Get Account Details:
Use a bank code to fetch and confirm bank account details.
- Initiate a transfer:
Send money to the resolved bank account via Flutterwave.
- Fetch the transfer:
Retrieve the status of a transfer to ensure it was processed.
- Verify a transaction is valid:
Confirm the authenticity of a transaction using Flutterwave’s verification endpoint.
Step 1: Setting up your Server App
To initiate a transfer successfully, you need to whitelist your current IP address. Here is a quick guide on how to do that.
You can also use the universal address 0.0.0.0 to allow transfers from all IP addresses. However, this method offers less control compared to specifying a list of acceptable IP addresses.
Create a Node.js project by running the command below:
Then, create an app.js and .env file in your project directory.
Install your Dependencies
Install the Flutterwave Node.js SDK and dotenv package.
npm install flutterwave-node-v3 dotenv
Configuring your Environment
Log into your Flutterwave dashboard to get your API keys and add the keys to your .env file.
FLW_SECRET_KEY=<your_secret_key_here>
FLW_PUBLIC_KEY=<your_public_key_here>
Initialize the runFullTransferFlow Function
Next, update the app.js by importing the required dependencies, add dummy data, and initialize a runFullTransferFlow() function.
const Flutterwave = require('flutterwave-node-v3');
require('dotenv').config();
const flw = new Flutterwave(
process.env.FLW_PUBLIC_KEY,
process.env.FLW_SECRET_KEY
);
// Dummy data for the process
const dummyData = {
country: 'NG',
account_number: '0690000031',
bank_name: 'Access Bank', // Bank code, e.g., GTBank for Nigeria
amount: 10000,
narration: 'Payment for services rendered',
currency: 'NGN',
reference: 'unique-transfer-ref-9p8',
transfer_id: null, // This will store the transfer ID from the created transfer
transaction_id: null, // This will store the transaction ID
account_name: 'Forrest Green',
};
const runFullTransferFlow = async () => {
try {
} catch (error) {
console.error(
'Error during transfer flow:',
error.response ? error.response.data : error
);
}
};
runFullTransferFlow();
Step 2: Get Bank Code
Before you make a transfer to any bank, you need the bank code. It is a unique identifier that every bank has. You will use this to identify the bank you want to transfer to.
Update the runFullTransferFlow function as shown below:
const runFullTransferFlow = async () => {
try {
// Step 2: Get Bank Code for the transfer
console.log("Fetching Bank List...");
const bankCodeResponse = await flw.Bank.country({ country: dummyData.country, account_bank: dummyData.bank_name });
console.log(bankCodeResponse)
// Filter the bank list for the bank with the name "Access Bank"
const selectedBank = bankCodeResponse.data.find(bank => bank.name === dummyData.bank_name);
if (!selectedBank) {
throw new Error(`Bank code with name ${dummyData.bank_name} not found`);
}
console.log(`Bank Found: ${selectedBank.name} with code ${selectedBank.code}`);
}
Step 3: Get Account Details
Next, validate the account before making the transfer.
const runFullTransferFlow = async () => {
try {
// Get Bank Code here
// Step 3: Resolve Account details to confirm they are valid
console.log("Verifying Account Details...");
const resolveAccountResponse = await flw.Misc.verify_Account({
account_number: dummyData.account_number,
account_bank: selectedBank.code,
});
console.log("Account Verified:", resolveAccountResponse);
Step 4: Initiate the Transfer
To initiate the transfer, update the next method in the runFullTransferFlow function.
const runFullTransferFlow = async () => {
try {
// Get Account Details Code here
// Step 4: Initiate a transfer
console.log("Initiating Transfer...");
const transferResponse = await flw.Transfer.initiate({
account_bank: selectedBank.code,
account_number: dummyData.account_number,
amount: dummyData.amount,
narration: dummyData.narration,
currency: dummyData.currency,
reference: dummyData.reference,
callback_url: "https://example.com/callback",
debit_currency: "NGN",
});
console.log("Transfer Initiated:", transferResponse);
// Save the transfer ID for future steps
dummyData.transfer_id = transferResponse.data.id;
You cannot use the same reference for multiple transactions. If you want
to run the request more than once, be sure to update the reference key in
your Dummydata reference.
Step 5: Fetch the Transfer Data
Add runFullTransferFlow function to retrieve the transaction data.
const runFullTransferFlow = async () => {
try {
// Initiate Transfer Data code here
// Step 5: Get details of the transfer
console.log("Fetching Transfer Details...");
const fetchTransferResponse = await flw.Transfer.get_a_transfer({ id: dummyData.transfer_id });
console.log("Transfer Details:", fetchTransferResponse);
Step 6: Transaction Verification
Cross-reference the retrieved data with your dummy data to ensure consistency before updating your customer balance.
const runFullTransferFlow = async () => {
try {
// Fetch the Transfer Data code here
// Step 6: Verifying Transaction Details
console.log("Verifying Transaction Details...");
// Compare important fields from the response to your dummy data
const matches = (
fetchTransferResponse.data.account_number === dummyData.account_number &&
fetchTransferResponse.data.amount === dummyData.amount &&
fetchTransferResponse.data.narration === dummyData.narration &&
fetchTransferResponse.data.reference === dummyData.reference &&
fetchTransferResponse.data.currency === dummyData.currency &&
fetchTransferResponse.data.full_name === dummyData.account_name // Add any other necessary fields
);
// Output the result of the comparison
console.log(matches);
// Conditional logic to determine if the transaction details match
if (matches) {
console.log("Transaction details match with dummy data. Verification successful.");
} else {
console.log("Transaction details do not match with dummy data. Verification failed.");
}
The Complete App
Here is how your entire app.js should look like on completing the steps above.
const Flutterwave = require('flutterwave-node-v3');
require('dotenv').config();
const flw = new Flutterwave(
process.env.FLW_PUBLIC_KEY,
process.env.FLW_SECRET_KEY
);
// Dummy data for the process
const dummyData = {
country: 'NG',
account_number: '0690000031',
bank_name: 'Access Bank', // Bank code, e.g., GTBank for Nigeria
amount: 10000,
narration: 'Payment for services rendered',
currency: 'NGN',
reference: 'unique-transfer-ref-9p8',
transfer_id: null, // This will store the transfer ID from the created transfer
transaction_id: null, // This will store the transaction ID
account_name: 'Forrest Green',
};
const runFullTransferFlow = async () => {
try {
// Step 1: Get Bank Code for the transfer
console.log('Fetching Bank List...');
const bankCodeResponse = await flw.Bank.country({
country: dummyData.country,
account_bank: dummyData.bank_name,
});
console.log(bankCodeResponse);
// Filter the bank list for the bank with name "Access Bank"
const selectedBank = bankCodeResponse.data.find(
(bank) => bank.name === dummyData.bank_name
);
if (!selectedBank) {
throw new Error(
`Bank code with name ${dummyData.bank_name} not found`
);
}
console.log(
`Bank Found: ${selectedBank.name} with code ${selectedBank.code}`
);
// Step 2: Resolve Account details to confirm they are valid
console.log('Verifying Account Details...');
const resolveAccountResponse = await flw.Misc.verify_Account({
account_number: dummyData.account_number,
account_bank: selectedBank.code,
});
console.log('Account Verified:', resolveAccountResponse);
// Step 3: Initiate a transfer
console.log('Initiating Transfer...');
const transferResponse = await flw.Transfer.initiate({
account_bank: selectedBank.code,
account_number: dummyData.account_number,
amount: dummyData.amount,
narration: dummyData.narration,
currency: dummyData.currency,
reference: dummyData.reference,
callback_url: 'https://example.com/callback',
debit_currency: 'NGN',
});
console.log('Transfer Initiated:', transferResponse);
// Save the transfer ID for future steps
dummyData.transfer_id = transferResponse.data.id;
// Step 4: Get details of the transfer
console.log('Fetching Transfer Details...');
const fetchTransferResponse = await flw.Transfer.get_a_transfer({
id: dummyData.transfer_id,
});
console.log('Transfer Details:', fetchTransferResponse);
// Step 5: Comparing to Verify the transaction
console.log('Verifying Transaction Details...');
const matches =
fetchTransferResponse.data.account_number ===
dummyData.account_number &&
fetchTransferResponse.data.amount === dummyData.amount &&
fetchTransferResponse.data.narration === dummyData.narration &&
fetchTransferResponse.data.reference === dummyData.reference &&
fetchTransferResponse.data.currency === dummyData.currency &&
fetchTransferResponse.data.full_name === dummyData.account_name; // Add any other necessary fields
console.log(matches);
if (matches) {
console.log(
'Transaction details match with dummy data. Verification successful.'
);
} else {
console.log(
'Transaction details do not match with dummy data. Verification failed.'
);
}
} catch (error) {
console.error(
'Error during transfer flow:',
error.response ? error.response.data : error
);
}
};
runFullTransferFlow();
Next Step
Check out other available features you can integrate from our Node.js SDK.
Also, check out our best practices and error handling guides to learn how to build more robust applications.