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

# Receiving the first deposit

> How to share a virtual account's deposit instructions, what arrives at your destination wallet, and how to reconcile it.

Once a virtual account reaches `ACTIVE`, it can receive money. This guide covers what to hand out, what lands at your destination wallet, and how to tie the two together.

If the account is not `ACTIVE` yet, see [Creating a virtual account](/guides/virtual-accounts/creating-a-virtual-account) first. `deposit_instructions` stays `null` until the banking partner issues the account.

## Sharing the deposit instructions

Read `deposit_instructions` from the account and pass every populated field to whoever is paying in. You get the same object from the `virtual_account.status.v2` webhook and from [Get Virtual Account Details](/api-reference/virtual-accounts/get-virtual-account-details), which returns the whole account:

| Field                       | Notes                                                                       |
| :-------------------------- | :-------------------------------------------------------------------------- |
| `bank_name`, `bank_address` | The receiving bank                                                          |
| `bank_account_number`       | The account to pay into                                                     |
| `bank_routing_number`       | Domestic routing. Not populated on rails that do not use one, such as SWIFT |
| `bank_beneficiary_name`     | The name the payment must be made out to                                    |
| `bank_code`                 | An object with `type` and `code`, for example a `BIC`                       |
| `bic_swift`                 | The BIC, for SWIFT deposits                                                 |
| `bank_country`              | Country of the receiving bank                                               |
| `account_type`              | The kind of account                                                         |
| `payment_rails`             | The rails this account accepts                                              |
| `currency`                  | The currency the account receives                                           |

```json theme={null}
{
  "data": {
    "id": "b84f17e1-96a8-4034-8394-e902ed403d96",
    "status": "ACTIVE",
    "developer_fee_percent": 2,
    "developer_fee_fixed": 2,
    "customer_id": "f60b6730-1bf1-4efa-a49e-be5ef5e75bb8",
    "created_at": "2026-09-09T12:27:57.657953Z",
    "updated_at": "2026-09-09T12:28:11.061185Z",
    "deposit_instructions": {
      "currency": "USD",
      "bank_name": "SSB Bank",
      "bank_address": null,
      "bank_routing_number": "",
      "bank_account_number": "235464829825",
      "bank_beneficiary_name": "WeiMing Tan",
      "bank_beneficiary_address": null,
      "payment_rails": [
        "ACH"
      ],
      "bank_country": "USA",
      "account_type": "BankSwift",
      "bank_code": {
        "type": "SWIFT",
        "code": "SSBAUS32"
      },
      "bic_swift": "SSBAUS32"
    },
    "destination": {
      "currency": "USDC",
      "destination_chain": "ETHEREUM",
      "address": "0xE6F46b9Fa4Bc867816f78323EC92887E9d325DbE"
    },
    "rfi": null,
    "bank": "SSB"
  }
}
```

<Warning>
  Which fields are populated depends on the rail. Fields that do not apply come back empty, either as `null` or as an empty string, so check for both rather than assuming a fixed set. Pass on the beneficiary name exactly as given: a payment made out to a different name may be returned.
</Warning>

Send the payer only the rails listed in `payment_rails`. A payment sent over a rail the account does not accept may be delayed or returned.

## What happens when money arrives

The deposit is converted and settled to the `destination` address you set when you created the account.

What lands is the deposited amount, less conversion and any `developer_fee` you configured, so the settled amount will not equal the amount sent. Both fee components apply if you set both:

| Field                   | Effect                                |
| :---------------------- | :------------------------------------ |
| `developer_fee_fixed`   | A flat amount taken from each deposit |
| `developer_fee_percent` | A percentage of the deposit amount    |

Settlement is not instant, and the two legs move on different clocks. The fiat leg depends on the rail the payer used, so an ACH deposit and a Fedwire deposit do not arrive on the same timeline. The crypto leg then depends on the destination network.

## Monitoring the deposit

Subscribe to [`transaction.status`](/api-reference/webhooks/transaction-status) to follow a deposit from arrival to settlement. This is the event that tells you money has landed, not the virtual account events: those only describe the account itself.

A virtual account deposit arrives with `transaction_type` set to `ONRAMP`.

| Status           | Meaning                                     |
| :--------------- | :------------------------------------------ |
| `FUNDS_RECEIVED` | The fiat has arrived at the virtual account |
| `PROCESSING`     | Conversion and settlement are under way     |
| `COMPLETED`      | Settled to your destination address         |
| `FAILED`         | The deposit did not complete                |
| `CANCELLED`      | The deposit was cancelled                   |

```json theme={null}
{
  "data": {
    "id": "53003b38-8f34-468d-9a40-1ec9abd0b0da",
    "hash": "0xbe69b3602a5abc54d9616b13114060ec029b66afd3f3c156e5979b9434b4b48c",
    "status": "COMPLETED",
    "fx_rate": 1,
    "batch_info": {
      "batch_id": null,
      "batch_item_id": null
    },
    "created_at": "2026-09-14T11:55:08.717927Z",
    "updated_at": "2026-09-14T11:59:38.024335243Z",
    "from_amount": 6,
    "developer_fee": 1.06,
    "from_currency": "USD",
    "payout_amount": 3.934,
    "beneficiary_id": null,
    "payout_currency": "USDC",
    "transaction_type": "ONRAMP",
    "processing_amount": 6,
    "transaction_ref_id": "b23cf755-bc0a-4cef-a5cb-939f651dc0c6",
    "virtual_account_id": "1ce59fee-a6ed-476f-9952-1719ea38ed91",
    "developer_fee_fixed": 1,
    "developer_fee_percentage": 1
  },
  "event": {
    "id": "e16fa3ca-fb51-4e64-8fc2-7e3c8cc101af",
    "type": "transaction.status",
    "created_at": "2026-09-14T11:59:38.081148Z",
    "sandbox_mode": true,
    "event_reference_id": "53003b38-8f34-468d-9a40-1ec9abd0b0da"
  }
}
```

The payload carries what you need to account for the deposit without a follow-up call:

| Field                                                              | Use                                             |
| :----------------------------------------------------------------- | :---------------------------------------------- |
| `virtual_account_id`                                               | Which virtual account received the deposit      |
| `from_amount`, `from_currency`                                     | The fiat that went in                           |
| `payout_amount`, `payout_currency`                                 | The stablecoin that came out                    |
| `processing_amount`                                                | The amount taken into conversion                |
| `fx_rate`                                                          | The rate applied                                |
| `developer_fee`, `developer_fee_fixed`, `developer_fee_percentage` | Your fee, in total and by component             |
| `hash`                                                             | The on-chain transaction hash of the settlement |
| `transaction_ref_id`                                               | Your own reference, if you set one              |

<Note>
  `hash` is the link between the deposit and what appears in your wallet. Store it against your record of the deposit, and reconciliation against the chain becomes a lookup rather than a guess.
</Note>

Expect more than one event per deposit. The same transaction ID arrives with each status change, so key on `data.id` and treat a repeat as an update rather than a new deposit.

## Reconciling the deposit

Webhooks tell you about a deposit as it happens. To check the record afterwards, or to catch up on anything you missed, use [Fetch Virtual Account Transactions](/api-reference/virtual-accounts/fetch-virtual-account-transactions), which lists what has arrived on one account and is paginated.

```
GET /v1/virtual-account/{virtual_account_id}/transactions
```

Reconcile against these records rather than against your wallet balance. A balance tells you that funds arrived, not which deposit they came from, and a wallet receiving settlements from several virtual accounts gives you no way to attribute them.

<Note>
  Keep your own mapping of virtual account ID to customer. The settlement arriving on chain does not carry the customer with it.
</Note>

## Troubleshooting

**Nothing has arrived.** Confirm the payer used a rail in `payment_rails`, and that they used every field exactly as given. An incomplete or mistyped beneficiary name is the most common cause of a returned payment.

**The settled amount looks wrong.** Check `developer_fee_fixed` and `developer_fee_percent` on the account. Both are deducted, alongside conversion.

**The deposit shows on the account but not at the wallet.** The fiat leg has completed and the crypto leg has not. Give the destination network time to confirm before treating it as missing.

<Note>
  **Something not adding up?**

  Contact us in your dedicated Slack channel with the virtual account ID and we will trace the deposit.
</Note>
