Tax is the one PrestaShop setting where a quiet mistake compounds for months before anyone notices. A product assigned to the wrong tax rules group ships untaxed; a missing country in a group charges 0% to every customer from that country; a rounding mode that disagrees with your accountant produces invoices that are off by a cent in a way auditors do notice. None of it throws an error. The cart still checks out, the order still confirms, and the gap only surfaces when you reconcile VAT at quarter-end — or when a tax authority does it for you.
This guide is about the mechanics: how PrestaShop's tax engine is actually built, the exact back-office paths and configuration keys, and how to wire up destination-based EU VAT so it just works and then stays invisible. The legal side — when you must register for OSS, how the €10,000 threshold works, what evidence you must keep — is its own subject; we cover that in VAT in the EU: OSS, IOSS and what your store must handle. Here we assume you already know what rate to charge, and you want PrestaShop to charge it correctly every time.
How PrestaShop models tax: three layers, not one
The single most useful thing to understand before you touch anything: PrestaShop does not have a "tax rate" you set on a product. It has three nested objects, and a product points at the top one.
| Layer | What it is | Back-office home | Class |
|---|---|---|---|
| Tax | A single named rate — "DE Standard 19%", "FR Reduced 5.5%". Just a number with a label and an active flag. | International → Taxes | Tax |
| Tax Rule | One line that says "for this country (optionally this state/zip range), apply this Tax". The bridge between a rate and a place. | Inside a group's editor | TaxRule |
| Tax Rules Group | A named bundle of Tax Rules — "EU Standard Rates", "EU Reduced (books)". This is what a product, a carrier or gift wrapping actually points at. | International → Taxes → Tax Rules | TaxRulesGroup |
So what does this buy you? You define each country rate once as a Tax, then assemble groups that reuse those rates. A product never names a country — it names a group, and the group decides the rate based on the customer's delivery address at calculation time. Change Germany's rate once at the Tax level and every group that references it updates. That indirection is exactly what makes a 27-country EU setup maintainable instead of a spreadsheet you edit by hand.
When an order is placed, PrestaShop resolves the rate through the delivery address against the product's group — the TaxManagerFactory hands the work to TaxRulesTaxManager, which matches the address's country (and state/zip where relevant) to a TaxRule and feeds the resulting rate into a TaxCalculator. You never call this directly, but knowing the chain is what lets you debug a "why is this order untaxed" ticket in two minutes instead of two hours.
Building the EU setup, step by step
Step 1 — Create one Tax per rate you actually charge
Go to International → Taxes and add a Tax for every standard rate you'll collect. A store shipping standard-rated physical goods across the EU needs all 27 member-state standard rates, so name them so a human can scan the list: DE Standard 19%, FR Standard 20%, PL Standard 23%, and so on. If you sell anything that qualifies for a reduced rate (books, food, some medical goods), add those as separate Taxes too — FR Reduced 5.5%, DE Reduced 7% — because reduced rates are tied to specific product categories and differ country by country.
The "Enable" toggle on a Tax matters: a disabled Tax stays in the database (so historical orders keep their correct rate) but won't appear in the dropdown when you build rules. That's how you retire an expired temporary rate without corrupting old invoices.
Step 2 — Assemble a Tax Rules Group per product profile
Under International → Taxes → Tax Rules, create a group — start with EU Standard Rates. Inside it, add one Tax Rule per country, each pointing the country at its matching Tax. This is the tedious part, and it's the part people get wrong: you must add a rule for every EU country you ship to, including your home country.
Here is the failure mode that bites everyone. If a customer's delivery country has no rule in the group, PrestaShop does not guess — it applies 0% tax. There's no warning. An order from Luxembourg with no Luxembourg rule sails through at net price, you still owe Luxembourg the VAT, and you simply didn't collect it. Treat "every shippable country has a rule" as a checklist item you verify, not an assumption.
If you sell mixed-rate goods, you'll end up with several groups — EU Standard Rates, EU Reduced (books), EU Zero / Exempt. Each is just a different bundle of the same underlying Taxes.
Step 3 — Point products at the right group
Open a product, go to the Pricing tab, and set Tax rule to the correct group. This is the step that silently breaks new-product workflows: depending on your PrestaShop version, form and import defaults, a new or imported product can default to No tax or to an unintended tax rules group, so if someone leaves it wrong once — or an import fills it incorrectly — every product added in a hurry afterwards carries that mistake until an audit finds it. Explicitly verify every product's tax rules group rather than trusting any pre-fill.
So what? Make "set the tax rule" an explicit step in your product-creation checklist rather than trusting the pre-fill, and spot-check it after any CSV import — the import will happily accept a blank or wrong tax group and you'll never see a red flag in the UI. For a catalogue already live, a quick filtered export of products by tax group is the fastest way to catch the untaxed strays.
The settings that decide the final number
Two products in a cart, the "right" rates configured, and the invoice total still disagrees with your accountant's — that's almost always rounding or a tax-on-extras setting, not the rates themselves.
Rounding: where Germany and France actually differ
Under Shop Parameters → General, the Round mode and Round type settings (PS_PRICE_ROUND_MODE and PS_ROUND_TYPE) change the math, not just the display. Round on each item tots up rounded line totals; Round on the total rounds once at the end. On a multi-item cart these produce different totals — sometimes by a cent or two, which is exactly the kind of discrepancy that makes invoices fail reconciliation.
This isn't a preference, it's jurisdiction-dependent. As a rule of thumb German practice expects per-line rounding while France permits rounding on the total — but confirm the current requirement for the country you're invoicing from rather than taking a blog's word for it, because these rules get revised. Test it the honest way: build a real multi-item cart, check the invoice, and compare against what your bookkeeper expects.
Shipping is taxable — and PrestaShop won't remind you
Each carrier carries its own tax rules group, set in Shipping → Carriers on the carrier's edit screen. The factory default on a new carrier is often No tax. Shipping is VAT-able in most EU countries, so a "No tax" carrier means you're under-collecting on every order's delivery charge. Configure each carrier's tax according to your local VAT rules — shipping VAT treatment can depend on the jurisdiction and on mixed-rate carts — and test mixed-rate carts with your accountant rather than assuming one main product rate applies to delivery.
Gift wrapping and ecotax — the two extras people forget
Gift wrapping has its own tax rules group under Shop Parameters → Order Settings (the gift-wrapping section). Leave it untaxed and you've got the same under-collection problem on a smaller line. If you operate in a country with an ecotax (France's eco-contribution, for instance), enable and configure the ecotax under International → Taxes (the tax settings), then set the ecotax fields per product where applicable — PrestaShop then handles it as a separate taxed component on the invoice.
B2C vs B2B: where the rate actually changes
The destination rate covers ordinary consumer sales. Two cases bend it, and each is deep enough to live in its own guide rather than be crammed in here.
- Intra-community B2B (reverse charge). A valid VAT number from a business in another EU country flips the order to 0% VAT, with the buyer accounting for it at home — but domestic B2B (a German firm buying from a German store) still pays full VAT. PrestaShop drives this through customer groups and VAT-number validation; the full setup, the VIES validation, and the invoice wording live in B2B e-commerce with PrestaShop.
- Whether prices show net or gross is a legal display rule, not a tax-calculation one, and it varies by market and customer type. We keep that entirely in price display rules in Europe so the two concerns don't get tangled.
For stores that lean B2B-heavy, the part PrestaShop's stock customer-group system handles least gracefully is reliable VAT-number validation against VIES — including VIES being down or returning partial matches. Our mpreuvatchecker module takes that workflow end to end: it validates at registration and checkout, applies the exemption only for genuine cross-border B2B, and degrades sanely when the VIES service is unavailable, so a customer with a valid number isn't blocked by a government API outage. The benefit isn't "more validation" — it's not having to manually fix orders that the default module exempted (or failed to exempt) on a bad VIES day.
Multistore: shared rates, separate defaults
If you run several shops under one PrestaShop install (a common pattern for per-country storefronts), the tax objects can be shared while the defaults stay shop-specific. The practical layout:
- Share the Taxes and Tax Rules Groups across all shops — you don't want "DE Standard 19%" defined three times and drifting out of sync. Define once at the All-Shops level.
- Set the default country per shop (PS_COUNTRY_DEFAULT is shop-context-aware, so each storefront can carry its own home country) and assign each shop's products to the right group in that shop's context. A German storefront sets Germany as the home country; a French storefront does the same with France.
- Re-test rounding per shop if currencies differ — tax rounding interacts with currency conversion, so a price that's clean in euros can land a cent off in another currency. Verify against a real cart in each shop's currency.
The pre-launch tax checklist
Before you trust the configuration with real orders, walk this list — it's the set of things that fail silently:
- Every shippable country has a Tax Rule in every group you use. Missing country = 0% charged, VAT still owed. Open each group and count.
- Your home country is in the group — the easiest one to forget because you "obviously" charge domestic VAT.
- Every product carries the right tax rules group — new and imported products can default to No tax or an unintended group depending on version and import data, so each must be set (or verified) rather than assumed.
- Carriers are not on "No tax" unless you genuinely don't tax shipping.
- Gift wrapping and ecotax are configured if you offer them.
- Rounding mode matches what your invoicing jurisdiction requires — tested on a multi-item cart, not assumed.
- Place real test orders from three or four different EU countries (use a test address per country) and read the actual invoice totals. This catches more problems than any amount of staring at the config screens.
Where tax configuration ends and other guides begin
Getting the rates onto orders is this article's job. Three adjacent things people often conflate with it have their own homes, so you don't get half-answers here:
- The legal VAT framework — OSS, IOSS, the €10,000 threshold, digital-goods place-of-supply, the location-evidence you must retain — is in VAT in the EU: OSS, IOSS and what your store must handle.
- Invoices — making the PDF show net, tax, gross and the right legal mentions per country — is covered in invoice customization in PrestaShop.
- The wider compliance picture your tax setup sits inside — consumer law, terms, returns — starts at e-commerce law in the EU.
PrestaShop gives you a genuinely capable tax engine — three clean layers, destination-aware calculation, per-carrier and per-extra control, multistore-ready defaults. What it won't do is tell you the correct configuration or warn you when a country is missing; that judgment is yours. Set it up deliberately, verify it with real cross-border test orders, and review your rates each quarter as temporary reductions expire. Do that, and tax becomes what it should be: a setting you configured once and never think about again — right up until the audit you pass without breaking a sweat.
Comments
No comments yet. Be the first!
Be the first to ask a question or share useful feedback.
Leave a comment
Share a question, an installation detail, or feedback that could help another reader.