Ask AI or search...
Get API Keys

Virtual Account Numbers #

Virtual accounts are virtual subledgers within one physical depository account that can be utilized in a variety of ways. Virtual Account Numbers (VANs) allow clients to provide a routing and account number that can be used to allow ACH transactions to and from a Dwolla Balance. The routing and account number is tied to a Dwolla Client’s Master Balance, or one of their Verified Customer's balances. Virtual accounts hold no funds—they are simply a mechanism to route funds into a single Dwolla Balance. Dwolla’s Virtual Account Number feature performs two crucial functions:

  • Eliminate the need to deposit funds into an intermediary depository account before transferring funds in or out of your Dwolla Balance.
  • Keep transaction data separate and organized within the Dwolla Balance.
Send funds directly from a Virtual Account Number

Items To Note:

  • VANs cannot be used as a source or destination when calling the /transfers endpoint.
  • Users that are enabled for VANs will currently not have access to RTP or wire features.
  • Many virtual account numbers can route to a single Dwolla Balance. If you need to designate a portion of funds within a balance, reference the Labels API.
  • Dwolla has no transaction limit for externally initiated transfers.

Interacting With Virtual Accounts #

The Dwolla API supports methods for creating a VAN for a Verified Customer and creating a VAN for a Master Account, as well as retrieving routing details and removing a virtual account.

Once a virtual account is created, a unique account and routing number pair will be available for use to create external transactions (reference example below). A virtual account will be represented as a Funding Source in the Dwolla API, however, it cannot be used when calling the Dwolla API to initiate transfers. Your Dwolla Balance is the only funding source you can use for transfers using the funds in that account within the Dwolla system, and you'll only be able to use the VAN to initiate transfers affecting the funds in that account from a third party system. Upon creation of a virtual account as a Funding Source, it will immediately be available for use with a verified status.

A VAN can be removed at any time via the API. A new VAN can be created in its place if needed.

Example Routing Details Response:

raw
{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c/ach-routing",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "ach-routing"
    },
    "funding-source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    }
  },
  "accountNumber": "9619991490430833",
  "routingNumber": "084106768"
}

Tracking Virtual Account Transfers #

Externally initiated transactions will be represented by transfers that are automatically created and available in the transaction listing endpoint when Dwolla is notified of the transaction by the ACH Network.

Adding funds into a balance will be represented by a new transfer where the source is the VAN funding source and the destination is the Customer.

Example Response Object

raw
{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/transfers/c7149132-c552-ec11-813a-ebf9f1240ece",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "transfer"
        },
        "source": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/533e2de1-bc59-4301-a081-a431ef023fbd",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "customer"
        },
        "destination": {
            "href": "https://api-sandbox.dwolla.com/customers/af6eb65c-ab64-4510-8ce3-56076b6ab3a9",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        }
    },
    "id": "c7149132-c552-ec11-813a-ebf9f1240ece",
    "status": "processed",
    "amount": {
        "value": "10.00",
        "currency": "USD"
    },
    "created": "2021-12-01T16:39:06.200Z",
    "achDetails": {
        "source": {
            "addenda": {
                "values": [
                    "addenda"
                ]
            },
            "beneficiaryName": "Fake name",
            "companyName": "Fake company name",
            "companyEntryDescription": "PAYMENT",
            "effectiveDate": "2021-12-01",
            "postingData": "Fake company name:Fake discretionary data:Fake name",
            "routingNumber": "222222226",
            "traceId": "222222225926346"
        },
        "destination": {}
    }
}

Withdrawals from the Dwolla Balance will be represented by a new transfer where the source is the Customer and the destination is the VAN funding source.

Example Response Object

raw
{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/transfers/c7149132-c552-ec11-813a-ebf9f1240ece",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "transfer"
        },
        "source": {
            "href": "https://api-sandbox.dwolla.com/customers/af6eb65c-ab64-4510-8ce3-56076b6ab3a9",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "customer"
        },
        "destination": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/533e2de1-bc59-4301-a081-a431ef023fbd",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        }
    },
    "id": "c7149132-c552-ec11-813a-ebf9f1240ece",
    "status": "processed",
    "amount": {
        "value": "10.00",
        "currency": "USD"
    },
    "created": "2021-12-01T16:39:06.200Z",
    "achDetails": {
        "source": {},
        "destination": {
            "addenda": {
                "values": [
                    "addenda"
                ]
            },
            "beneficiaryName": "Fake name",
            "companyName": "Fake company name",
            "companyEntryDescription": "PAYMENT",
            "effectiveDate": "2021-12-01",
            "postingData": "Fake company name:Fake discretionary data:Fake name",
            "routingNumber": "222222226",
            "traceId": "222222225926346"
        }
    }
}

Each new transfer will trigger a bank_transfer_created or customer_bank_transfer_created webhook. The creation webhooks will be triggered approximately 30 minutes prior to any completed webhook event of bank_transfer_completed or customer_bank_transfer_completed.

Transfers will be created in a pending or failed status depending on whether the customer record or VAN has been deactivated, suspended, or removed. Pending transfers will be processed automatically during the following times (subject to change).

  • 11 a.m. CT
  • 1:15 p.m. CT
  • 5:45 p.m. CT

Additional details about an external transaction will be available in the achDetails JSON object when retrieving the transfer from the API. Either the source or the destination will be present in the object depending on the direction of the funds transfer.

ACH Details Optional Fields

NameDescription
companyEntryDescriptionDescribes the purpose of the transaction. Values can include but are not limited to: REVERSAL, RECLAIM, NO CHECK, AUTOENROLL, REDEPCHECK, RETURN FEE, RETRY PMNT, and HEALTHCARE.
routingNumberRouting number of Originating Depository Financial Institution (ODFI)
beneficiaryNameBeneficiary of the transaction's name. In general, should match the user onboarded to the Platform's name.
companyDiscrestionaryDataUsed internally by ODFI to describe the transaction.
companyIdNumeric identifier of originator.
companyNameName of the originator.

Example achDetails Object

raw
{
  ...
  "achDetails": {
    "source": {
      "addenda": {
        "values": [
          "string"
        ]
      },
      "beneficiaryName": "string",
      "companyId": "string",
      "companyName": "string",
      "companyEntryDescription": "PAYMENT",  // will differ depending on originator
      "effectiveDate": "YYYY-MM-DD",
      "postingData": "string:string:string", // suggested memo line, fields are companyName:companyDiscretionaryData:beneficiaryName
      "routingNumber": "string",             // of originating bank
      "traceId": "string"
    },
    "destination": {
      // same fields as source
    }
  }
}

Test Virtual Account Number transfers #

External transfers can be simulated in the Dwolla Sandbox by using the sandbox-simulations endpoint with a request body that includes: a type field set to virtual and a transfers field with a list of transfers to process (see example below). Up to 10 transfers at a time can be included in one call to the sandbox simulations endpoint. Transfers will be created in an initial status of pending and will be updated to processed based on the times outlined below. A failed status can occur when the virtual account number (VAN) has been removed, the Customer has been deactivated or suspended, or when an ACH return code is assigned. Reference the Testing Virtual Account Transfer Failures section for more information on how to replicate a failed status.

Pending transfers will be processed automatically during the following times (all in Central Time):

  • 2 a.m.
  • 5 a.m.
  • 8 a.m.
  • 11 a.m.
  • 1:15 p.m.
  • 5:45 p.m.
  • 8 p.m.
Optional fields and default values for VAN transfers
Optional FieldDefault Value
companyEntryDescriptionNote: The default value is an empty string "" . To simulate how a reversal transaction would look, set companyEntryDescription to "REVERSAL".
routingNumber"222222226"
addenda"addenda"
beneficiaryName"Fake name"
companyDiscretionaryData"Fake discretionary data"
companyId"random integer value"
companyName"Fake company name"
Example VANs transfer processing
bash
POST https://api-sandbox.dwolla.com/sandbox-simulations
Accept: application/vnd.dwolla.v1.hal+json
Content-Type: application/vnd.dwolla.v1.hal+json
Authorization: Bearer {Your access token}

{
    "type": "virtual",
    "transfers": [
        {
            "_link": {
                "destination": {
                    "href": "https://api-sandbox.dwolla.com/funding-sources/5880e310-675a-4ce3-87d9-a475cc565e09"
                }
            },
            "amount": {
                "currency": "USD",
                "value": "1.11"
            },
            "achDetails": {
                "companyEntryDescription": "AUTOENROLL",
                "companyName": "Test Business Name",
                "companyDiscretionaryData": "Test discretionary data",
                "beneficiaryName": "Test Name",
                "routingNumber": "012256789",
                "addenda": "addenda example",
                "companyId": "0012422"
            }
        }
    ]
}

...

HTTP/1.1 202 Accepted

Test Virtual Account Number transfer failures #

Similar to testing ACH bank transfer failures, you can test a transfer failure with a virtual account number by specifying an "R" code in the "name" parameter when creating a VAN (e.g. “R08 Failure Test VAN”). The return code must be at the beginning of the VAN funding source’s name. Note that it is not case sensitive.

List of codes for testing VAN transfer failures
CodeDescriptionWhen is the failure triggered?
R01Insufficient Funds: This value is used to simulate funds failing from the source bank account (ACH debit).During processing of pending transactions.
R02No Account/Unable to Locate Account: This value is primarily used to simulate funds failing to the destination bank account (credit). The funding source will be automatically removed from Dwolla when this return code is triggered.During processing of pending transactions.
R08Payment Stopped: The person who owns the account has placed a stop payment with their bank.“Immediately” triggered upon transfer creation by funding source naming convention.
R10Customer Advises Unauthorized, Improper, Ineligible, or Part of an Incomplete Transaction: The person who owns the bank account has told their bank account that the transaction was unauthorized.“Immediately” triggered upon transfer creation by funding source naming convention.

Create a VAN funding source for an account #

HTTP request - VAN funding source #

POST https://api.dwolla.com/funding-sources

Request parameters #

ParameterRequiredTypeDescription
nameyesstringArbitrary nickname for the funding source.
typeyesstringDenotes that this is a virtual funding source being created (VAN). Value must be virtual.
bankAccountTypeyesstringValue must be checking. VANs with a bankAccountType of savings are not currently available.

HTTP status and error codes #

HTTP StatusMessage
403Virtual account numbers are not enabled for this account.

Request and response #

Raw
POST https://api-sandbox.dwolla.com/funding-sources
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
{
 "name": "My First VAN",
 "type": "virtual",
 "bankAccountType": "checking"
}

...

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/funding-sources/04173e17-6398-4d36-a167-9d98c4b1f1c3

Create a VAN funding source for a Customer #

HTTP request - Create a VAN funding source #

POST https://api.dwolla.com/customers/{id}/funding-sources

Request parameters #

ParameterRequiredTypeDescription
nameyesstringArbitrary nickname for the funding source.
typeyesstringDenotes that this is a virtual funding source being created (VAN). Value must be virtual.
bankAccountTypeyesstringValue must be checking. VANs with a bankAccountType of savings are not currently available.

HTTP status and error codes #

HTTP StatusMessage
403Virtual account numbers are not enabled for this account.

Request and response #

Raw
POST https://api.dwolla.com/customers/fd7c402f-cd33-4333-9be4-54414e39f844/funding-sources
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
{
 "name": "My First VAN",
 "type": "virtual",
 "bankAccountType": "checking"
}

...

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/funding-sources/04173e17-6398-4d36-a167-9d98c4b1f1c3

Retrieve a VAN funding source #

HTTP request - Retrieve a VAN funding source #

GET https://api.dwolla.com/funding-sources/{id}

Request parameters #

ParameterRequiredTypeDescription
idyesstringid of funding source to retrieve.

HTTP status and error codes #

HTTP StatusMessage
404Funding source not found.

Request and response #

Raw
GET https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY

...
{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        },
        "customer": {
            "href": "https://api-sandbox.dwolla.com/customers/fd7c402f-cd33-4333-9be4-54414e39f844",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "customer"
        },
        "ach-routing": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c/ach-routing",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "ach-routing"
        },
        "remove": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/e6d68efb-c49b-43db-8867-e1ca58c6ee8c",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        }
    },
    "id": "e6d68efb-c49b-43db-8867-e1ca58c6ee8c",
    "status": "verified",
    "type": "virtual",
    "bankAccountType": "checking",
    "name": "My First VAN",
    "created": "2021-11-19T12:49:51.000Z",
    "removed": false,
    "channels": [
        "external"
    ],
    "bankName": "SANDBOX TEST BANK",
    "fingerprint": "ab589c89b3f7fe227920f7aed5a383fb48e3cb927eacb1a3b37c3b0f739d68d7"
}

Remove a VAN funding source #

HTTP request - Remove a VAN funding source #

POST https://api.dwolla.com/funding-sources/{id}

Request parameters #

ParameterRequiredTypeDescription
idyesstringid of funding source to delete.
removedyesstringSpecify a value of true to remove the associated funding source.

HTTP status and error codes #

HTTP StatusMessage
404Funding source not found.

Request and response #

Raw
POST https://api-sandbox.dwolla.com/funding-sources/62c88abb-96cb-4f1e-8ca9-7f45b5308d16
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer pBA9fVDBEyYZCEsLf/wKehyh1RTpzjUj5KzIRfDi0wKTii7DqY
{
    "removed": true
}

...

HTTP 200 OK
{
    "_links": {
        "self": {
            "href": "https://api-sandbox.dwolla.com/funding-sources/62c88abb-96cb-4f1e-8ca9-7f45b5308d16",
            "type": "application/vnd.dwolla.v1.hal+json",
            "resource-type": "funding-source"
        }
    },
    "id": "62c88abb-96cb-4f1e-8ca9-7f45b5308d16",
    "status": "verified",
    "type": "virtual",
    "bankAccountType": "checking",
    "name": "My First VAN",
    "created": "2021-11-19T13:56:11.000Z",
    "removed": true,
    "channels": [
        "external"
    ],
    "fingerprint": "a6f548e4b427191bab4284dc240f673d03046270a4fd519a8a8f82623f2814ac"
}
Still haven’t found what you are looking for?
Ask the community.
Test in the Sandbox for free today.
Use sandbox environment to test API requests.
Get API Keys
2024 All Rights Reserved
Financial institutions play an important role in our network.

All funds transfers made using the Dwolla Platform are performed by a financial institution partner, and any funds held in a Dwolla Balance are held by a financial institution partner. Learn more about our financial institution partners.