Skip to main content
A virtual account gives your customer a set of bank details to receive fiat into. When a payment lands, Fin.com converts it and settles the proceeds as stablecoin to a wallet address you nominate. This guide covers the whole path: what to have in place first, how to create the account, how to follow it to ACTIVE, and what to expect on the first deposit.

Before you start

  • An approved customer. Virtual accounts belong to a customer, so the customer has to exist and have reached APPROVED. See Onboarding individual customers or Onboarding business customers.
  • Confirm your customer has the capability. Call Get Customer Capabilities and check the on_ramp entry for the currency and rail you intend to use. A customer can be approved without being eligible for every corridor.
  • A destination wallet that you have custody of. The converted funds settle to an address you nominate, and Fin.com does not custody them for you. Have the address ready on the network you intend to use, and the means to sign transactions out of it.

Choosing the source and destination

A virtual account has two sides. The source is the fiat side, meaning the bank details your customer hands out. The destination is the crypto side, meaning where the converted funds settle.
This guide covers issuing USD virtual accounts only.
Not every combination is valid even within these values. Check Supported rails and currencies before you build against a pair, and note that what is enabled for your account may be narrower still. The destination.wallet format follows the network: Ethereum, Base and Polygon take a hexadecimal address, Solana takes base58. Check it carefully. Funds settled to a wrong address cannot be recovered.

Creating the account

Call Create Virtual Account with the customer in the path.
developer_fee is your own markup on each deposit. Set a fixed amount, a percentage, or both, and both are applied.

What comes back

A 200 with the account in data. The field to read first is status, and on a fresh account it is PROCESSING:
deposit_instructions is null until the banking partner issues the account. Do not treat a 200 as the account being ready, and do not send a customer anywhere to pay until you have the deposit instructions in hand.

One account per currency and rail

A customer can hold only one virtual account per source currency and rail. Requesting one that already exists returns 422, with the colliding source in errors and the virtual_account_id of the existing account:
Use the account it points at rather than retrying. Treat 422 here as a lookup result, not a failure.

Waiting for the account to go live

New accounts are reviewed before the banking partner issues them. The account moves through these states:

Which webhooks to subscribe to

Subscribe to both: virtual_account.status.v2 is the one that matters operationally. It carries the full account object, so when status becomes ACTIVE the same payload contains the populated deposit_instructions. You do not need a follow-up call to fetch them.
event_reference_id carries the virtual account ID, so you can match the event to your own record without parsing data.

How long it takes

Issuance is not instant and is not a fixed interval. It depends on the banking partner and on the customer’s risk profile, and a REQUEST_FOR_INFORMATION pauses it until you respond. Build for this rather than polling tightly:
  • Drive off the webhook. Treat ACTIVE as an event you react to, not a state you wait on inside a request.
  • If you must poll, poll slowly. Get Virtual Account Details returns the same object. Minutes between calls, not seconds.
  • Handle REQUEST_FOR_INFORMATION. The rfi object is populated only in this state and tells you what is outstanding. Nothing progresses until it is answered.
  • Do not show a customer any bank details until you have seen deposit_instructions populated.

Next: receiving the first deposit

The account can now receive money. See Receiving the first deposit for what to hand to the payer, what lands at your destination wallet, and how to reconcile it.

Managing accounts

Need help getting set up?Contact us in your dedicated Slack channel to confirm which banking partners and corridors are enabled for you.