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:

  1. The integrator initiates the payment — either by requesting a Quote and creating a Transfer, or by provisioning a Virtual Account for the customer.
  2. Stables returns unique funding details — a single-use deposit address for Transfers, or persistent local fiat bank details for Virtual Accounts.
  3. The customer completes the deposit using the provided instructions.
  4. Stables confirms receipt of funds and performs any required FX conversion. For Virtual Account payments, a virtual_account.activity.updated.status_transitioned webhook fires with event_object_status: "processing". For Transfers, a transfer.created webhook fires when the transfer is initiated.
  5. The funds are routed to the destination — on-chain wallet address or fiat bank account — and the payment progresses through its remaining states.
  6. On terminal success, Stables emits a virtual_account.activity.updated.status_transitioned webhook (event_object_status: "completed") for Virtual Account payments, or a transfer.updated.status_transitioned webhook (event_object_status: "COMPLETED") for Transfers.

See the Transfer states reference for the full lifecycle of a Transfer.

On this page