---
title: "Who pays the fees at a cross-border checkout: shopper or merchant?"
seoTitle: "Who pays cross-border checkout fees: shopper or merchant?"
description: "How to decide who pays fees at a cross-border checkout in 2026: cover_fees, sender vs receiver quotes, platform fees, and how to show the total."
date: "2026-10-24"
updated: "2026-10-24"
category: "payments"
author: "BlindPay Team"
faq:
  - q: "Should the shopper or the merchant pay cross-border checkout fees?"
    a: "For most online sales, let the shopper's local total include fees and exchange, and let the merchant receive the exact list price. The shopper sees one number before paying, so there is no surprise, and the merchant's revenue matches the price list. Absorb fees on the merchant side only when the shopper's local amount must stay fixed, such as a BRL invoice."
  - q: "What does cover_fees do on a BlindPay payin quote?"
    a: "It decides who pays. With cover_fees false, the fee is deducted from the stablecoin amount the BlindPay customer receives, which is the most common setup. With cover_fees true, the sender pays: the fee is added on top of the fiat amount they send. For a checkout, the BlindPay customer is the merchant and the sender is the shopper."
  - q: "What is the difference between a sender and a receiver quote?"
    a: "It sets which side request_amount is denominated in. A sender quote fixes what the shopper sends in their currency. A receiver quote fixes what the merchant receives in stablecoins. Pair a receiver quote with cover_fees true to charge a USD price: the merchant gets exactly that amount and the shopper's local total carries the fees."
  - q: "How does a checkout platform add its own fee?"
    a: "Create a partner fee once with a percentage in basis points and a flat amount in cents, then pass its partner_fee_id on every payin quote. BlindPay collects the fee during each transaction, accumulates it over the calendar month, and releases it on the first day of the next month, after netting out your BlindPay invoice. Each quote reports partner_fee_amount."
  - q: "How should I show fees on the checkout page?"
    a: "Show the total the shopper pays in their own currency, large, with a short line such as Includes fees and exchange. Show the amount the merchant receives in small print if your brand allows it. Add a countdown to the quote's expiry. Baymard found 12% of shoppers left because they could not see or calculate the total cost up front."
---

At a cross-border checkout, the cleanest default is that the shopper pays fees and exchange inside one local total, and the merchant receives the exact list price. On BlindPay, that is a receiver-denominated payin quote with `cover_fees: true`. Flip it only when the shopper's local amount must stay fixed, and then the merchant absorbs the fees.

This guide belongs to the series on [what a global payments checkout is](/resources/more/what-is-a-global-payments-checkout). For the platform margin itself, read [partner fees on live quotes](/resources/more/partner-fees-markup-on-live-quotes).

**Key takeaways**

- Two BlindPay quote fields decide fee incidence: `currency_type` (`sender` or `receiver`) and `cover_fees` (`true` or `false`).
- `currency_type: "receiver"` plus `cover_fees: true` gives the merchant exactly `request_amount`, with fees and exchange inside the shopper's `sender_amount`.
- A platform fee rides on top through `partner_fee_id`, collected per transaction and paid out monthly.
- Baymard found 40% of US shoppers abandoned over extra costs and 12% because they could not see the total up front.
- BlindPay discloses its own fees in the live quote before execute, so the page always shows a real number, never an estimate.

## Why does fee placement change conversion?

Shoppers punish late surprises more than high prices. [Baymard's checkout research](https://baymard.com/lists/cart-abandonment-rate) ranks "extra costs too high (shipping, tax, fees)" as the top reason for abandonment, at 40% of US shoppers, and 12% left because they could not see or calculate the total order cost up front.

Cross-border orders add two more costs a shopper worries about: the exchange rate and the bank's own charges. [Stripe's localization guide](https://stripe.com/resources/more/payment-localization-best-practices-a-guide-for-scaling-payments-worldwide) gives the same advice from the merchant side: show prices in the buyer's currency throughout the flow, including the final charge, to avoid surprises.

So the real question is not only who pays. It is whether the shopper sees one final number before they commit.

## Which two quote settings decide who pays?

`currency_type` decides which side of the payment is fixed. `cover_fees` decides which side the fee comes from. On a checkout, the BlindPay customer is the merchant and the sender is the shopper.

| Setup | What stays fixed | Who pays the fees | Best for |
| --- | --- | --- | --- |
| `receiver` + `cover_fees: true` | What the merchant receives, in stablecoins | The shopper, inside their local total | Stores and SaaS priced in USD |
| `sender` + `cover_fees: false` | What the shopper sends, in local currency | The merchant, deducted from what it receives | Invoices or prices set in BRL, MXN, ARS, or COP |
| `sender` + `cover_fees: true` | The shopper's base amount, with fees added on top | The shopper, as an added fee line | Marketplaces that show a separate service fee |

BlindPay's [payin docs](/docs/payins) describe the two `cover_fees` values plainly: with `false`, the fee is deducted from the stablecoin amount the customer receives, the most common setup; with `true`, the sender pays and the fee is added on top of the fiat amount they send.

Three currencies add a rounding rule. MXN, COP, and ARS settle in whole units, so computed sender amounts round down to a whole peso. Your page should display the quote's `sender_amount`, never a number you computed yourself.

## How does the default setup work, step by step?

Price in dollars, let the quote convert, and keep the merchant whole. [Receiver-side quotes](/resources/more/pay-exact-local-amount-receiver-side-quote) explain the same mechanism on the payout side.

1. **The merchant sets a USD price**, for example US$100.00, sent as `request_amount: 10000`.
2. **The shopper picks a rail**, such as Pix, SPEI, Transfers 3.0, PSE, ACH, wire, or RTP.
3. **Your backend requests a payin quote** with `currency_type: "receiver"`, `cover_fees: true`, and the platform's `partner_fee_id` if there is one.
4. **The quote returns `sender_amount`**, the shopper's total in their currency with fees and exchange included, plus `receiver_amount`, which equals the price, and `expires_at`, 5 minutes out.
5. **The page shows the total large**, "Includes fees and exchange" under it, and a countdown.
6. **The shopper pays.** The merchant's wallet receives exactly the price in stablecoins.

If the countdown ends, quote again on the next click. Each new quote carries a fresh rate and the same guarantee for the merchant.

## Illustrative example: one US$100 order, three fee choices

This example is illustrative. It uses letters for BlindPay's per-transaction fee, because the real number comes only from the live quote, and an example platform fee of 1% plus US$0.30 that a platform might choose for itself.

- **Shopper pays (receiver + `cover_fees: true`).** The merchant receives US$100.00. The shopper's local total equals US$100.00 plus the quote's fee F plus the platform's US$1.30, converted at the quoted rate. One number on the screen.
- **Merchant pays (sender + `cover_fees: false`).** The shopper pays exactly the local price, say a fixed BRL amount on an invoice. The merchant receives that amount converted, minus F and minus the platform fee.
- **Split view (sender + `cover_fees: true`).** The shopper sees a base amount and a fee line. Common on marketplaces, where buyers already expect a service fee.

The same decision shows up on card gateways. [Stripe's Pix docs](https://docs.stripe.com/payments/pix) say Brazilian customers paying a business outside Brazil owe IOF of 3.5%, paid by the customer by default, or absorbed by the merchant if it chooses. Different tax, same question: inside the shopper's total, or out of the merchant's margin.

## How should a platform fee fit in?

A platform fee is a markup on top of the provider's fee, and it should travel inside the same quote. That way the shopper still sees one total and your revenue is reported per transaction.

On BlindPay, create a partner fee once with `payin_percentage_fee` in basis points and `payin_flat_fee` in cents, save the `pf_...` id, and pass `partner_fee_id` on every payin quote. Each quote returns `partner_fee_amount`, the amount collected on that transaction. BlindPay collects the fee during each transaction, accumulates it over the calendar month, releases it on the first day of the following month, and nets your BlindPay invoice out first.

There is no update endpoint, so a pricing change means deleting the fee and creating a new one. Plan fee changes per merchant tier, not per order.

Who pays the platform fee follows the same `cover_fees` rule. With `cover_fees: true` on a receiver quote, the shopper's total includes it and the merchant still receives the full price. [Showing a quote with fee disclosure](/resources/more/cross-border-quote-screen-fee-disclosure) covers how to label it.

## How does BlindPay handle fees at checkout?

BlindPay puts every fee in the quote, before the shopper commits. Its pricing combines a monthly plan (platform access) with per-transaction fees that vary by rail and network and are disclosed only in the live quote before execute. There is no static rate card to copy onto your page, which is the point: the page shows the real total for that rail, that amount, and that minute.

The quote locks the rate and fees for 5 minutes, so the number the shopper sees is the number they pay. With `currency_type: "receiver"` and `cover_fees: true`, the merchant receives exactly the price on every rail, whether the shopper pays by Pix, SPEI, Transfers 3.0, PSE, ACH, wire, or RTP.

For platforms, the partner fee turns each payment into revenue without a second charge. For merchants, withdrawals have their own payout quote with its own fee disclosure, over ACH, wire, RTP, or SWIFT (POBO/COBO). [Recipient fees on local payouts](/resources/more/recipient-fees-to-receive-local-payouts) covers what the receiving bank may charge on that leg.

**Who this is for:** checkout platforms setting their take rate, and merchants deciding whether to price in USD or in local currency.

## Methodology and sources

Abandonment figures come from [Baymard](https://baymard.com/lists/cart-abandonment-rate) (updated September 22, 2025). Localization advice comes from [Stripe's guide](https://stripe.com/resources/more/payment-localization-best-practices-a-guide-for-scaling-payments-worldwide). The IOF example comes from [Stripe's Pix docs](https://docs.stripe.com/payments/pix). BlindPay behavior comes from the [payins](/docs/payins), [payin quotes](/docs/payin-quotes), and [partner fees](/docs/learn/partner-fees) docs, as of October 2026. For the currency decision behind the fee decision, read [local currency pricing at checkout](/resources/more/local-currency-pricing-at-checkout).

## What to do next

Pick one default for your whole catalog: shopper pays, merchant receives the list price. Then create a test partner fee on a BlindPay development instance, request a receiver quote with `cover_fees: true`, and check that `receiver_amount` equals your price.
