> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spherepay.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Fiat Currency Trading with Stablecoin Settlement

> Trade between fiat currency pairs using stablecoins as the settlement bridge — BRL ↔ USD, USD ↔ EUR, and other corridors as SpherePay's rails expand.

Use SpherePay to facilitate currency trading between fiat pairs using stablecoins as the settlement layer. The pattern is the same across corridors — a stablecoin sandwich routes the trade through USDC (or another stablecoin), with SpherePay handling both fiat legs.

This is the right pattern for FX brokerages, currency-exchange platforms, B2B cross-currency settlement, and any product that needs to convert one fiat into another fast and predictably.

## The pattern, in one shape

Every corridor below follows the same three-step model:

1. **On-ramp** the source fiat to USDC.
2. **Bridge** the USDC across networks if needed (one wallet to another).
3. **Off-ramp** USDC to the destination fiat.

The cleanest implementation uses an [Offloader Wallet](/concepts/automation/offloader-wallets) for step 3 — Sphere automatically converts USDC to the destination fiat and wires it to a bank account, eliminating the need for a second transfer API call.

<Info>
  Both fiat legs require separate verification profiles on the customer (one per currency). See each corridor below for the specific profiles required.
</Info>

## Supported corridors

Expand a corridor below for the full step-by-step integration walkthrough.

<AccordionGroup>
  <Accordion title="BRL ↔ USD — Brazilian Real and US Dollar" icon="banknote">
    The most common Sphere corridor today. Moves funds between Brazilian Reais (via PIX) and US Dollars (via wire or ACH) with USDC as the bridge currency.

    **Common use cases:**

    * Import/export payments — Brazilian importers paying USD invoices to international suppliers, or exporters receiving USD proceeds.
    * Loan repayments — borrowers holding BRL servicing USD-denominated debt.
    * Real estate transactions — buyers or sellers in Brazilian property deals settling in USD.
    * Remittances — Brazilian senders, US recipients.

    ### Prerequisites

    <Warning>
      The customer must be approved for **both** verification profiles:

      * `kyc_profile_a` / `kyb_profile_a` — required for USD transfers
      * `kyc_profile_b` / `kyb_profile_b` — required for BRL/PIX transfers

      See [Individual KYC](/concepts/onboarding/individual-kyc) and [Business KYB](/concepts/onboarding/business-kyb) for setup.
    </Warning>

    <Warning>
      Passing `"network": "sol"` on a BRL transfer will result in a rejected request. Use `ethereum`, `polygon`, `arbitrum`, `base`, or `avalanche` for USDC. USDT supports `ethereum` or `tron`.
    </Warning>

    ### Flow

    ```mermaid theme={"dark"}
    sequenceDiagram
        participant U as End user
        participant I as Your integration
        participant S as SpherePay
        participant P as PIX network
        participant B as USD bank

        I->>S: POST /v2/bank-account (USD)
        S-->>I: usdBankAccountId
        I->>S: POST /v2/offloader-wallet (USDC → USD)
        S-->>I: offloaderWallet.address
        I->>S: POST /v2/wallet (register offloader address)
        S-->>I: walletId
        I->>S: POST /v2/bank-account (BRL + PIX key)
        S-->>I: brlBankAccountId
        I->>S: POST /v2/transfer (BRL → USDC on-ramp)
        S-->>I: transferId, instructions.pixKey
        I->>U: Present PIX payment instructions
        U->>P: Send BRL via PIX
        P->>S: BRL received
        Note over S: Convert BRL → USDC, deliver to Offloader Wallet
        Note over S: Offloader Wallet auto-converts USDC → USD
        S->>B: Settle USD via wire
    ```

    ### Step 1 — Create a USD bank account

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

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

    ### Step 2 — Create an Offloader Wallet

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "currency": "usdc",
      "network": "polygon",
      "destination": {
        "bankAccountId": "{{usd_bank_account_id}}",
        "currency": "usd",
        "network": "wire"
      }
    }
    ```

    Store the returned `address` as `{{offloader_address}}`.

    ### Step 3 — Register the Offloader address as a wallet

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "network": "polygon",
      "address": "{{offloader_address}}"
    }
    ```

    Store the returned `id` as `{{wallet_id}}`. Steps 1–3 only need to be done once per customer — reuse `{{wallet_id}}` for all future BRL → USD transfers.

    ### Step 4 — Create a BRL bank account

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

    ```json theme={"dark"}
    {
      "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"]
    }
    ```

    `pixKeyType` accepts `email`, `phone`, `cnpj`, or `random`.

    ### Step 5 — Create the BRL → USDC transfer

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

    ```json theme={"dark"}
    {
      "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"
    }
    ```

    <Warning>
      **BRL constraints:** `integratorBpsFeeRate` is required (fixed fees not supported), per-transfer limits R$1.00–R$7,500.00, Solana not supported. See [Supported rails](/concepts/transfers/supported-rails).
    </Warning>

    ### Step 6 — Fund the transaction

    The response includes an `instructions.pixKey` — present this to your end user. Once they send the BRL via PIX:

    1. Sphere receives the BRL and converts it to USDC.
    2. USDC is delivered to the Offloader Wallet.
    3. The Offloader Wallet auto-converts USDC to USD and wires it to the registered USD bank account.

    ### Reverse direction — USD → BRL

    For the opposite direction, flip the pattern: register a BRL Offloader Wallet (USDC → BRL via PIX), then on-ramp USD → USDC into it. Same primitives, same number of API calls.

    ### Error handling

    | Scenario                                     | What happens                                      | What to do                                                 |
    | -------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------------- |
    | On-ramp fails                                | BRL returned via PIX. No USDC minted.             | Retry or surface to user.                                  |
    | On-ramp succeeds, Offloader conversion fails | USDC sits in Offloader Wallet. No USD sent.       | Contact SpherePay support.                                 |
    | Customer sends wrong PIX amount              | Partial or excess USDC lands in Offloader Wallet. | Wallet converts whatever arrives — reconcile on your side. |
  </Accordion>

  <Accordion title="USD ↔ EUR — US Dollar and Euro" icon="euro">
    Convert between US Dollars (via ACH or wire) and Euros (via SEPA) with USDC or EURC as the bridge. SEPA settles same/next business day; SEPA Instant is near-instant where supported.

    **Common use cases:**

    * US importers paying European suppliers.
    * European platforms accepting USD revenue and settling to EUR.
    * Cross-border treasury — companies operating in both regions managing FX exposure.
    * FX brokerages offering retail USD/EUR conversion.

    ### Prerequisites

    The customer must be approved for both USD and EUR verification profiles. Both fiat rails fall under `kyc_profile_a` / `kyb_profile_a` (no separate profile is needed for EUR, unlike BRL).

    All standard USDC networks are supported, including Solana. For EURC, supported networks are Base, Ethereum, and Solana.

    ### Flow

    ```mermaid theme={"dark"}
    sequenceDiagram
        participant U as End user
        participant I as Your integration
        participant S as SpherePay
        participant USB as USD bank
        participant EUB as EUR bank

        I->>S: POST /v2/bank-account (EUR + SEPA)
        S-->>I: eurBankAccountId
        I->>S: POST /v2/offloader-wallet (USDC → EUR)
        S-->>I: offloaderWallet.address
        I->>S: POST /v2/wallet (register offloader)
        S-->>I: walletId
        I->>S: POST /v2/bank-account (USD)
        S-->>I: usdBankAccountId
        I->>S: POST /v2/transfer (USD → USDC on-ramp)
        USB-->>S: USD received via ACH/wire
        Note over S: Convert USD → USDC, deliver to Offloader Wallet
        Note over S: Offloader auto-converts USDC → EUR
        S->>EUB: Settle EUR via SEPA
    ```

    ### Step 1 — Create an EUR bank account

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "bankName": "Deutsche Bank",
      "accountName": "EUR settlement",
      "accountOwner": "Acme GmbH",
      "currency": "eur",
      "accountDetails": {
        "iban": "DE89370400440532013000",
        "bic": "DEUTDEFFXXX"
      },
      "networks": ["sepa"]
    }
    ```

    Use `sepaInstant` in `networks` if you need near-instant settlement and the recipient bank supports it.

    ### Step 2 — Create an Offloader Wallet for USDC → EUR

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "currency": "usdc",
      "network": "ethereum",
      "destination": {
        "bankAccountId": "{{eur_bank_account_id}}",
        "currency": "eur",
        "network": "sepa"
      }
    }
    ```

    Pick the source network based on where you'll be receiving USDC. Solana is the cheapest and fastest; Ethereum and Base are common for institutional flows.

    Store the returned `address` as `{{offloader_address}}`.

    ### Step 3 — Register the Offloader address as a wallet

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "network": "ethereum",
      "address": "{{offloader_address}}"
    }
    ```

    Store the returned `id` as `{{wallet_id}}`.

    ### Step 4 — Create a USD bank account

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

    ```json theme={"dark"}
    {
      "customerId": "{{customer_id}}",
      "bankName": "Chase",
      "accountName": "USD source",
      "accountOwner": "Acme Inc",
      "currency": "usd",
      "accountDetails": {
        "accountNumber": "1234567890",
        "routingNumber": "021000021",
        "accountType": "checking"
      },
      "networks": ["ach", "wire"]
    }
    ```

    ### Step 5 — Create the USD → USDC transfer

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

    ```json theme={"dark"}
    {
      "customer": "{{customer_id}}",
      "amount": "10000.00",
      "source": {
        "type": "bank_account",
        "id": "{{usd_bank_account_id}}",
        "currency": "usd",
        "network": "wire"
      },
      "destination": {
        "type": "wallet",
        "id": "{{wallet_id}}",
        "currency": "usdc",
        "network": "ethereum"
      }
    }
    ```

    Pick `wire` for large or international transfers; `ach` is the cheaper option for domestic US transfers and is sent same-day by default.

    ### Step 6 — Settlement

    Once USD arrives at SpherePay:

    1. Sphere converts USD → USDC.
    2. USDC is delivered to the Offloader Wallet.
    3. Offloader Wallet auto-converts USDC → EUR and sends via SEPA.

    Total time: minutes (wire) to \~1 business day (ACH + SEPA), depending on rail choices.

    ### Reverse direction — EUR → USD

    Same primitives, flipped. Register a USD Offloader Wallet (USDC → USD), on-ramp EUR → USDC into it.

    ### Using EURC instead of USDC

    For EUR-heavy flows, EURC can reduce slippage. Set `currency: "eurc"` and `network` to one of `base`, `ethereum`, or `solana` on the Offloader Wallet. The bridge currency becomes EURC instead of USDC; the rest of the integration is identical.
  </Accordion>
</AccordionGroup>

## What you handle vs. what SpherePay handles

| Responsibility                                           | Owner                            |
| -------------------------------------------------------- | -------------------------------- |
| Creating the customer, bank accounts, and wallet objects | You (integrator)                 |
| Creating and managing the Offloader Wallet               | You (integrator)                 |
| Initiating the on-ramp transfer                          | You (integrator)                 |
| Fiat collection and source-fiat → USDC conversion        | SpherePay                        |
| USDC → destination-fiat conversion and settlement        | SpherePay (via Offloader Wallet) |
| Handling failures on either leg                          | You (integrator)                 |

## Constraints common to all corridors

* Each leg is billed as a separate transfer.
* Offloader Wallets don't support webhooks today — poll `GET /v2/transfer/{id}` to track on-ramp status.
* Both source-fiat and destination-fiat verification profiles must be approved before either transfer can be initiated.

## Looking ahead — single-call cross-currency transfers

Today every corridor requires setting up an Offloader Wallet plus a separate on-ramp transfer call. SpherePay is working toward a **single-call cross-currency transfer** API that abstracts the stablecoin hop entirely — you'd send one request with the source and destination currencies, and SpherePay would handle the routing internally. When that ships, the patterns in this guide will still work, but you'll have the option to consolidate to a single call.

## Related

<CardGroup cols={2}>
  <Card title="Offloader Wallets" icon="wallet" href="/concepts/automation/offloader-wallets">
    How automated stablecoin-to-fiat conversion works.
  </Card>

  <Card title="Transfers API" icon="arrow-right-left" href="/concepts/transfers/overview">
    Full transfer creation and tracking reference.
  </Card>

  <Card title="Supported rails" icon="globe" href="/concepts/transfers/supported-rails">
    Per-currency network and rail compatibility.
  </Card>

  <Card title="Cross-border trade finance" icon="ship" href="/solutions/cross-border-trade-finance">
    Multi-party trade payment patterns.
  </Card>
</CardGroup>
