---
title: "How to pay an exact BRL, MXN, or EUR amount from USDC: receiver-side quotes explained"
seoTitle: "Pay an exact BRL, MXN, or EUR amount from USDC"
description: "Fix what the recipient gets, not what you send. How receiver-side quotes and cover_fees land exact amounts over Pix, SPEI, and SEPA, with worked examples."
date: "2026-10-03"
updated: "2026-10-03"
category: "payments"
author: "BlindPay Team"
faq:
  - q: "How do I make sure my recipient gets an exact amount in local currency?"
    a: "Quote on the receiver side. Set currency_type to receiver, put the local amount in request_amount in minor units, and set cover_fees to true so fees are added to the stablecoins you send. The quote returns the sender_amount that delivers that amount. Execute against the quote id before expires_at and the recipient gets the quoted receiver_amount."
  - q: "What does cover_fees do on a receiver-side quote?"
    a: "It decides who absorbs the fee. With cover_fees set to true, the fee is added on top of the stablecoin amount you send, so the recipient gets the full amount. With cover_fees set to false, BlindPay's docs describe the fee as deducted from the fiat the recipient receives. Either way, read receiver_amount on the response before you show or promise a number."
  - q: "Is there a minimum for a receiver-side EUR quote?"
    a: "Yes. A SEPA payout quoted by the EUR amount the receiver should get needs at least 10 EUR, and a SEPA quote by USDC amount needs at least 11 USDC. Below that, the quote fails with sepa_minimum_is_10_eur or sepa_minimum_is_11_usdc. International SWIFT payouts need at least 100 USD requested. Other rails have no minimum beyond the fee itself."
  - q: "What happens to the exact amount if the quote expires?"
    a: "Nothing moves. An expired quote is rejected, not executed at a new rate. Request a new receiver-side quote with the same local amount. The receiver amount stays fixed, and the sender_amount changes to the new rate. Show the new USDC figure, get confirmation if your flow needs it, and execute against the new quote id."
  - q: "Can I fix the BRL amount and let the recipient pay the fees?"
    a: "You can request the quote with currency_type set to receiver and cover_fees set to false, but then the fee comes out of what the recipient gets, so the delivered BRL can sit below the amount you typed. If the obligation is an invoice or a salary with a fixed number, use cover_fees set to true instead."
howto:
  name: "How to pay an exact local-currency amount from USDC with a receiver-side quote"
  steps:
    - name: "Add and approve the recipient's bank account"
      text: "Create a bank account for the recipient with the rail's details: a Pix key for Brazil, a CLABE for Mexico, or an IBAN and BIC for SEPA. Wait for status approved."
    - name: "Request a receiver-side quote"
      text: "Call POST /v1/instances/{instance_id}/quotes with bank_account_id, currency_type receiver, request_amount in local minor units, cover_fees true, network, and token."
    - name: "Show the stablecoin cost and a countdown"
      text: "Display sender_amount as the USDC needed and count down from expires_at, which is in epoch milliseconds."
    - name: "Authorize exactly the quoted amount"
      text: "For an external EVM wallet, call approve on the token contract with the contract payload from the quote. Managed wallets skip this step."
    - name: "Execute the payout before expiry"
      text: "Call POST /v1/instances/{instance_id}/payouts/evm with quote_id and sender_wallet_address. If the quote expired, request a new one with the same local amount."
    - name: "Reconcile against the obligation"
      text: "Match receiver_amount on the quote to the invoice or salary line, store the quote id with the payout id, and close the item when the payout completes."
---

To pay an exact BRL, MXN, or EUR amount from USDC, request a receiver-side quote: set `currency_type` to `receiver`, put the local amount in `request_amount`, and set `cover_fees` to `true`. The quote returns the USDC `sender_amount` that delivers that exact amount, locked until `expires_at`. Execute before then and the number lands.

That is the whole trick. The rest of this guide is the detail that makes it work on Pix, SPEI, and SEPA without surprises.

**Key takeaways**

- Fix the side that matters to the business. A BRL invoice is a BRL number, so quote the BRL side and let the USDC float.
- `currency_type: "receiver"` plus `cover_fees: true` is the pairing for "recipient gets exactly X." With `cover_fees: false`, the fee comes out of the recipient's amount.
- Amounts are integers in minor units: R$27,000.00 is `2700000`. No floats.
- On re-quote, the local amount stays fixed and only the USDC cost moves.
- SEPA has a receiver-side minimum of 10 EUR, and SEPA quotes can expire sooner than 5 minutes. Read `expires_at`.

## When should you fix the receiver amount instead of the send amount?

Fix the receiver amount when the obligation is written in local currency. Fix the send amount when the budget is written in dollars. The quote can do either; your job is to pick the side that matches the contract.

The [quotes explainer](/resources/more/stablecoin-api-quotes-explained) covers what `currency_type` and `cover_fees` mean. This is about which combination fits which job.

| Use case | Obligation is in | Quote side | `cover_fees` | Why |
| --- | --- | --- | --- | --- |
| Supplier invoice in Brazil | BRL | `receiver` | `true` | The invoice says R$27,000.00. Anything less is a short payment. |
| Contractor salary in Mexico | MXN | `receiver` | `true` | The contract fixes pesos. The company absorbs the fee. |
| Rent or tuition in the euro area | EUR | `receiver` | `true` | The bill is in euros and must clear in full. |
| Marketplace seller payout | USD balance | `sender` | `false` | The seller earned a USD balance and gets the net in local currency. |
| Treasury sweep to a local account | USDC on hand | `sender` | `false` | You move a USDC amount and accept the local result. |

A rule of thumb: if someone will check the local number against a document, quote the local number.

## How does a receiver-side quote work?

You tell BlindPay the fiat amount the bank account must receive. BlindPay prices the conversion at request time and returns how much stablecoin the funding wallet must send, plus every fee line, locked for the quote's window.

The request goes to `POST /v1/instances/{instance_id}/quotes`:

```json
{
  "bank_account_id": "ba_000000000000",
  "currency_type": "receiver",
  "cover_fees": true,
  "request_amount": 2700000,
  "network": "polygon",
  "token": "USDC"
}
```

The response carries `id`, `expires_at` (epoch milliseconds), `commercial_quotation` (the market rate), `blindpay_quotation` (the rate net of BlindPay's fee), `sender_amount`, `receiver_amount`, and the fee fields. The [payout quotes reference](/docs/payout-quotes) lists every field.

Two details catch teams the first time.

- **Minor units.** `request_amount` is an integer. R$27,000.00 is `2700000`, and $35,000.00 MXN is `3500000`. Convert once, at the edge of your system.
- **The direction flips on payins.** On a payout quote, `receiver` means the fiat side. On a payin quote, `receiver` means the stablecoin side. A shared helper that ignores this quotes the wrong side.

## What does an exact-amount payout look like in each currency?

The same request shape works across rails. What changes is the bank account behind `bank_account_id` and a couple of rail rules.

| | Brazil | Mexico | SEPA zone |
| --- | --- | --- | --- |
| Rail | Pix | SPEI | SEPA |
| Recipient detail | Pix key (CPF, CNPJ, phone, email, or random key) | 18-digit CLABE | IBAN and BIC, plus beneficiary name and address |
| Receiver-side minimum | Fee only | Fee only | 10 EUR (11 USDC on the sender side) |
| Quote window | 5 minutes by default | 5 minutes by default | Can be shorter than 5 minutes |
| Estimated arrival in BlindPay's docs | Instant | Instant | About 1 business day |

Pix and SPEI both run around the clock. The [Central Bank of Brazil](https://www.bcb.gov.br/en/financialstability/pix_en) operates Pix as an instant payment system, and [Banco de México](https://www.banxico.org.mx/services/interbanking-electronic-payme.html) operates SPEI around the clock. SEPA is the euro area's common framework for euro transfers, described by the [European Central Bank](https://www.ecb.europa.eu/paym/integration/retail/sepa/html/index.en.html).

For which details each rail needs, see [Pix keys, CPF, and CLABE explained](/resources/more/pix-key-cpf-clabe-payout-details) and the [SEPA off-ramp guide](/resources/more/how-to-off-ramp-usdc-to-euros-sepa).

## How much USDC does an exact amount cost?

The quote tells you. You never compute `sender_amount` yourself. But you should know how to read it, so you can check the cost against the market.

**Illustrative example.** These rates are made up for the arithmetic. They are not BlindPay pricing.

| | Brazil invoice | Mexico salary | Euro rent |
| --- | --- | --- | --- |
| Receiver amount (fixed) | R$27,000.00 | $35,000.00 MXN | €2,500.00 |
| Market rate (`commercial_quotation`) | 5.40 BRL per USDC | 18.50 MXN per USDC | 0.8600 EUR per USDC |
| `sender_amount` returned | 5,025.13 USDC | 1,901.40 USDC | 2,921.58 USDC |
| Effective rate (receiver ÷ sender) | 5.3730 | 18.4075 | 0.8557 |
| USDC needed at the market rate | 5,000.00 | 1,891.89 | 2,906.98 |
| All-in cost vs market | 25.13 USDC (50 bps) | 9.51 USDC (50 bps) | 14.61 USDC (50 bps) |

The math for Brazil: 27,000 ÷ 5,025.13 = 5.3730 BRL per USDC delivered. At the market rate, 27,000 ÷ 5.40 = 5,000.00 USDC. The difference, 25.13 USDC, is everything you paid: spread plus fees. As a share: (5.40 - 5.373) ÷ 5.40 = 0.50%, or 50 basis points.

That one number is the honest comparison between providers. Ask each for a receiver-side quote of the same amount at the same moment, then compare `sender_amount`. For the spread side of that math, see [how to calculate FX spread](/resources/more/how-to-calculate-fx-spread).

## What changes when the quote expires?

Only the USDC side. The local amount is what you asked for, so a new quote keeps it and reprices the stablecoin.

Payout quotes expire 5 minutes after creation by default, and SEPA quotes can be shorter because the rail's own deadline can be tighter. An expired quote is rejected. Nothing executes at a new rate behind your back.

So the re-quote loop for an exact amount is simple:

1. Request a new receiver-side quote with the same `request_amount`.
2. Compare the new `sender_amount` with the old one.
3. If your flow needs approval for changes, show the new USDC figure. If not, execute.

The local number never changes in that loop, which is why finance teams like receiver-side quotes for payables. The risk that moves is yours to see before you send. [Who carries FX risk at each step](/resources/more/who-carries-fx-risk-stablecoin-payout) walks through who holds the rate between quote, execution, and settlement.

## What goes wrong with exact-amount payouts?

Most failures are setup mistakes, not rate problems.

- **Wrong side.** Quoting `sender` with a BRL number in `request_amount` sends 27,000 USDC. Test both sides in development before you ship.
- **`cover_fees: false` on a fixed obligation.** The fee comes out of the recipient's amount, and the invoice is short. Use `true` when the number must land in full.
- **Floats.** `27000.00` is rejected. Send `2700000`.
- **Hardcoded 5 minutes.** SEPA quotes can be shorter. Count down from `expires_at` and divide by 1,000 if your library wants seconds.
- **Reusing a quote.** A `quote_id` backs one payout. The second payout against it fails.
- **Under the minimum.** A €8 SEPA payout quoted by EUR amount fails with `sepa_minimum_is_10_eur`.

The [stablecoin payout mistakes guide](/resources/more/stablecoin-payout-mistakes) covers the rest, from wrong networks to bad bank details.

## How do you reconcile exact-amount payouts?

Store the quote with the payout. The quote's `receiver_amount` is the number your obligation should match, and the payout id is what your webhooks report on.

A minimal record per payment:

| Field | Source | Use |
| --- | --- | --- |
| Invoice or payroll line id | Your system | What the payment settles |
| `quote.id` | Quote response | Proof of the locked rate and fees |
| `receiver_amount` | Quote response | Must equal the obligation, in minor units |
| `sender_amount` | Quote response | USDC cost for your ledger |
| `payout.id` | Payout response | Joins webhook events to the obligation |
| Final status | Webhooks | Close the item on completion |

If `receiver_amount` doesn't equal the invoice amount, stop before executing. That check catches the wrong side, the wrong `cover_fees`, and a typo in minor units, all at once.

For contractor runs, the [stablecoin payroll guide for Latin America](/resources/more/stablecoin-payroll-latam-contractors) shows where this fits in a monthly cycle, and the [on/off-ramp liquidity glossary](/resources/more/onramp-offramp-liquidity-glossary) defines every term used here.

## What to do next

Open a free development instance, add a test bank account, and request two quotes for the same local amount: one with `cover_fees: true`, one with `false`. Compare `receiver_amount` on both. Then follow the [payout quotes guide](/docs/payout-quotes) to execute against the one that lands the exact number.
