Skip to content
All posts

Currency conversion and refunds: the spread you pay twice

Refunds convert at the live rate on refund day while your original conversion fee never returns. Here is the cash consequence and how to bound your exposure.

FeeGuard13 min read

Currency conversion and refunds: the spread you pay twice

For platforms settling Connect payments across currencies, this article answers exactly how Stripe converts on charge day versus refund day, which clauses of the FX documentation move real money, and who absorbs the difference between the two rates under each Connect charge pattern.

Where conversion happens in Connect

Stripe defines the trigger plainly: FX takes place whenever the starting currency of a funds flow differs from its destination currency — on payments when the presentment currency differs from the settlement currency, and on transfers when the sending platform's balance currency differs from the receiving connected account's (multiple currencies). Running a Connect platform across borders therefore puts conversions at four distinct points, each with its own money consequences:

  1. Charge day: the customer pays in one currency and the payment settles in another. On destination charges without on_behalf_of, Stripe converts first from presentment currency to the platform's default currency, then again toward the connected account.
  2. Transfer time: when the balance you transfer from is in a different currency than the balance receiving it, another conversion happens on the way through. The documentation's own illustration: a USD charge settling on a GBP platform, transferred onward to a connected account whose default currency is EUR — two conversions on one sale, at two different moments.
  3. Payout day: if no bank account or debit card exists for a balance's currency, Stripe converts that balance toward your default bank account's currency as part of the payout.
  4. Refund day: the reversal leg converts at whatever the market says that day. This point behaves differently from the other three, and it is the subject of this article.

The first three points can be planned, quoted, or scheduled. The fourth reprices itself, after the fact, on someone else's schedule — the buyer's.

What Stripe documents about rates

Two documented facts set the stage. First, on rates: when Stripe provides currency conversion services, it generally applies the mid-market rate based on third-party pricing data, and conversion on Stripe is subject to fees as detailed on Stripe's pricing page (exchange rates). Second, on control: the FX Quotes API lets you lock rates for some conversions but not others. Knowing the boundary matters, because teams routinely assume a quote they took at charge time still governs the money weeks later. It does not.

Quotes also carry limited lock windows — the documented examples use hour and five-minute durations — so even a lockable leg reprices at the live rate if execution slips past its window. A quote is a short-term instrument, not a hedge position.

Conversion pointLockable with an FX quote?Rate applied
Payment presentment → settlementYes, via quote ID on the PaymentIntentLocked quote within its duration
Standalone transfer between differing balance currenciesYes, via quote ID on the transferLocked quote within its duration
Conversion occurring on a transfer between balances (destination flow)NoLive rate at execution
Application fee conversionNoLive rate at execution
Payout conversionNoLive rate at execution
Refund-day conversionNoLive rate on refund day

For destination charges without on_behalf_of the documentation states you can't use FX quotes for any conversion occurring on the transfer from the platform to the connected account, nor on any conversion of application fees; for payouts it states flatly that FX quotes are not supported. Every row marked "No" reprices at the live rate when it executes — including, critically, the last one.

The refund-day rule, quoted

The FX Quotes API page carries a section titled FX on refunds, quoted here in full:

When you refund a payment that was originally converted to another currency, we use the live FX rate at the time of the refund. This is true regardless of whether you used FX quotes to set your FX rate on the original payment. Stripe doesn't charge an FX fee for any conversion on the refund. Stripe doesn't refund the FX fee charged on the original transaction.

Four clauses, four cash consequences:

  • "the live FX rate at the time of the refund." Your refund leg floats. Whatever the market did between sale and refund lands entirely on whichever balance funds the refund.
  • "regardless of whether you used FX quotes." A locked quote protects the original conversion only. It provides zero protection on the refund leg; there is no product switch today that changes this.
  • "doesn't charge an FX fee for any conversion on the refund." The small mercy: Stripe adds no new conversion fee on the way back. You pay the rate movement, not a second toll on top of it.
  • "doesn't refund the FX fee charged on the original transaction." The sale is undone, but the first toll survives. You paid to convert in, and you now pay the spread to convert out.

Read together, the rule means a cross-currency refund can cost more than the sale earned even though the buyer received every cent back. That asymmetry is the "twice" in the title: once at charge day, once at refund day. It is also exactly what practitioners mean by the term — see what FX slippage in payments means for the short version of this same mechanism.

A worked two-rate example

All inputs below are illustrative assumptions chosen to make the arithmetic checkable — the rates are hypothetical and the fee percentage stands in for whatever Stripe's pricing page publishes for your currency pair:

  • Presentment €100.00 on a EUR card; your platform settles USD.
  • Charge-day rate: 1.0900 USD/EUR (assumption).
  • Conversion fee: 1% of the converted amount (assumption; actual published on the pricing page).
  • Full refund six weeks later; refund-day rate: 1.1500 USD/EUR (assumption).

Arithmetic, one step per line:

  • Charge day settlement: €100.00 × 1.0900 = $109.00 enters your USD settlement.
  • Assumed conversion fee: $109.00 × 0.01 = $1.09.
  • Net receipt from the sale: $109.00 − $1.09 = $107.91.
  • Refund-day debit: €100.00 × 1.1500 = $115.00 leaves the USD balance, with no new FX fee on this leg.
  • Rate spread: $115.00 − $109.00 = $6.00.
  • Cash delta versus what the sale actually left you: $115.00 − $107.91 = $7.09.

Conclusion: funding that full refund costs $7.09 more than the sale ever put in your account — $6.00 of pure rate movement plus the $1.09 original fee that the documentation says is not returned. The buyer is whole, Stripe has kept its tolls, and the difference comes out of whoever's balance funded the refund.

Movement cuts both ways, unevenly. Holding the same assumptions, the table shows the refund debit and your cash position across three rate paths:

Refund-day rate (assumed)Move vs charge dayRefund debit from USD balanceCash delta vs $107.91 received
1.0900flat$109.00+$1.09
1.1500(1.1500 − 1.0900) ÷ 1.0900 ≈ +5.5%$115.00+$7.09
1.0300(1.0300 − 1.0900) ÷ 1.0900 ≈ −5.5%$103.00−$4.91

Note the asymmetry the table exposes: a 5.5% adverse move costs you $7.09, while an equally sized favorable move relieves you by only $4.91, because the unreturned $1.09 fee sets a floor under your losses. Flat rates still leave you down exactly the fee. There is no scenario in which the cross-currency round trip costs nothing.

Who absorbs it by charge pattern

Which balance funds the refund decides who eats the spread, and that follows directly from Stripe's documented debit rules for each charge type:

  • Destination and separate charges and transfers. The platform balance is debited for refunds (and disputes), with or without on_behalf_of. So the platform converts at the refund-day rate first and negotiates recovery afterward. Recovery is a transfer reversal, which adds back to the platform's available balance only what the connected account can cover: the separate-charges documentation states a reversal succeeds only if the connected account's available balance exceeds the reversal amount or connected reserves are enabled. On destination charges, requesting the reversal inside the refund call when the seller lacks funds produces an API error rather than a pending refund. And if the refund itself fails mid-flight, funds return to the balance within up to about 30 days — for destination charges, back to the platform's balance — so a bounced refund briefly strands the converted amount on whichever side funded it.
  • Direct charges. The connected account funded the sale — direct charges are always converted to the connected account's default currency from the presentment currency, with the application fee converting toward the platform separately. The refund debits the connected account, so the seller's settlement absorbs the refund-day rate. Your exposure concentrates in the fee leg instead: pass refund_application_fee=true deliberately, because fees are not automatically refunded and the connected account otherwise loses that amount (direct charges).

One constraint bites specifically at the cross-currency edge case. Quoted from the separate-charges page: "If the transfer reversal requires a currency conversion, and the reversal amount would result in a zero balance after the conversion, it returns an error." In other words, even a willing seller with just enough balance can fail to make you whole when rounding across currencies zeroes them out. Cross-border recovery carries enough wrinkles of this kind that we keep a dedicated playbook for cross-border recovery complications.

Also remember timing: refunds draw on the available balance only, and shortfalls become pending until funded (balance becomes available). A large foreign-currency refund against a thin balance may sit pending precisely when you want it gone.

Detection and bounds

You cannot eliminate refund-day floating, but you can measure it, and measurement starts from a baseline every finance team already has. The method, stated as formulas rather than statistics:

  • expected_refund_debit = presentment amount × charge-day rate (from your own records of the sale).
  • observed_refund_debit = the amount actually debited from the settlement-currency balance for the refund.
  • slippage = observed − expected.

Label every input honestly: the charge-day figure is either the rate you observed or were quoted on the sale, and everything else comes from your own ledger. For the €100.00 example above, expected = 100.00 × 1.0900 = $109.00, observed = $115.00, slippage = $6.00 — matching the hand computation, which is exactly what a baseline should do.

Aggregate the result and two readings fall out. Slippage summed over a quarter tells you the size of the exposure; per-refund slippage flags any single refund that moved beyond what the market did that day, which is how you catch an operational error hiding inside FX noise. A cheap stress bound completes the picture: pick the largest single-day move you are willing to treat as plausible — choose the number yourself; the point is a bound, not a forecast — multiply it by your cross-currency refund volume in presentment terms, and you have a ceiling for what one bad refund day can cost. We keep a running version of this exact baseline in the FX slippage audit; FeeGuard monitors platforms for this class of drift alongside unreversed transfers and kept fees, reporting findings with the underlying evidence attached.

Two boundaries keep the method sound. Treat the output as a bound on FX-caused cost, not a claim about Stripe's internal rate selection: your baseline rate and Stripe's executed rate can differ slightly by source and timestamp. And exclude refunds on single-currency payments entirely — with no conversion legs there is no spread, only ordinary processing-fee economics.

Reducing exposure structurally

Floating refund-day rates are a fact of the rails; structure determines how much of the fact reaches your income statement. Four levers, in descending order of permanence:

  1. Match charge currency to settlement currency wherever your product allows. If presentment equals settlement, there is no charge-day conversion, no fee on one, and no spread at refund time — the entire vector disappears rather than shrinks.
  2. Where multi-currency flows are unavoidable, use multi-currency settlement. Connected accounts eligible to settle in additional currencies change which conversions happen at all; see the options described in working with multiple currencies. Fewer conversion hops means fewer places for the spread to land.
  3. Lock quotes where supported, knowing the limits. An FX quote pins the payment leg and standalone transfers, which stabilizes what sellers receive; it does nothing for the refund leg, application-fee conversions, or payouts, per the table above.
  4. Decide deliberately who bears residual risk, and write it into seller terms. Whether your marketplace claws back the refund-day delta, splits it, or absorbs it as a cost of doing business is a policy choice. Sellers accept clauses they can verify, so attach the same baseline computation from the previous section to your statements. Whichever side bears it, book the residual as a known line item rather than discovering it during payout reconciliation. We maintain the monitoring side of this in the Connect FX slippage solution.

What is not on the list: hoping rates average out. They may, but a refund is not a portfolio — each one settles at one rate on one day, and the loss realization is immediate and one-sided, as the asymmetric table showed.

Frequently asked questions

Does Stripe charge an FX fee when it converts my refund?

No. The FX Quotes API documentation states Stripe doesn't charge an FX fee for any conversion on the refund. The catch sits in the next sentence: Stripe also doesn't refund the FX fee charged on the original transaction. So the refund conversion itself is toll-free, but the round trip still costs you the original fee plus whatever the rate moved.

Can I lock the refund-day rate with an FX quote?

No. Quotes apply to the original payment conversion and to standalone transfers, and the documentation says the refund uses the live FX rate at the time of the refund regardless of any quote used on the original payment. Payout conversions are likewise unsupported for quotes. Today there is no mechanism to fix the refund leg in advance.

Who owes the spread on a destination charge?

The platform balance funds the buyer's refund first, converting at the refund-day rate, because Stripe debits the platform for refunds on destination charges. Recovery then depends on reversing the seller's transfer, which succeeds only up to what their available balance covers. Whatever the reversal cannot pull back stays with the party your seller terms assign it to.

Do FX quotes help anywhere in a refund scenario?

Yes, indirectly. Locking the payment leg stabilizes the amount that settled originally, which makes your baseline computation exact instead of estimated — you know precisely what the sale put in your account before the refund repriced it. That tightens your slippage measurement even though the refund-day leg itself remains floating.

Check your own last 90 days

This arithmetic runs silently on every cross-currency refund your platform issues, and each occurrence leaves readable evidence in your Stripe objects. FeeGuard exists to surface it: the free audit reads your last 90 days of Connect activity through a restricted, read-only API key and reports every unreversed transfer, unreclaimed application fee, uncovered dispute loss, and instance of FX slippage with the amounts attached, so you can verify each line yourself. You get the answer first; ongoing monitoring is optional afterward.

Run the free 90-day audit.

FeeGuard is an independent product and is not affiliated with, endorsed by, or sponsored by Stripe, Inc.