Virtual accounts¶
TL;DR - A virtual account (VA) is a real bank account at the upstream provider that money is wired to. Magma uses two flavours: fiat VAs hold the customer's USD balance (one per customer, used for top-up); crypto VAs auto-convert inbound USD to stablecoin and forward it on-chain (one per saved wallet, used for on-ramp).
VA modes¶
| Mode | Source funds in | Destination | Used by |
|---|---|---|---|
fiat |
USD wire | Customer's USD balance | Top-up |
crypto |
USD wire | Customer's destination crypto wallet (USDC or USDT) | On-ramp |
Both modes share the same deposit-coordinate fields (account number, routing, SWIFT/BIC, reference memo) - what differs is where the money lands after the upstream provider receives it. Crypto VAs are pass-through: the USD never sits on the customer's USD balance.
Fiat VAs¶
A fiat VA is provisioned automatically when a customer reaches the verified
state. Each customer has at least one fiat VA - the main account - and v1
ships with USD only.
A fiat VA has:
- A unique account number and routing number.
- A SWIFT / BIC for international inbound.
- An on-the-record beneficiary name (the customer's legal entity).
- A bank letter PDF you can download for the customer's records.
It is a real bank account, not a synthetic ledger entry. Money that arrives is held at the upstream provider's bank, and Magma reflects the balance.
Balance vs reserved¶
The balance card shows two numbers:
- Available - what you can spend right now on a fiat payout.
- Reserved - funds locked by an in-flight transaction (e.g. a payout that has been submitted but not yet settled at the rail). Reserved funds become available again if the payout fails or returns.
The amount the customer sees on top-up = available + reserved.
Downloading the bank letter¶
From the customer dashboard, click the VA card → Download bank letter to get a PDF the customer can give to their counterparty as proof the account is theirs. The letter is generated by the provider and includes the beneficiary name, bank name, account number, and SWIFT/BIC. Bank letters are available for fiat VAs only.
Crypto VAs¶
A crypto VA is provisioned automatically when an operator registers a saved wallet for a customer. Each saved wallet has exactly one paired crypto VA, and each VA is tied to a single destination address on a single network.
A crypto VA has the same banking coordinate fields as a fiat VA, plus a
destination triplet: network (e.g. polygon), token (e.g. USDC), and
on-chain address. Money wired into the VA is auto-converted by the upstream
provider and forwarded to the destination.
Crypto VAs do not maintain a USD balance - the upstream provider holds USD only for the few seconds between deposit detection and conversion. The balance card on the customer dashboard reflects only fiat VAs.
VA lifecycle¶
| Status | Meaning | What an operator should do |
|---|---|---|
pending |
The upstream provider is still allocating the account. Deposit coordinates are not yet available. | Wait. Usually 1–2 minutes for crypto VAs; near-instant for fiat. |
active |
Coordinates assigned; ready to receive deposits. | Share the coordinates with the customer. |
suspended |
The upstream provider deactivated or blocked the account. Rare; typically downstream of a KYC issue. | Contact Magma support. |
Crypto VAs show a Provisioning badge in the dashboard while pending. A
notice on the wallet detail and on-ramp screens explains that bank coordinates
will appear once the VA activates.
One VA per currency (fiat), one per (network, token) (crypto)¶
- Fiat - each customer gets one fiat VA per supported currency. v1 ships with USD only; multi-currency support is on the roadmap.
- Crypto - each customer can have one crypto VA per
(network, token)pair. Attempting to add a second wallet on the same combination is rejected with a duplicate error.
Reading deposit info programmatically¶
For fiat VAs:
For crypto VAs the same fields are returned embedded in the wallet response:
The virtual_account.deposit_coordinates field has the same shape as the
fiat deposit-info response and is populated only once the VA is active.
What happens behind the scenes¶
| UI action | Endpoint |
|---|---|
| List a customer's fiat VAs | GET /api/v1/organizations/{orgId}/virtual-accounts |
| Read fiat VA details | GET /api/v1/virtual-accounts/{id} |
| Read fiat VA balance | GET /api/v1/virtual-accounts/{id}/balance |
| Read fiat VA deposit coordinates | GET /api/v1/virtual-accounts/{id}/deposit-info |
| Download fiat VA bank letter | GET /api/v1/virtual-accounts/{id}/bank-letter |
| List a customer's crypto wallets / VAs | GET /api/v1/organizations/{orgId}/wallets |
| Read a saved wallet (with paired crypto VA) | GET /api/v1/wallets/{id} |
What's next¶
- Top up a customer - share the fiat VA deposit instructions.
- On-ramp - register a wallet and share the crypto VA's deposit instructions.
- Send a fiat payout - debit the USD balance held in the fiat VA.