# Bank Onramp via USD Virtual Account

> Assign ACH routing details to a customer for repeatable USD deposits that convert to cryptocurrency, optionally withdrawn to an address.

## Overview

This workflow assigns a bank account number (e.g., ACH routing number) to customers for receiving repeatable fiat deposits. These deposits are automatically converted to your specified cryptocurrency and can optionally be withdrawn to a customer's destination address.

Use the [POST `workflows/bank-deposit-to-onchain-address`](../../../api-reference/convert-fiat-to-crypto) endpoint endpoint to configure this workflow.

:::tip
When you set up a USD ACH virtual account, the bank may require you to verify ownership through a microdeposit verification process. A microdeposit consists of one or more small deposits (under $1) to verify account ownership, each of which triggers 2 [FiatDeposit](../../api-concepts/webhooks/fiat-deposits.md) events and 2 [Transaction](../../api-concepts/webhooks/transactions.md) events. Microdeposits appear as regular deposits in the user's transaction history. For details, see [Microdeposits](../../api-concepts/microdeposits.md).
:::

Alternatively, or in addition, you can [create a EUR virtual account](bank-onramp-eu.md).

For more details on this product, see the [Payin via Virtual Account](../../products/bank-onramp) Product page.

### Example Scenario

Consider a US corporate treasury management system using this workflow to streamline cross-border payments:

**Setup:**

- **CustomerID:** Company's treasury account
- **Input:** USD bank deposits
- **Output:** USDC on Ethereum mainnet
- **Destination:** Company's multi-sig wallet address

**Key Implementation Features:**

- Fetch virtual account banking details from the API each time you display them to customers, rather than caching stale values
- Audit logs documenting that USD-to-USDC conversions are irreversible once sent on-chain
- Real-time price monitoring to alert treasury managers of market volatility
- Strategic timing capabilities for transfers during price stability periods

### Expected Settlement Times

Once funds arrive from the banking network, fiat-to-crypto conversion is instant—USDC is minted immediately. The total time your customers wait depends on which banking rail they use:

| Payment Method | Bank Settlement Time | Total Time to Crypto |
| -------------- | -------------------- | -------------------- |
| Standard ACH   | 1–3 business days    | 1–3 business days    |
| ACH Same-day   | Same day             | Same day             |
| Wire Transfer  | Same day             | Same day             |
| SWIFT          | 1–5 business days    | 1–5 business days    |

When setting expectations with your customers:

- **For standard ACH:** "Your transfer typically arrives within 1–3 business days. Once received, your crypto is available instantly."
- **For same-day ACH or wire:** "Your transfer settles same day. Once received, your crypto is available instantly."
- **For SWIFT:** "International wire transfers via SWIFT typically settle within 1–5 business days, depending on intermediary banks. Once received, your crypto is available instantly."

### Compatibility

Compatible with [Hosted Onboarding](../onboarding/hosted-onboarding.md) and [Token Share Onboarding](../onboarding/token-share-onboarding.md).

**Note:** USD Virtual Accounts are ONLY compatible with Standard Model KYC. Reliance Model customers cannot create USD Virtual Accounts.

## Recipe

Implement a scenario as described above by following the steps below.

<details>

<summary>1. Set Up the Environment</summary>

#### Register Your Interest

- Register your interest or book a demo by contacting Noah Support at business@noah.com.
- [Sign up for a Sandbox account](https://business.sandbox.noah.com/auth/signup) and contact Noah support to upgrade it to a business account.

#### Authenticate & Request Signing

For guidance on generating and configuring your API keys, see the [Authentication](../../api-concepts/authentication/configuration.md) page.

- Generate your Sandbox API key via the Business Dashboard.
- Include your API key in the `X-Api-Key` header of all requests.
- Request Signing is optional in Sandbox and required in Production. It is important to setup Request Signing before migrating to Production, to do this see the [Request Signing](../../api-concepts/authentication/signing.md) page.

#### Configure Webhooks

For guidance on webhook subscriptions and configuration, see the [Configuration](../../api-concepts/webhooks/configuration) page.

1. Optionally whitelist Noah's Webhook IP addresses, detailed on the [Whitelisting](../../api-concepts/webhooks/configuration.md#whitelisting) section.
2. Create a webhook subscription for the following event types, the details required to ingest the webhooks are also available on their respective pages.
   - `FiatDeposit` - see [FiatDeposit Event](../../api-concepts/webhooks/fiat-deposits).
   - `Transaction` - see [Transaction Event](../../api-concepts/webhooks/transactions).

:::tip

Throughout the Bank Onramp Workflow, you will receive three webhook events:

1. `FiatDeposit` - to notify you when the customer has sent a fiat payment to their assigned bank account number.
2. Cryptocurrency purchase `Transaction` event type - to notify you when the fiat has been converted to your chosen `CryptoCurrency` and credited to your Noah Account.
3. Cryptocurrency withdrawal `Transaction` - to notify you when the funds have been withdrawn to your customer's `DestinationAddress`.

:::

</details>

<details>

<summary>2. Create a Customer</summary>

Create a customer, if not already created, via the the [Standard Model](../../getting-started/kyc.md#standard-model), in support of which the [Hosted Onboarding recipe](../../recipes/onboarding/hosted-onboarding.md) and the [Token Share Onboarding recipe](../onboarding/token-share-onboarding.md) are provided.

</details>

<details>

<summary>3. Call the Workflow Endpoint</summary>

Call the [POST `workflows/bank-deposit-to-onchain-address`](../../../api-reference/convert-fiat-to-crypto-session) endpoint, passing the following data:

- `CustomerID`: pertaining to the customer initiating the Onramp.
- Transaction Details: including the `FiatCurrency`, `CryptoCurrency`, withdrawal `Network` and `DestinationAddress`

#### Polygon Testnet Amoy Example

```typescript
curl -L -X POST 'https://api.sandbox.noah.com/v1/workflows/bank-deposit-to-onchain-address' \
-H 'Content-Type: application/json' \
-H 'X-Api-Key: <X-Api-Key>' \
--data-raw '{
  "CustomerID": "321434324",
  "FiatCurrency": "USD",
  "CryptoCurrency": "USDC_TEST",
  "Network": "PolygonTestAmoy",
  "DestinationAddress": {
    "Address": "0x370206496048f4eDbe60e3AcBD4CFEC50B2433bd"
  }
}'
```

#### Solana Devnet Example

```typescript
curl -L -X POST 'https://api.sandbox.noah.com/v1/workflows/bank-deposit-to-onchain-address' \
-H 'Content-Type: application/json' \
-H 'X-Api-Key: <X-Api-Key>' \
--data-raw '{
  "CustomerID": "6482917350",
  "FiatCurrency": "USD",
  "CryptoCurrency": "USDC_TEST",
  "Network": "SolanaDevnet",
  "DestinationAddress": {
    "Address": "ANVUJaJoVaJZELtV2AvRp7V5qPV1B84o29zAwDhPj1c2"
  }
}'
```

:::tip

For details on the USDC_TEST token above, see [Sandbox Testnet Currencies](../../api-concepts/testnet-currencies.md).

:::

You will receive a `200` response to indicate that the bank account number has been assigned to the customer and is prepared to accept a fiat deposit. All the newly created virtual account details are shown to you, including the account holder name, accout number, bank address, bank code, and payment method type.

```typescript
{
    "AccountHolderName": "Noah LT UAB",
    "AccountNumber": "000000000000",
    "BankAddress": {
        "City": "New York",
        "Country": "US",
        "PostCode": "00000",
        "State": "NY",
        "Street": "000 Wall Street"
    },
    "BankCode": "000000000",
    "BankName": "BANKING CIRCLE USA",
    "PaymentMethodID": "Bank/Ach/USD/000000000/000000000000/000000000",
    "PaymentMethodType": "BankAch",
    "VirtualAccountID": "abc123virtualaccountid",
    "DestinationAddress": {
        "Address": "0x370206496048f4eDbe60e3AcBD4CFEC50B2433bd"
    }
}
```

</details>

<details>

<summary>4. Receive Webhook Events</summary>

#### Receive the FiatDeposit Webhook

You will receive a `FiatDeposit` event type when a customer performs a fiat deposit into their assigned bank account number. The `FiatDeposit.Settled` webhook fires once the deposit clears compliance review—typically within minutes of funds arriving from the bank. At this point, USDC minting begins immediately.

For the full payload structure and status reference, see [FiatDeposit Event](../../api-concepts/webhooks/fiat-deposits).

#### Receive the Transaction Webhooks

- You will receive a `Transaction` event when Noah completes the fiat to Crypto exchange. See [Transaction Event](../../api-concepts/webhooks/transactions).
- You will receive a second `Transaction` event when Noah completes the Crypto Withdrawal to the customer's `DestinationAddress`.

</details>

<details>

<summary>5. Simulate a Fiat Deposit</summary>

In the Sandbox environment, you can simulate a fiat deposit, to trigger webhooks and transactions.

Use the `PaymentMethodID` retrieved from step 3 to call the [POST `sandbox/fiat-deposit/simulate`](../../../api-reference/simulate-fiat-deposit) endpoint.

```typescript
curl -L 'https://api.sandbox.noah.com/v1/sandbox/fiat-deposit/simulate' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'X-Api-Key: <X-Api-Key>' \
-d '{
  "PaymentMethodID": "string",
  "FiatAmount": "10.1",
  "FiatCurrency": "USD"
}'
```

This triggers a `FiatDeposit` event, and the automated workflow will continue to the cryptocurrency purchase step.

</details>

## Guardrails

Your customers may use their individually assigned **Virtual Accounts** for use cases that comply with the Guardrails below.

---

### USD Virtual Accounts

#### Non-US-Resident Customers

##### Receive First-Party Deposits from

- The customer’s bank, fintech app, or brokerage account.

##### Receive Third-Party Deposits from

- **Registered businesses** sending USD from a domestic business account
- A **family member’s** bank account where the customer shares a surname
- **Non-family members** up to **5 000 USD** — any transaction that exceeds this limit **triggers an EDD review**

---

#### US-Resident Customers

##### Receive First-Party Deposits from

- The customer’s bank, fintech app, or brokerage account.

##### Receive Third-Party Deposits from

- **Registered businesses** sending USD from a domestic business account

---

#### Limits (apply to **all** USD Virtual Accounts)

- **Single-transaction limit:** **10 000 USD** — any transaction that exceeds this limit **triggers an EDD review**.
- **Monthly aggregated limit:** **20 000 USD** — the transaction that pushes a customer over this volume **triggers an EDD review**.

---

### Enhanced Due Diligence (EDD) Process

When an EDD review is triggered, Noah’s Compliance team will request documentation according to the KYC model your business uses.

| Model              | Who receives the Request for Information (RFI) | Information requested                                                                         |
| ------------------ | ---------------------------------------------- | --------------------------------------------------------------------------------------------- |
| **Reliance Model** | Your compliance team                           | • Proof of Source of Funds (SoF)• Full KYC pack• Purpose of the transaction |
| **Standard Model** | Your customer (via the email address on file)  | • Proof of Source of Funds (SoF)• Purpose of the transaction                         |

_Deposits requiring EDD are frozen at the `FiatDeposit` step until the requested information is received. Once EDD is completed, funds are unfrozen, converted to the defined cryptocurrency, and withdrawn to the customer’s `DestinationAddress`. If the documents are not provided within **10 days** of the RFI, the transaction will be rejected and the funds automatically refunded._

---

### Important Note

Noah reserves the right, at its sole discretion, to:

1. Request further information and/or documentation for any payment made by a third party; and
2. Amend and/or update these Guardrails from time to time.
