Overview
The Stables Payments APIs enable the movement of value between stablecoin and fiat rails on behalf of your customers, through a single unified interface. Payments are built around two primitives - Transfers for single-use, one-time movement of funds, and Virtual Accounts for reusable fiat deposit details that automatically on-ramp into stablecoins.
Every payment is tied to a verified customer. Before initiating any payment, the customer must hold the relevant entitlement for the rail in use. See the Customer documentation for onboarding details.
Key Concepts
Transfer: A single-use instruction to move value from a source to a destination — for example, stablecoin to fiat payout. Each transfer generates unique deposit instructions that must only be used for that specific transaction.
Virtual Account: A reusable fiat deposit account issued in your customer's name. Incoming fiat is automatically converted to stablecoins and credited to a designated wallet address.
Quote: A pre-transaction estimate of the conversion amount, applicable fees, and payout detail. Quotes back every Transfer and must be requested before funds movement begins.
Rail: The underlying network or banking system used to move funds — for example, ACH, SEPA, NPP, Polygon, or Tron.
Webhooks: Real-time notifications of state changes throughout the payment lifecycle. Rely on webhooks for the terminal state of any payment.
Transfers vs Virtual Accounts
The two primitives solve different problems:
- Use Transfers when your customer needs to send money out — paying a vendor, settling a bill, off-ramping crypto to fiat. Transfers are dynamic and single-use; each Transfer generates fresh source instructions tied to an explicit destination.
- Use Virtual Accounts when your customer needs to receive money in — collecting payments, ongoing fiat-to-stablecoin on-ramp, recurring deposits. Virtual Accounts are static and reusable; provision once and the customer reuses the same deposit details indefinitely.
To learn more, see Transfers and Virtual Accounts.
Fees and Limits
Payments are subject to conversion fees, processing fees, and per-rail limits. The applicable fees for any specific transaction are always returned in the quote response.
For the full breakdown, refer to our Fees and Limits documentation.
High Level Payment Flow
A typical payment moves through the following stages:
- The integrator initiates the payment — either by requesting a Quote and creating a Transfer, or by provisioning a Virtual Account for the customer.
- Stables returns unique funding details — a single-use deposit address for Transfers, or persistent local fiat bank details for Virtual Accounts.
- The customer completes the deposit using the provided instructions.
- Stables confirms receipt of funds and performs any required FX conversion. For Virtual Account payments, a
virtual_account.activity.updated.status_transitionedwebhook fires withevent_object_status: "processing". For Transfers, atransfer.createdwebhook fires when the transfer is initiated. - The funds are routed to the destination — on-chain wallet address or fiat bank account — and the payment progresses through its remaining states.
- On terminal success, Stables emits a
virtual_account.activity.updated.status_transitionedwebhook (event_object_status: "completed") for Virtual Account payments, or atransfer.updated.status_transitionedwebhook (event_object_status: "COMPLETED") for Transfers.
See the Transfer states reference for the full lifecycle of a Transfer.