Skip to main content
A user funds their wallet by paying in cash at any of 50,000+ retail locations, which OMS converts to USDC. They hold the USDC on Polygon. When they want to move money out, they can send it onchain to another wallet or external blockchain address, or withdraw it back to a bank account. Funding via bank rails uses a dedicated virtual account for inbound ACH. This is the core loop for any consumer crypto product: move money in, hold it onchain, move it out. OMS handles the fiat rails, conversion, and compliance on both sides. Who this is for:
  • Consumer apps that want to offer crypto-backed savings or spending accounts
  • Crypto exchanges and brokers handling retail on/off-ramp volume
  • DeFi frontends that need fiat on-ramps for users without existing crypto holdings
  • Apps onboarding cash-preferring or unbanked users who fund without a bank account or card
Cash-in funding, crypto-to-crypto sends, bank funding, and bank payouts all run on the OMS API today. Create a virtual account for inbound ACH with POST /virtual-accounts, and register the customer’s bank account for payouts with POST /external-accounts. In sandbox you can exercise inbound ACH with the virtual-account simulate endpoint. The OMS API is in early access: request access for an API key.

How it works

On-ramp flow
1AppOMSPOST /cash-ins (cash funding), or fund via a Virtual Account for inbound ACH
2OMSAppQuote with rate, fees, and expiry window
3AppOMSPOST /transactions (quoteId)
4OMSReceives fiat cash, or ACH to a Virtual Account, converts to USDC, credits wallet
5OMSAppWebhook: transaction.fiatToCrypto.completed
Off-ramp flow
1AppOMSPOST /quotes (wallet source, bank destination)
2OMSAppQuote with rate, fees, and expiry window
3AppOMSPOST /transactions (quoteId)
4OMSPulls USDC from wallet, initiates ACH or wire transfer to the external account
5OMSAppWebhook: transaction.cryptoToFiat.completed
Both directions use the same quote-then-execute flow. The source is always an OMS wallet, and the customer agrees to a rate and fee breakdown before any money moves. Rates lock at quote time for a short window, so the customer sees exactly what they’ll receive. To move money out as a crypto-to-crypto send, run the same POST /quotes then POST /transactions flow: the source is the customer’s wallet and the destination is another wallet or an external blockchain address. Bank payouts follow the flow above, with the destination referencing an external account, registered with POST /external-accounts, by its ext_ identifier.

OMS resources

ResourceRole
CustomerIdentity record with KYC and endorsements
WalletCustodial USDC balance
Virtual accountDedicated account number for inbound ACH funding, created with POST /virtual-accounts
External accountCustomer’s bank account, registered with POST /external-accounts and referenced by ext_ ID
QuoteRate lock with fee breakdown before execution
fiatAccountToCrypto transactionConverts inbound fiat to USDC and credits the wallet
cashToCrypto transactionConverts cash-in funding to USDC and credits the wallet
cryptoToCrypto transactionSends USDC from the wallet to another wallet or external blockchain address
cryptoToFiatAccount transactionPulls USDC from the wallet, delivers fiat via ACH or wire

Implementation

Customer onboarding

Create customer records, collect KYC, and provision wallets.

Fiat to crypto

Quote and execute cash-in funding and ACH on-ramps via virtual accounts.

Crypto to fiat

Quote and execute ACH or wire off-ramps.

Bank transfers

Full walkthrough of both funding and withdrawal flows.