> ## 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.

# Virtual Accounts

> Learn how to use a virtual account.

Virtual accounts are generated account details (account number and bank) that allow Flutterwave merchants to receive payments from customers via bank transfer. Virtual accounts are currently only available in naira.

<Note>
  **Virtual Cards and Virtual Accounts are Unrelated**

  Virtual accounts allow you to receive payments into your Flutterwave wallet via bank transfer, while [virtual cards](/fund-transfer/virtual-cards) allow you to make online payments.
</Note>

Virtual accounts are either *dynamic* (temporary) or *static* (permanent). A temporary account number expires after handling the specified number of transactions (the `frequency` parameter), while a static account number doesn't expire.

**Temporary Virtual Accounts** are useful for receiving one-off payments via bank transfer. When the customer is checking out, you generate a temporary virtual account with a fixed amount and provide it to them. When they make payment, we'll send you a webhook and you can handle it.

**Static Virtual Accounts** can be useful if you're building an app with a wallet system. You can issue a virtual account number for each customer to use in funding their wallet:

1. You generate a virtual account for the customer with our API and provide them with the details.
2. The customer transfers to their assigned account.
3. We send you a webhook notifying you that we've received the payment.
4. You credit the needed funds to the customer's wallet on your platform.

### Creating a Virtual Account

You can generate a virtual account with this [endpoint](/api-reference/virtual-cards/create-a-virtual-card), which is supported in our [backend SDKs](/sdk-plugins/backend-libraries/nodejs). You will need to specify the email to be associated with the account number (the customer's email). If you're creating a static virtual number, their `bvn` will be required.

<CodeGroup>
  ```javascript Node.js theme={null}
  // 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 = {
      email: "developers@flutterwavego.com",
      is_permanent: "False",
      bvn: "22222222280"
  };
  flw.VirtualAcct.create(details)
      .then(console.log)
      .catch(console.log);

  ```

  ```php PHP theme={null}
  // Install with: composer require flutterwavedev/flutterwave-v3

  $flw = new \Flutterwave\Rave(getenv('FLW_SECRET_KEY')); // Set `PUBLIC_KEY` as an environment variable
  $virtualAccountsService = new \Flutterwave\VirtualAccount();
  $details = [
      "email" => "developers@flutterwavego.com",
  ];
  $response = $virtualAccountsService->createVirtualAccount($details);
  ```

  ```ruby Ruby theme={null}
  # Install with: gem install flutterwave_sdk

  require 'flutterwave_sdk'

  flw = Flutterwave.new(ENV["FLW_PUBLIC_KEY"], ENV["FLW_SECRET_KEY"], ENV["FLW_ENCRYPTION_KEY"])
  virtual_account_number = VirtualAccountNumber.new(flw)
  details = {
    email: "developers@flutterwavego.com"
  }
  response = virtual_account_number.create_virtual_account_number details
  print response
  ```

  ```python Python theme={null}
  # Install with: pip install rave_python

  import os
  from rave_python import Rave

  rave = Rave(os.getenv("FLW_PUBLIC_KEY"), os.getenv("FLW_SECRET_KEY"))
  res = rave.VirtualAccount.create({
      "email": "developers@flutterwavego.com"
  })
  print(res)
  ```

  ```go Go theme={null}
  // Install with: go get github.com/Flutterwave/Rave-go/rave

  import (
    "fmt"
    "os"
    "github.com/Flutterwave/Rave-go/rave"
  )
  var r = rave.Rave{
    false,
    os.Getenv("FLW_PUBLIC_KEY"),
    os.Getenv("FLW_SECRET_KEY"),
  }
  var virtualAccount = rave.Virtualaccount{
      r,
  }
  details := rave.CreateAcctData {
    Email: "developers@flutterwavego.com",
  }
  err, response := virtualAccount.Create(details)
  if err != nil {
      panic(err)
  }
  fmt.Println(response)
  ```

  ```json cURL theme={null}
  curl --request POST 'https://api.flutterwave.com/v3/virtual-account-numbers' \
    --header 'Authorization: Bearer YOUR_SECRET_KEY' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "email": "developers@flutterwavego.com"
  }'
  ```
</CodeGroup>

<Info>
  **BVN is Required for Static Virtual Account**

  When generating a static virtual account, you'll need to provide a BVN. If you've created a static virtual account without a BVN in the past, you'll need to [set a BVN](/api-reference/virtual-account-numbers/update-bvn). You'll find more details [in our announcement](https://flutterwave.com/us/blog/important-update-changes-to-the-virtual-account-creation-process).
</Info>

There are more options available when generating virtual accounts. You can also set the following:

| Parameters  | Functions                                                                                       |
| ----------- | ----------------------------------------------------------------------------------------------- |
| `amount`    | The amount to be collected per transaction.                                                     |
| `frequency` | The number of times the account can be used before expiring.                                    |
| `narration` | The name should be shown when the account details are fetched.                                  |
| `tx_ref`    | The transaction reference that should be returned whenever a transfer is made into the account. |

Additionally, you can [create virtual accounts in bulk](/api-reference/virtual-account-numbers/fetch-bulk-virtual-account-details) and [retrieve](/api-reference/virtual-account-numbers/fetch-a-virtual-account-number) their details at any time. For more details, see the [API reference](/api-reference/virtual-account-numbers/create-a-virtual-account-number).

If the account is created successfully, you'll get a successful response. The response will have a `response_code` of `02` and a `response_message` of `"Transaction in progress"`, indicating that the account number has been successfully created, and we're ready to accept payments for you.

<CodeGroup>
  ```json Success theme={null}
  {
      "status": "success",
      "message": "Virtual account created",
      "data": {
          "response_code": "02",
          "response_message": "Transaction in progress",
          "order_ref": "URF_1613406439309_370935",
          "account_number": "7824822527",
          "bank_name": "WEMA BANK",
          "amount": null
      }
  }
  ```

  ```json Failure theme={null}
  {
    "status": "error",
    "message": "BVN is required for static account number",
    "data": null
  }
  ```
</CodeGroup>

#### Virtual Account Webhooks

Next, pass the details on to your customers, and they can make a transfer into the account. When they do, we'll send you a webhook that looks like this:

```json theme={null}
{
  "event": "charge.completed",
  "data": {
    "id": 407347576,
    "tx_ref": "Links-221401982810",
    "flw_ref": "000016210415121239000082517439",
    "device_fingerprint": "7852b6c97d67edce50a5f1e540719e39",
    "amount": 30020,
    "currency": "NGN",
    "charged_amount": 10,
    "app_fee": 0.14,
    "merchant_fee": 0,
    "processor_response": "success",
    "auth_model": "AUTH",
    "ip": "72.140.222.142",
    "narration": "payment for sample product",
    "status": "successful",
    "payment_type": "bank_transfer",
    "created_at": "2021-04-15T11:13:10.000Z",
    "account_id": 82913,
    "customer": {
      "id": 254967086,
      "fullname": "Flutterwave Developers",
      "phone_number": null,
      "email": "developers@flutterwavego.com",
      "created_at": "2021-04-14T16:39:17.000Z"
    }
  },
  "event.type": "BANK_TRANSFER_TRANSACTION"
}

```

If you specify a `tx_ref` when creating the account, the `reference` field will be set to that value. If you don't set one, we'll generate a unique value for that.

Now, your webhook endpoint can handle the event and credit the customer's wallet. For help setting up webhooks, see our guide on [webhooks](/webhooks).
