| Virtual Account | Orchestration Address | |
|---|---|---|
| Direction | Fiat → Stablecoin | Stablecoin → Fiat |
| Deposit method | Bank transfer (wire / ACH) | On-chain stablecoin transfer |
| Destination | A crypto wallet | A bank account |
Common Use Cases
Merchant settlement
Give customers a stable on-chain address to pay into. Auto-settle to your bank daily with
SCHEDULED mode.Payment processing
Issue per-customer addresses and settle each payment independently for clean reconciliation. Best paired with
PER_DEPOSIT mode.Treasury sweeps
Accumulate stablecoin revenue across wallets and sweep to fiat on a fixed cadence.
SCHEDULED mode (DAILY / WEEKLY) keeps your bank balance predictable.Payouts collection
Collect stablecoin from multiple senders and convert to USD once a meaningful balance accrues.
THRESHOLD mode minimizes per-offramp fees.OTC desks & exchanges
Automate fiat off-ramping without a manual quote-accept on every trade.
PER_DEPOSIT gives each trade its own offramp record.Subscription billing
Charge customers in stablecoin and convert to fiat on your billing cycle with
SCHEDULED mode.How Orchestration Addresses Work
Create the address
Configure a source
(currency, chain), a USD destination payout account, and an orchestration mode. HIFI provisions a dedicated on-chain wallet and returns its address.Receive stablecoin deposits
Senders transfer USDC or USDT on-chain to the address. HIFI detects each deposit via on-chain webhooks.
Orchestration Modes
Choose one of three modes at create time. The mode is changeable later via the update endpoint.PER_DEPOSIT
Every detected deposit becomes its own batch and offramp, immediately.Best for clients who want each customer payment to settle independently with full traceability.
SCHEDULED
Deposits accumulate until the next scheduled tick (
HOURLY, DAILY, or WEEKLY), then roll up into a single batch.Best for predictable cadence or end-of-day sweeps.THRESHOLD
Deposits accumulate until their aggregate amount reaches
thresholdAmount, then roll up into a single batch.Best for minimizing offramp fees by waiting for a meaningful balance.SCHEDULED clock.
Supported Source Pairs
| Chain | USDC | USDT |
|---|---|---|
| Ethereum, Polygon, Base, Solana | ✅ | ✅ |
| Tron | ❌ | ✅ |
Minimum Amounts
Every destination rail enforces a minimum amount. A batch is only created once the eligiblePENDING deposits sum to at least that minimum.
| Rail | Minimum |
|---|---|
| Wire, ACH, RTP | 1 USDC |
| SWIFT | 5 USDC |
| USDT (any rail) | 10 USDT |
PER_DEPOSIT— a deposit at or above the minimum is batched immediately; a sub-minimum deposit is heldPENDINGand swept into the next qualifying batch.SCHEDULED— a tick whosePENDINGtotal is below the minimum batches nothing; the deposits roll into the next tick.THRESHOLD—thresholdAmountis validated to be ≥ the rail minimum at create/update time, so a crossed threshold always clears it.- Manual trigger — returns
triggered: false, reason: "below_offramp_minimum"if the pending total is below the minimum.
Creating an Orchestration Address
Create an address using the Create Orchestration Address endpoint.Request Fields
Your idempotency key (UUID v4). Repeating the same
requestId with the same payload returns the existing record; repeating it with a different payload returns 409 RESOURCE_CONFLICT identifying the first mismatched field (one of source.currency, source.chain, destination.currency, destination.accountId, mode, schedule.interval, or thresholdAmount).The stablecoin and chain the address will accept.
The USD payout account that will receive the offramped funds.
Orchestration mode. One of
PER_DEPOSIT, SCHEDULED, or THRESHOLD.Required when
mode = SCHEDULED. Must be omitted otherwise.Required when
mode = THRESHOLD. Must be omitted otherwise. Must be at least the destination rail’s offramp minimum.Response
status may briefly be PENDING_WALLET while the on-chain wallet is being provisioned. The Create endpoint waits for provisioning to complete, so the typical response is already ACTIVE with address populated.Managing the Address Lifecycle
Update
Update the mode, schedule, threshold, or destination account at any time while the address isACTIVE. Updates do not affect offramps already in flight — only future deposits use the new configuration.
Deactivate
Deactivate the address with awalletAddress to receive any in-kind refunds. Deactivation:
- Refunds all
PENDING(not-yet-batched) deposits in-kind towalletAddress. - Lets in-flight
PROCESSINGbatches continue to completion. - Stops offramping any new deposits — they are recorded as
IGNOREDwith no automatic refund.
Manually trigger an orchestration
Call Trigger Orchestration to batch all currently-PENDING deposits immediately, regardless of mode. Idempotent — returns triggered: false with a reason when there is nothing to orchestrate.
Tracking Deposits and Batches
Each on-chain deposit is recorded as a deposit row; each produced offramp is recorded as a batch row.| Resource | Statuses | Use |
|---|---|---|
| Deposit | PENDING, BATCHED, IGNORED | Track individual on-chain transfers. |
| Batch | PENDING, PROCESSING, COMPLETED, FAILED | Track the offramp produced from a group of deposits. |
Reconciling with offramps
Orchestration offramps flow through the same pipeline as direct offramps, so the existing offramp endpoints and webhooks work without changes:- Webhook events: the standard offramp progress events fire for orchestration offramps. Each event payload includes an
orchestrationAddressIdfield — non-null when the offramp was produced by an orchestration address, null for direct offramps. - Cross-reference: Get Offramp includes
orchestrationAddressIdin its response, and a batch’sofframpTransactionIdlinks to the full offramp record. You can pivot in either direction without an extra round-trip.
Ignored deposits
A deposit is recorded withstatus = IGNORED (and not offramped) in two cases:
ADDRESS_DEACTIVATED— the deposit arrived after the address was deactivated.UNSUPPORTED_TOKEN— the sender used the wrong stablecoin (for example, sending USDT to a USDC-only address).
Failed batches
A batch can land inFAILED for one of two reasons, surfaced as failureReason:
ADDRESS_NOT_ACTIVE— the address was deactivated between batch creation and processing.- A terminal offramp status (
NOT_INITIATED,QUOTE_FAILED,CRYPTO_FAILED,FIAT_FAILED,EXPIRED,REJECTED,CANCELLED) — the underlying offramp terminated. Compliance issues (lost product access, KYC rejection) surface here.
BATCHED status and are not automatically retried. Contact support to re-batch them once any underlying issue is resolved.
Getting Help
- 📧 Email: support@hifi.com
- 💬 Slack: Message us in our shared Slack channel
Related Resources
- Virtual Accounts - The inverse flow: fiat deposits converted to stablecoins
- Developer Fees - Fee calculation for offramp transactions
- API Reference - Complete endpoint documentation