Skip to main content
CrossBorderFreelance
Informational only — not tax or legal advice

The output is a comparison of fees and FX margins across providers based on each provider's published rates and our research-based estimates where rates are not published — not a recommendation to use any specific provider, nor a guarantee of the rate you will receive. For decisions affecting your taxes or legal status, consult a provider's own quote at the moment of your transaction.

Data last verified 15 Jul 2026 — methodology

How the FX Reality Check tool computes fees and margins

Compiled by the Cross Border Freelance editorial team. Last reviewed . [REVIEWED] — CPA / international finance reviewer byline to be added after editorial review pass.

TL;DR

The tool fetches a live mid-market rate, applies each provider's published or estimated FX margin plus its fees, and ranks providers by the net amount actually delivered. It does not recommend a "best" provider, calculate tax, or guarantee the rate you'll get at transaction time.

1. What is the mid-market rate, and where does it come from

The mid-market rate (also called the "real" or "interbank" rate) is the midpoint between the buy and sell price of a currency pair on the global wholesale market — the rate you'd see quoted on Google, Reuters, or XE, with no markup added. No retail provider actually gives you this exact rate; every provider marks it up by some amount, which is the FX margin (see section 2).

This tool fetches the mid-market rate from Frankfurter, which republishes the European Central Bank's daily reference rates, with a secondary open-data source (ExchangeRate-API's open endpoint) filling in currencies the ECB does not publish. The merged table is cached for up to six hours via Cloudflare KV so repeated page loads don't hammer either upstream API. If both live sources are temporarily unavailable, a clearly-labelled stored snapshot is shown instead of a broken page. The exact source name and fetch timestamp are always displayed next to the rate in the comparison table banner — never hidden or approximated.

2. Published vs. estimated FX margins

An FX margin is the difference between the mid-market rate and the rate a provider actually gives you, expressed as a percentage. It is a cost that is entirely separate from any advertised "fee" — a provider can advertise "$0 fees" while still marking up the exchange rate itself by several percentage points, which is often the larger of the two costs.

Not every provider discloses this number, so the tool treats the two cases differently:

  • Published (fxMarginType: 'published'): the provider discloses its FX margin on its own pricing page (e.g. Wise, Revolut Business on some plans). We show that exact percentage.
  • Estimated (fxMarginType: 'estimated'): the provider does not disclose its margin (e.g. PayPal, traditional bank wires, Western Union). We show an independently-researched { min, max } band based on comparing the provider's advertised rate against the mid-market rate across sample transactions and public reporting — never a single fabricated precise number. Estimated rows are always visibly labelled "estimated" in the comparison table.

3. How fees are applied

Each provider record also carries a fee model, applied on top of the FX margin:

  • Fixed fee — a flat amount charged per transfer, in a specified currency (0 if the provider charges none).
  • Percentage fee — a percentage of the transfer amount, charged separately from the FX margin (0 if none).
advertisedRate = midMarketRate × (1 − marginPct / 100)
netDelivered (send) = (amount − fixedFee) × (1 − percentageFee / 100) × advertisedRate

When comparing "receive" instead of "send", the math is inverted to solve for the source amount required so the recipient nets the amount you specified. The full implementation is in src/lib/fx-margin.ts, which is open for review.

4. Ranking — by net amount delivered only

Every row in the comparison table is sorted by netDelivered — the amount the recipient would actually receive after the FX margin and all fees are deducted — from highest to lowest. The rankProviders() function in src/lib/fx-margin.ts does not take any affiliate field as an input.

Affiliate relationships never influence ranking. When we have an affiliate relationship with a provider, that provider's row carries an additional "(affiliate)"-labelled link — a separate visual element appended after all the ranking-relevant cells. It never changes that row's position in the list.

5. What this tool does not do

  • Does not recommend a "best" provider — it presents computed comparisons only.
  • Does not calculate tax, filing obligations, or any tax determination.
  • Does not guarantee the rate shown will be the rate you receive — providers quote at the moment of the actual transaction.
  • Does not let affiliate payout influence ranking, sort order, or which row appears first.
  • Does not store your inputs on our servers — all scenario data stays in your browser's localStorage.

6. Data sources

The tool compares 7 providers, each sourced from that provider's own public pricing page (never a blog, review site, or third-party aggregator):

Provider Margin type Pricing source
Wise Business Published wise.com/pricing
Revolut Business Published revolut.com/business/pricing
Airwallex Estimated airwallex.com/pricing
Payoneer Estimated payoneer.com/fees
PayPal Estimated paypal.com/merchant-fees
SWIFT bank wire (mid-tier bank) Estimated Independent research across sample retail bank wire quotes
Western Union Estimated westernunion.com/price-estimator

All provider records are last verified: . Rows still marked dataStatus: 'seed' show a visible "pending verification" notice in the comparison table until manually re-checked against the live pricing page above.

Frequently asked questions

Can this tool show me the exact rate I will get?

No. FX rates are quoted at the moment of a transaction and move constantly — sometimes multiple times a minute during volatile periods. What this tool shows is a snapshot comparison: the current mid-market rate plus each provider's disclosed or estimated margin. Always check the provider's own quote at the moment you actually send money before relying on a specific number.

What is an FX margin?

An FX margin — also called a spread or markup — is the gap between the mid-market rate (the real, no-markup exchange rate you'd see on Google or Reuters) and the rate a provider actually gives you. It is separate from any advertised transfer "fee": a provider can advertise "$0 fees" while still marking up the exchange rate itself by 1-3% or more, which is often the larger cost.

Why are some margins shown as an estimated range instead of an exact number?

Not every provider publishes its FX margin. Where a provider discloses it — Wise and Revolut Business, for example, publish their markup — we show that exact percentage, labelled "published". Where it is not disclosed — PayPal, traditional bank wires, and remittance services like Western Union typically do not publish a margin — we show an independently-researched band (e.g. "2.0–4.5%") based on comparing the provider's advertised rate against the mid-market rate across multiple sample transactions and public reporting. This band is always labelled "estimated" and is never collapsed into a single fabricated number.

Do you rank providers by how much commission they pay you?

No. Every row is ranked strictly by netDelivered — the amount the recipient would actually receive after all fees and the FX margin are deducted. This computation lives in src/lib/fx-margin.ts in the rankProviders() function, which does not take any affiliate field as an input. Affiliate CTAs are rendered as a separate badge appended after the ranking-relevant cells and never move a row up or down.

Where does the mid-market rate come from, and how often does it refresh?

The mid-market rate is fetched from Frankfurter, which republishes the European Central Bank's daily reference rates, with a secondary open-data source (ExchangeRate-API's open endpoint) filling in currencies the ECB does not publish. The merged table is cached for up to six hours via Cloudflare KV, so repeated page loads don't hammer either upstream API. If both live sources are temporarily unavailable, a clearly-labelled stored snapshot is shown rather than a broken page. The source name and the exact fetch timestamp are always displayed next to the rate — never hidden.

Can I trust the fee and margin data shown here?

Every provider row shows a "last verified" date, and rows still marked as seed data display a visible "pending verification" notice. Seed data is hand-researched from each provider's own public pricing page — never from a blog, review site, or aggregator — but has not yet been manually cross-checked against the live pricing page a second time. Once a Sam manually re-verifies a provider's numbers against its current pricing page, dataStatus flips to "verified". See the data sources table below for the exact pricing page URL used for each of the 7 providers.

Was this tool useful? — help us improve