> ## Documentation Index
> Fetch the complete documentation index at: https://flutterwaveinc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js

> Learn how to complete a bank transfer using our Node.js SDK.

## Concept

This guide will walk you through the core concepts needed to integrate Flutterwave into your Node.js server. You'll learn how to:

1. **Set up your server app**:
   Install dependencies and configure your Node.js environment to handle API requests.
2. **Get bank code**:
   Retrieve a list of bank codes from Flutterwave's API for initiating transactions.
3. **Get Account Details**:
   Use a bank code to fetch and confirm bank account details.
4. **Initiate a transfer**:
   Send money to the resolved bank account via Flutterwave.
5. **Fetch the transfer**:
   Retrieve the status of a transfer to ensure it was processed.
6. **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](https://flutterwave.com/mu/support/integrations/how-to-whitelist-ip-addresses-on-your-flutterwave-dashboard) on how to do that.

<Info>
  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.
</Info>

Create a Node.js project by running the command below:

```bash theme={null}
npm init -y
```

Then, create an `app.js` and `.env` file in your project directory.

### Install your Dependencies

Install the Flutterwave Node.js SDK and `dotenv` package.

```bash theme={null}
npm install flutterwave-node-v3 dotenv
```

### Configuring your Environment

Log into your [Flutterwave dashboard](https://app.flutterwave.com/dashboard) to get your API keys and add the keys to your `.env` file.

```bash theme={null}
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.

```javascript theme={null}
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:

```javascript theme={null}
    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.

```javascript theme={null}
    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.

```javascript theme={null}
    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;

```

<Note>
  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.
</Note>

# Step 5: Fetch the Transfer Data

Add `runFullTransferFlow` function to retrieve the transaction data.

```javascript theme={null}
    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.

```javascript theme={null}
    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.

```javascript theme={null}
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](https://github.com/Flutterwave/Node-v3/tree/master?tab=readme-ov-file#usage) from our Node.js SDK.
Also, check out our [best practices](/best-practices) and [error handling](/common-errors) guides to learn how to build more robust applications.
