New: BRL/PIX transfers now supported  View changelog

BRL to USD

Move funds from Brazilian Reais to US Dollars using a PIX on-ramp and an off-loader wallet for automated stablecoin-to-fiat conversion.

Overview

Using Sphere's flexible payment infrastructure, integrators can offer end-users BRL → USD transfers that settle fast. This guide uses a stablecoin sandwich — routing funds through a stablecoin intermediary — to bridge the two currencies:

  • Leg 1 (On-ramp): BRL → USDC or USDT via PIX
  • Leg 2 (Auto-conversion): USDC or USDT → USD via an Off-loader Wallet

An Off-loader Wallet is a Sphere-managed on-chain address tied to a USD bank account. Any stablecoin sent to it is automatically converted and forwarded to the destination bank account — no second transfer API call required. Your integration makes a single transfer request, and Sphere handles the rest.

The choice of stablecoin determines which networks are available. USDC is supported on Arbitrum, Avalanche, Base, Ethereum, and Polygon. USDT is supported on Ethereum and Tron. The examples in this guide use USDC on Polygon.

Because both legs are standard Sphere primitives, your integration can present the entire flow to your end users as a single BRL → USD operation.

You orchestrate, SpherePay converts

SpherePay handles the currency conversion and settlement on each leg. Your integration is responsible for setting up the instruments and initiating the on-ramp transfer.

Use cases

This pattern is well-suited for cross-border payments where one party transacts in BRL and the other receives USD, including:

  • Import/export payments — Brazilian importers paying USD invoices to international suppliers, or exporters receiving USD proceeds from foreign buyers.
  • Loan repayments — Borrowers holding BRL servicing USD-denominated debt without manual FX conversion.
  • Real estate transactions — Buyers or sellers in Brazilian property deals settling in USD for international counterparties.

What you handle vs. what SpherePay handles

ResponsibilityOwner
Creating the customer, bank accounts, and wallet objectsYou (integrator)
Creating and managing the Off-loader WalletYou (integrator)
Initiating the BRL → USDC on-ramp transferYou (integrator)
PIX payment collection and BRL → USDC conversionSpherePay
USDC → USD conversion and wire deliverySpherePay (via Off-loader Wallet)
Handling failures on either legYou (integrator)

Prerequisites

This flow requires the customer to be approved for both verification profiles:

  • kyc_profile_a / kyb_profile_a (individuals / businesses) — required for USD transfers
  • kyc_profile_b / kyb_profile_b (individuals / businesses) — required for BRL/PIX transfers

See the Individual Customer guide and Business Customer guide for KYC/KYB setup instructions.

Before starting you will need:

  • A customer with KYC/KYB approved for both verification profiles
  • A USD bank account to receive the final payout — registered in Step 1
  • A BRL bank account with a valid PIX key — registered in Step 4

Passing "network": "sol" on a BRL transfer will result in a rejected request. For USDC use ethereum, polygon, arbitrum, base, or avalanche. For USDT use ethereum or tron.


Flow Diagram


Step 1: Create a USD Bank Account

Register the USD destination account where the final payout will be delivered.

POST https://api.spherepay.co/v2/bank-account

{
  "customerId": "{{customer_id}}",
  "bankName": "Chase",
  "accountName": "My USD Account",
  "accountOwner": "Alice Johnson",
  "currency": "usd",
  "accountDetails": {
    "accountNumber": "1234567890",
    "routingNumber": "021000021",
    "accountType": "checking"
  },
  "networks": ["wire"]
}

Store the returned id as {{usd_bank_account_id}}.


Step 2: Create an Off-loader Wallet

Create an Off-loader Wallet linked to the USD bank account from Step 1. Sphere provisions a dedicated on-chain address — any stablecoin sent to it is automatically converted and wired to the destination bank account. Set currency to usdc or usdt depending on which stablecoin you want to use as the intermediary.

POST https://api.spherepay.co/v2/offloader-wallet

{
  "customerId": "{{customer_id}}",
  "currency": "usdc",
  "network": "polygon",
  "destination": {
    "bankAccountId": "{{usd_bank_account_id}}",
    "currency": "usd",
    "network": "wire"
  }
}

Choosing your fiat rail

The network field in destination controls how USD is delivered. Wire (wire) settles faster — typically within a few hours on the same business day — but incurs higher fees. ACH (ach) is cheaper but slower, typically settling in 1–2 business days. Choose based on the speed vs. cost trade-off that fits your use case.

The response includes an address field — the on-chain wallet address. Store it as {{offloader_address}}.


Step 3: Register the Off-loader Address as a Wallet Object

The Transfers API requires a wallet object (with a Sphere-assigned ID) as the transfer destination, not a raw on-chain address. Register the off-loader address to get one.

POST https://api.spherepay.co/v2/wallet

{
  "customerId": "{{customer_id}}",
  "network": "polygon",
  "address": "{{offloader_address}}"
}

Store the returned id as {{wallet_id}}. Steps 2 and 3 only need to be completed once per customer — reuse {{wallet_id}} for all subsequent BRL → USD transfers for this customer.


Step 4: Create a BRL Bank Account

Register the BRL source account using currency: "brl" and PIX-specific details in accountDetails.

POST https://api.spherepay.co/v2/bank-account

{
  "currency": "brl",
  "bankName": "Banco do Brasil",
  "accountName": "My BRL Account",
  "accountDetails": {
    "pixKey": "alice@example.com",
    "pixKeyType": "email"
  },
  "accountOwner": {
    "accountHolderName": "Alice Johnson",
    "address": {
      "line1": "Rua das Flores 123",
      "city": "São Paulo",
      "state": "SP",
      "postalCode": "01310-100",
      "country": "BRA"
    }
  },
  "networks": ["pix"]
}

The pixKeyType field accepts email, phone, cnpj, or random. The format of pixKey must match the specified type.


Step 5: Create the BRL → USDC Transfer

With all instruments in place, create the on-ramp transfer. The destination is the wallet object registered in Step 3 — backed by the off-loader wallet that will auto-convert to USD.

POST https://api.spherepay.co/v2/transfer

{
  "customer": "{{customer_id}}",
  "amount": "100.00",
  "source": {
    "type": "bank_account",
    "id": "{{brl_bank_account_id}}",
    "currency": "brl",
    "network": "pix"
  },
  "destination": {
    "type": "wallet",
    "id": "{{wallet_id}}",
    "currency": "usdc",
    "network": "polygon"
  },
  "integratorBpsFeeRate": "50"
}

BRL transfer constraints

integratorBpsFeeRate is required for BRL transfers (fixed fees are not supported), and Solana is not supported. See BRL/PIX transfer constraints for the full list.


Step 6: Fund the Transaction

The response from Step 5 includes an instructions field with the PIX key your customer should use to send BRL. Present this to your end user.

Once they initiate the PIX payment:

  1. Sphere receives the BRL and converts it to USDC
  2. USDC is delivered to the off-loader wallet address
  3. The off-loader wallet automatically converts USDC to USD and wires it to {{usd_bank_account_id}}

Error Handling

ScenarioWhat happensWhat to do
On-ramp failsBRL is returned via PIX. No USDC is minted.Retry the transfer or surface the failure to your user.
On-ramp succeeds, off-loader conversion failsUSDC sits in the off-loader wallet. No USD is sent.Contact SpherePay support — the off-loader wallet handles conversion automatically and any failure is on Sphere's side.
Customer sends wrong amount via PIXPartial or excess USDC lands in the off-loader wallet.The off-loader wallet will convert whatever USDC arrives. Handle reconciliation on your side.

Constraints

  • PIX runs 24/7 and is near-instant. USD wires only process during banking hours with a 5pm EST cutoff, and can take up to an hour depending on processing times.
  • Off-loader Wallets do not support webhooks. Track the on-ramp transfer status via GET /v2/transfer/{{transfer_id}}.
  • Both legs are billed as separate transfers.
  • Both verification profiles (A and B) must be approved before either transfer can be initiated.
  • Solana (sol) is explicitly blocked as the intermediary network for BRL transfers — the API will reject requests using it regardless of stablecoin.

Looking ahead

Today this flow requires setting up an Off-loader Wallet and a separate transfer API call. SpherePay is working toward a single-call cross-currency transfer that abstracts the intermediate stablecoin hop — you would send one request with BRL as the source currency and USD as the destination currency, and SpherePay would handle the routing internally.

When that API is available, the pattern in this guide will still work, but you'll have the option to simplify your integration to a single call.


Last updated on