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

# Inbound transaction or deposit

> Money arriving into a virtual account, and the two paths it takes depending on the rail.

An inbound transaction, or deposit, is money arriving from outside — the mirror of a payout. It needs an **open** virtual account: an account that exists but has not activated cannot receive anything, and [Account opening](/lifecycles/account-opening) is what gets it there.

## What advances it

| From                    | To                      | What moves it                                                             |
| ----------------------- | ----------------------- | ------------------------------------------------------------------------- |
| —                       | `PENDING`               | Money arrives on a `crypto` account and settlement has not finished       |
| —                       | `COMPLETED`             | Money arrives on a `fiat` account, which has no settlement step           |
| `PENDING`               | `COMPLETED`             | Settlement finishes                                                       |
| `PENDING` / `COMPLETED` | `KYT_PENDING`           | A compliance check holds it                                               |
| `KYT_PENDING`           | `PENDING` / `COMPLETED` | The check passes, and the deposit returns to where it was before the hold |
| `KYT_PENDING`           | `KYT_REJECTED`          | The check declines it                                                     |
| `KYT_REJECTED`          | `COMPLETED`             | Compliance withdraws the rejection and releases the money                 |
| `PENDING` / `COMPLETED` | `REFUNDED`              | A bank return sends the money back — terminal                             |
| `KYT_PENDING`           | `REFUNDED`              | A bank return arrives before the check resolves — terminal                |
| `KYT_REJECTED`          | `REFUNDED`              | Compliance sends the money back — terminal                                |
| `PENDING`               | `FAILED`                | Settlement did not finish — terminal                                      |

<Warning>
  **`COMPLETED` is not the end.** A completed deposit can still be held by a compliance check, and a bank can claw money back after settlement — both are valid transitions out of it. `FAILED` and `REFUNDED` are the only states nothing leads out of.

  **`FAILED` is reachable from `PENDING` only.** A deposit that reached `COMPLETED` can be held or returned, never failed, so a handler that branches on `FAILED` is branching on something that can only arrive before settlement finished.
</Warning>

## What announces it

The account's own events are in [Account opening](/lifecycles/account-opening). These are the deposit's:

| Event                                          | When                                                        |
| ---------------------------------------------- | ----------------------------------------------------------- |
| `virtual_account.deposit_funds_received`       | Money detected                                              |
| `virtual_account.deposit_funds_in_transit`     | On its way                                                  |
| `virtual_account.deposit_funds_in_destination` | Credited                                                    |
| `virtual_account.deposit_scheduled`            | Scheduled to arrive                                         |
| `virtual_account.deposit_in_review`            | Under review                                                |
| `virtual_account.deposit_funds_refunded`       | Returned to the sender                                      |
| `virtual_account.deposit_funds_failed`         | Settlement did not finish, with `failure_reason`            |
| `virtual_account.microdeposit_funds_received`  | A sub-dollar verification micro-deposit, not a real deposit |

**`virtual_account.deposit_funds_received` is the rail-independent signal.** Balance behaviour is not uniform across rails, so an integration that watches the balance instead will work on one rail and quietly fail on another.

## Corridors

| Account mode | Money arrives as                            | On credit                    | Terminal status         |
| ------------ | ------------------------------------------- | ---------------------------- | ----------------------- |
| `fiat`       | A bank transfer                             | Already complete at arrival  | `completed`             |
| `crypto`     | A transfer on `solana`, `polygon` or `tron` | A settlement step runs first | `pending` → `completed` |

<Note>
  A fiat deposit has no separate settlement step, so it is complete the moment it arrives — there is no intermediate state to wait through. A crypto one starts `pending` and the settlement pipeline advances it.
</Note>

## Where an RFI interrupts it

A deposit can raise a request for information against the sub-client that owns the account, and until it resolves, what it blocks stays blocked. The events are the same as in [Sub-client verification](/lifecycles/sub-client-verification).

<Warning>
  **One held deposit blocks every payout from that account.** A hold sits in `KYT_PENDING`, and a decline moves it to `KYT_REJECTED` — which only compliance can clear.
</Warning>

## Making one arrive in sandbox

You do not have to wait for a real payer. [Simulate a deposit](/api-reference/virtual-accounts/simulate-a-deposit) credits the account for real and fires the same webhooks a real deposit does, which is what makes it worth testing against. It exists in sandbox only.

<Card title="Payout" icon="arrow-right" href="/lifecycles/payout">
  Money leaving, to a counterparty you saved.
</Card>
