Skip to main content

Bank Onramp via USD Virtual Account

Overview

Assign a bank account number (e.g., ACH routing number) to a given customer to receive repeatable fiat deposits which are automatically converted to the defined CryptoCurrency and optionally withdrawn to a customer's DestinationAddress using the POST workflows/bank-deposit-to-onchain-address endpoint.

Alternatively, or in addition, you can create a EUR virtual account. For more details on this product, see the Payin via Virtual Account Product page.

Example Scenario

Imagine a US corporate treasury management system integrating this workflow to automatically convert company USD bank deposits into USDC for cross-border payments, setting up the workflow with the company's treasury CustomerID, USD as FiatCurrency, USDC on Ethereum mainnet as the target, and the company's multi-sig wallet address. The system implements automated daily calls to refresh the bank account details before displaying them to accounting staff, preventing failed transfers from expired routing numbers.

Additionally, the system would maintain audit logs acknowledging that once USD deposits are converted to USDC and sent on-chain, these transactions cannot be reversed, and incorporates real-time price monitoring to alert treasury managers when significant market volatility might affect the expected USDC amounts received from their USD deposits, enabling them to time transfers strategically during periods of price stability.

Compatibility

Compatible with Hosted Onboarding and Token Share Onboarding.

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.

1. Set Up the Environment

Register Your Interest

Authenticate & Request Signing

For guidance on generating and configuring your API keys, see the Authentication 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 page.

Configure Webhooks

For guidance on webhook subscriptions and configuration, see the Configuration page.

  1. Optionally whitelist NOAH's Webhook IP addresses, detailed on the 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.
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.
2. Create a Customer

Create a customer, if not already created, via the the Standard Model, in support of which the Hosted Onboarding recipe and the Token Share Onboarding recipe are provided.

3. Call the Workflow Endpoint

Call the POST workflows/bank-deposit-to-onchain-address 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

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

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.

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.

{
"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"
}
4. Receive Webhook Events

Receive the FiatDeposit Webhook

  • You will receive a FiatDeposit event type when a customer performs a fiat Deposit into their assigned bank account number. See FiatDeposit Event.

Receive the Transaction Webhooks

  • You will receive a Transaction event when NOAH completes the fiat to Crypto exchange. See Transaction Event.
  • You will receive a second Transaction event when NOAH completes the Crypto Withdrawal to the customer's DestinationAddress.
5. Simulate a Fiat Deposit

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 endpoint.

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.

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.

ModelWho receives the Request for Information (RFI)Information requested
Reliance ModelYour compliance team• Proof of Source of Funds (SoF)
• Full KYC pack
• Purpose of the transaction
Standard ModelYour 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.