Going Stellar

Home/Methods

E-commerce · Cross-border

How to compare store profitability across EU countries: VAT rates, currencies and exchange rates

To compare stores that sell in different EU countries, remove each destination country's VAT from revenue, convert every order from its own currency at a dated exchange rate, take costs without the VAT on their own invoices, and only then compare contribution per delivered order. Most of our cross-country errors came from a wrong VAT divisor, a stale exchange rate or a cost read in the wrong currency.

Updated

The short answer: contribution per delivered order, without VAT, in one currency

Store profitability can be compared across EU countries only after three normalisations: revenue without the VAT of the country where the parcel is delivered, every amount converted into one reporting currency at a dated exchange rate, and costs taken without the VAT charged on the supplier's invoice. The comparable figure is contribution per delivered order: revenue minus cost of goods, shipping and marketing, all without VAT.

We sell cash on delivery in Romania, Czechia, Poland, Bulgaria, Slovakia and Hungary, and also in Moldova, which is outside the EU. Cash on delivery (COD) means the customer pays the courier at the door, so only delivered orders count as revenue. Every rule below lives in one shared profitability library that all our reports import, so two reports cannot disagree about VAT or currency.

The formula is contribution = paid ÷ (1 + destination VAT) − goods − shipping − marketing, counted on delivered orders, with goods and shipping already net of the VAT on their own invoices.

Step 1: remove each destination country's VAT from revenue

Revenue from a distance sale to a consumer in another EU country carries the VAT rate of the destination country, not the seller's home rate. The VAT divisor therefore changes per order. The standard rates held in our profitability code are Romania 21%, Bulgaria 20%, Czechia 21%, Poland 23%, Hungary 27%, Slovakia 23% and Croatia 25%. Those standard rates are a snapshot: VAT rates change, some goods take reduced rates, and every rate must be re-checked with the tax authority of the country before use.

A hypothetical example shows why the divisor matters. Two orders are both worth 1,000 without VAT. In Czechia, at 21%, the customer pays 1,210. In Hungary, at 27%, the customer pays 1,270. Divide the Hungarian order by the home divisor 1.21 instead of 1.27 and the report shows about 1,050 of revenue instead of 1,000. The Hungarian store then looks about 5% better than it is, on every single order, and no individual row looks wrong.

A single home-country divisor works for a domestic business, which is why it survives in spreadsheets. Our older profitability sheets divided all revenue by the home rate, which overstated revenue in the higher-rate countries.

Step 2: convert from the order's own currency at a dated rate

Convert each order from the currency recorded on that order, at the rate for the order's date or month. Do not convert per store. A multi-market store can take orders in several currencies, and a country can change currency: Bulgaria moved from the lev to the euro on 1 January 2026, the lev is now derived from the euro at the fixed rate of 1.95583, and the changeover day was the only day in our data with two currencies in one store.

A daily rate is exact for each order; a monthly average is simpler, and a monthly rate per currency is what our profitability engine stores. Two rules matter more than that choice. The open month is refreshed from the central bank's official rates every time the report runs. A closed month stays frozen, because it is the figure that was reported, and only missing currencies are filled in.

Never store a fallback exchange rate. On the first day of a month the official source has no rate yet, and our code once wrote an approximate hard-coded rate into the rate table. That value stayed for the whole month, because nothing was allowed to overwrite it. A fallback rate now lives in memory only, with a warning.

Spreadsheet currency functions fail as well. In one of our reporting sheets a live exchange-rate function returned an error for a few minutes; the error had been stamped into the formulas as a literal multiplier, so it became permanent in the history. Wrap a live rate function in a fallback and reference the rate cell instead of copying its value into formulas.

Step 3: know which currency every cost is in

Revenue, cost of goods and advertising do not have to share a currency, even inside one store. In our stores the cost of goods is recorded in the home currency on every store, including the stores that sell in another currency. A cost of 20 next to a price of 11.99 is therefore not a loss: the two numbers are in different currencies. On a multi-market store, revenue arrives in each market's local currency while cost is held in the store's base currency, so revenue and cost need different exchange rates.

Advertising accounts have their own currency, and that currency cannot be guessed from the numbers. We once inferred from a plausible-looking cost per order that an ad account was in the home currency; the account was in US dollars. Read the currency from the ad account's settings, and keep it next to the account in the mapping table.

Step 4: shipping gross versus net, and why international parcels cost more

Courier invoices include VAT. The VAT on a cost follows the invoice you receive, not the destination of the parcel. If the courier that carries an international parcel invoices from the home country, divide its cost by the home rate, even though the revenue of that same order is divided by the destination rate.

Use the real shipping cost per order, one main parcel per order. Our label tables keep one row per label and labels are often duplicated, so summing them multiplies the cost. Where the real cost is missing, our shipping cascade falls back to a median for that courier, and then to a flat rate.

International parcels cost more than domestic ones. In one review of our own contribution, charging foreign parcels at the domestic rate was one of four corrections, all of which lowered contribution. Compare countries using each country's own parcel cost.

A refused international parcel still cost the outbound trip. Whether the courier also bills the return leg depends on the contract. We changed this rule more than once: one version of our model charged every refused international parcel twice, and the current model charges one leg, because the international rate it uses is already the higher one. Read your own contract rather than copying either rule.

Invoicing under OSS: the basics we check

OSS (the EU One-Stop Shop) lets a seller declare the VAT due on distance sales to consumers in other EU countries through one quarterly return in its home country, instead of registering in each country. The invoice to the consumer carries the destination country's rate, and that includes the shipping line charged to the customer.

Invoicing software usually holds each OSS rate as a named rate per country. If the rate is not set up under that country's name, the invoice is refused; if the software silently picks the home rate, the invoice is issued with the wrong VAT.

We check OSS on real issued invoices, not on settings. A small script downloads a sample of invoice documents, reads the country and the VAT rate printed on each, and compares them with the country table. The sample stays small and slow, because invoicing platforms throttle document downloads. A settings screen does not show which rate actually lands on the invoice; only reading issued invoices does.

A marketplace order feed can report a VAT rate of 0 on its lines as a configuration artefact; that does not make the sale exempt. Outside the EU, OSS does not apply. For Moldova the sale is either an export or a delivery from a local warehouse, and the invoice must state its legal basis; which one applies is a decision for an accountant. Our invoicing software rejected invoices that lacked that mention. Sales to businesses with a VAT number follow other rules, which this method does not cover, and none of this is tax advice.

Where we were wrong

We divided all revenue by the home VAT rate. Higher-rate countries looked better than they were. The VAT divisor now comes from the order's destination country.

We stored a guessed exchange rate. A fallback written on the first day of a month stayed all month, and when we added a store in a new non-EU currency the first report used an estimated rate marked to be refined. Estimated rates now never reach the rate table.

We guessed an ad account's currency from its cost per order. The guess was wrong. Currency is read from the account, never inferred.

Limits, and a short checklist

Contribution per delivered order leaves out fixed costs that differ by country, such as customer service in another language. Delivery rates differ by country and settle at different speeds, so a fresh window flatters no one equally. Exchange-rate movements change the comparison from month to month; to compare operations rather than currencies, recompute both months at one rate. Tax rules change, and the rates above must be verified.

Checklist: revenue divided by the destination country's VAT, re-checked; every order converted from its own currency at a dated official rate; open month refreshed, closed month frozen, no stored fallbacks; cost currency and ad-account currency read, not assumed; shipping net of the VAT on the courier's invoice, one main parcel per order; refused parcels charged the legs the contract bills; OSS verified on real invoice documents; non-EU sales invoiced with a legal basis chosen by an accountant.

Questions and answers

How do I compare the profitability of online stores in different EU countries?

Compare contribution per delivered order. For each order, divide what the customer paid by one plus the destination country's VAT rate, convert it from the order's own currency at a dated official exchange rate, then subtract cost of goods, shipping and marketing, each without the VAT on its own invoice. Only after these steps do stores in different countries and currencies become comparable.

Which VAT rate applies to an online sale to a consumer in another EU country?

For distance sales to consumers inside the EU, the invoice normally carries the VAT rate of the country where the goods are delivered, declared through the One-Stop Shop (OSS) in the seller's home country. Standard rates differ by country, for example 21% in Czechia, 23% in Poland and 27% in Hungary at the time of writing, and must be re-checked with each tax authority.

Should I use a daily or a monthly exchange rate for profitability reports?

Either works if it is official, dated and applied per order. A daily rate is exact; a monthly average is simpler. What matters more is that the open month is refreshed from the official source on every run, that closed months stay frozen at the rate that was reported, and that no approximate fallback rate is ever written into the rate table.

Is shipping VAT calculated at the destination country's rate?

Two different things are meant. The shipping charged to the customer on the invoice carries the destination country's rate under OSS. The courier's invoice to the seller carries the VAT of the courier's own invoice, so when a home-country courier carries an international parcel, the seller removes the home rate from that cost, not the destination rate.

Does OSS apply to sales to Moldova or other non-EU countries?

No. OSS covers distance sales between EU countries only. A sale to a non-EU country such as Moldova is treated either as an export or as a delivery from a local warehouse, and the invoice has to state the legal basis for its VAT treatment. Which basis applies depends on how the goods move, and an accountant should decide it.

How to cite this

Going Stellar (2026). How to compare store profitability across EU countries: VAT rates, currencies and exchange rates. GOING STELLAR S.R.L..
https://goingstellar.ro/methods/compare-store-profitability-eu-countries-vat-currency/

Read as Markdown

All methods

Contact

Tell us what is not working

Write in English or Romanian. A person reads it — usually the same person who would do the work — and answers within one business day.