Home » Blog » WooCommerce EU VAT: OSS, Rates and Invoices Without the Headache
WooCommerce

WooCommerce EU VAT: OSS, Rates and Invoices Without the Headache

WooCommerce EU VAT setup checklist - destination rates, VIES-checked VAT IDs, sequential invoices and quarterly OSS exports, with shop-base tax flagged as the common mistake

WooCommerce VAT is the scariest screen in the whole store setup – not because the software is hard, but because the rules behind it feel like a trap. Charge the wrong rate to a customer in Austria and you owe someone money; forget the reverse charge note on a B2B invoice and a client’s accountant in Germany sends the invoice back; miss the EUR 10,000 threshold and you are suddenly filing in a scheme you have never heard of. I have set up or repaired the tax configuration on dozens of EU-facing WooCommerce stores, and the honest news is this: once you understand three concepts – the destination principle, the OSS scheme and the reverse charge – the WooCommerce side is a few hours of careful work, not a permanent source of dread.

One thing before anything else: I am a WordPress developer, not a tax advisor. This guide explains how EU VAT typically works for online stores and how to configure WooCommerce to match it, because that is the part clients ask me to build. Your registrations, your rates and your returns should be confirmed by your accountant or tax advisor before you sell a single item – every store I set up gets its tax configuration signed off by the client’s accountant, and yours should too. What I can promise is that after reading this you will know exactly what to ask them, and exactly which buttons to press afterwards.

Table of contents

EU VAT for stores in plain language

Strip away the jargon and the system for a typical EU-based store selling to consumers works like this. When you sell to customers in your own country, you charge your own country’s VAT and report it in your normal domestic return – nothing new. When you sell to consumers in other EU countries, the destination principle applies: above a threshold, you charge the VAT rate of the customer’s country, not yours. A German store selling to a customer in Ireland charges Irish VAT at 23%, not German VAT at 19%.

The threshold is the famous EUR 10,000 – and it is smaller than most owners think. It covers your combined cross-border B2C sales to all other EU countries per calendar year (goods plus digital services), not EUR 10,000 per country. Below it, a small store may keep charging its home rate on everything. Cross it – and a store doing even modest international business crosses it quickly – and destination rates become mandatory from that point on.

Charging 27 different countries’ VAT used to mean 27 registrations. The One Stop Shop (OSS) exists so it does not: you register once, in your own country, through your national tax portal. Every quarter you file a single OSS return listing how much you sold into each EU country and the VAT you collected at each rate, pay the total to your own tax office, and they distribute it. Your job as a store owner reduces to three things: charge the right rate at checkout, keep records that break sales down by country and rate, and file the quarterly return. WooCommerce can do the first two well if you configure it properly – which is what the rest of this guide is about.

Three more terms you will meet. The reverse charge shifts the VAT obligation to the buyer when you sell cross-border to a VAT-registered business – you charge 0% and they account for it locally. IOSS is the import cousin of OSS for non-EU sellers shipping low-value goods into the EU. And reduced rates are the special lower rates many countries apply to categories like books, food or ebooks – relevant if you sell anything in those categories, ignorable if you sell standard goods.

Decisions to make before you touch a setting

Most VAT messes I untangle started with someone opening the settings screen before answering four questions. Answer them first, with your accountant where noted:

  • Are you over the EUR 10,000 threshold, or will you be? If you are meaningfully selling cross-border, assume yes and register for OSS – the registration is free, the return is quarterly, and being registered before you need it beats scrambling after. Your accountant confirms this.
  • Will prices be entered including or excluding tax? For B2C stores selling across the EU, entering prices including tax is almost always right: the customer in every country sees the same gross price (EUR 49 is EUR 49 in Berlin and Dublin), and your margin absorbs the rate difference. B2B-first stores often prefer net prices. Decide now – changing later means re-entering every price.
  • What do you actually sell, tax-wise? Standard-rated goods only, or also reduced-rate categories (books, food supplements) or digital products? Each distinct treatment becomes a WooCommerce tax class, so list them before you build the tables.
  • Do you sell to businesses in other EU countries? If yes, you need VAT ID validation and reverse charge handling at checkout – a plugin, not a manual process. My WooCommerce B2B guide covers the wider wholesale setup; the VAT-specific part is below.

Write the answers down in one paragraph and get the accountant’s yes in writing. The configuration that follows is mechanical once these are fixed.

Configuring WooCommerce tax settings step by step

WooCommerce ships with a competent tax engine that most owners never configure past the defaults. Here is the order I use on client stores.

1. Enable taxes and set the base behaviour

Under WooCommerce > Settings > General, tick “Enable tax rates and calculations” – the Tax tab appears. On that tab, set “Prices entered with tax” according to your decision above. Then “Calculate tax based on”: for a store past the threshold this should be customer shipping address (destination principle for goods); use billing address if you sell only digital products. Never leave it on “shop base address” for a cross-border store – that is the single most common misconfiguration I find, and it means every foreign customer was charged your home rate.

2. Rounding, display and the price suffix

Enable “Round tax at subtotal level” – it prevents the one-cent discrepancies that make accountants distrust the whole export. Set shop and cart displays consistently: B2C stores show prices including tax everywhere; B2B stores often show excluding with a suffix. The price display suffix (“incl. VAT”) is a small setting that prevents a lot of support email, and in Germany it is effectively expected on every price.

3. Tax classes

WooCommerce gives you Standard, Reduced rate and Zero rate classes, and you can add your own. Create one class per distinct treatment you identified: most stores need only Standard; a store selling ebooks adds a class for them because several countries tax ebooks at a reduced rate; a food or supplement store may need two reduced classes. Every product then gets assigned a class – and every future product needs one too, which is a line worth adding to your product-creation checklist alongside the items in my store launch checklist.

4. Shipping tax

In the EU, shipping generally follows the VAT treatment of the goods being shipped. Set the shipping tax class to “Shipping tax class based on cart items” and WooCommerce handles the common case correctly. Setting shipping to a fixed class – or to no tax at all – is misconfiguration number two on my list, and it quietly understates VAT on every single order.

5. Geolocation and the default customer location

Set the default customer location to “Geolocate” so visitors see plausible tax-inclusive prices before they enter an address. It is cosmetic – the checkout address decides the real rate – but it avoids the jarring price jump between the product page and the cart.

Building the rate tables

The Standard rates screen is a table: country, rate, name, priority, and flags for compound tax and shipping. For an OSS store you need one row per EU country per tax class – 27 rows for standard rates, plus rows in each reduced class for the countries where that class differs. Nobody types these by hand; the screen has CSV import and export, and the workflow that works is: build the table once in a spreadsheet, import it, and keep the CSV in version control or a shared drive as the source of truth.

To give you a feel for the spread (always verify current rates before importing – they do change, a country or two per year):

Country Standard rate Note
Germany 19% 7% reduced covers books, food staples
Austria 20% 10% and 13% reduced bands
France 20% 5.5% on books incl. most ebooks
Ireland 23% 0% on printed books
Luxembourg 17% Lowest standard rate in the EU
Hungary 27% Highest standard rate in the EU

Two practical notes on the table mechanics. First, priorities: if you ever need two rates to apply to the same order (rare in the EU), rows need different priorities; for a normal store, keep every row at priority 1 so exactly one rate matches. Second, the asterisk: a row with country “*” matches everywhere, which is occasionally useful as a catch-all but usually a foot-gun – if a customer country has no explicit row, I would rather see zero tax and catch it in testing than silently charge a wrong catch-all rate.

Where do you get a maintained rate table? Three options in ascending order of cost: build the CSV yourself from the European Commission’s published rates (an hour of work, you own the review job), use the rates bundled with a compliance plugin such as EU VAT Compliance for WooCommerce (it maintains the table for you), or use WooCommerce’s own automated tax service where available. For most owner-managed stores I set up the CSV plus a twice-yearly review reminder; for stores with no one watching, the plugin subscription is cheap insurance.

Then test. Place test orders with shipping addresses in four or five countries – your own, a high-rate country like Hungary, a low-rate one like Luxembourg, and one in each reduced class you use – and check the tax line on each order against a calculator. Fifteen minutes here catches the typo that would otherwise surface in your OSS return.

Five-step EU VAT setup for WooCommerce: register for OSS, set tax settings, import per-country rate tables, add VIES VAT ID checks, place test orders - with key facts like the EUR 10,000 threshold
The setup order that avoids rework – registrations and the pricing decision first, rate tables and validation after.

B2C vs B2B: VAT numbers and the reverse charge

Everything above assumed consumers. Business buyers with a VAT registration change the picture: when you sell cross-border within the EU to a business with a valid VAT ID, you do not charge VAT at all. The invoice shows 0%, carries the buyer’s VAT number and a reverse charge note, and the buyer accounts for the VAT in their own country. Domestic B2B orders are unaffected – a German store still charges German businesses 19%; the reverse charge is a cross-border mechanism only.

The operational question is proof: you can only zero-rate the sale if the VAT ID is valid, and “the customer typed something that looks like a VAT number” is not proof. The EU runs VIES, a validation service that checks a VAT ID against the national registers, and your checkout should query it live. In WooCommerce that means a plugin – the official EU VAT Number extension, the B2B suites, or the EU VAT Compliance plugin all do it. The good ones handle the awkward realities:

  • A VAT ID field at checkout that validates against VIES before the order completes, removes the tax for qualifying cross-border orders, and stores the validation result and timestamp on the order – that stored evidence is what protects you in an audit.
  • VIES downtime handling. The service does go down. Decide the fallback with your accountant: queue the order and validate later, or charge VAT and refund on validation. Never silently zero-rate unvalidated numbers.
  • Domestic exclusion. The plugin must keep charging home VAT when the buyer’s VAT ID is from your own country. I have fixed more than one store that was zero-rating its domestic B2B orders – an expensive bug, because the store still owes that VAT.
  • The invoice wording. A reverse charge invoice needs both VAT numbers and an explicit note – “VAT reverse charged” or a reference to the relevant article of the VAT Directive. The invoice plugin (next section) handles this if the order data is right.

Reporting also differs: reverse charge sales do not go in your OSS return – they are reported separately (recapitulative statement or EC sales listing, depending on your country’s terminology). This is exactly the kind of split your exports need to respect, which is why the reporting section below matters. And if B2B is a serious part of your store – wholesale pricing, quotes, account customers – the VAT part is one chapter of a bigger setup I cover in the B2B and wholesale guide.

Table comparing VAT treatment of B2C and B2B orders in a WooCommerce store: rate charged, VIES validation, invoice wording and reporting route for consumers versus business buyers with a VAT ID
Same store, two treatments – reverse charge applies only cross-border with a validated VAT ID; domestic B2B keeps the home rate.

Invoices that satisfy EU rules

WooCommerce’s order emails are not invoices, and for EU B2B customers – and tax offices – that distinction is real. A compliant EU invoice needs, at minimum: a unique sequential invoice number, the invoice date, your full business name, address and VAT number, the customer’s name and address (plus their VAT number for reverse charge sales), a description of the goods with quantities, the net amount per VAT rate, the VAT rate and VAT amount per rate, the gross total, and where relevant the reverse charge note or an exemption reference. Sequential matters: gaps in the numbering are the first thing an auditor asks about, which is why the invoice number must come from the invoice plugin’s own counter – never reuse WooCommerce order numbers, which develop gaps naturally from cancelled and failed orders.

The plugins I actually deploy:

Plugin Cost Best for Watch out for
WooCommerce PDF Invoices & Packing Slips Free core, paid Pro Most stores – solid numbering, templates, attach to emails Reverse charge note needs the template edited or Pro
Germanized for WooCommerce Free core, paid Pro Stores selling into Germany – invoices plus German legal texts Broad plugin; only worth it if you need the legal side too
YITH PDF Invoice Paid Stores already in the YITH ecosystem Check the sequential counter survives refunds correctly
Accounting SaaS (e.g. invoicing via your accounting tool) Monthly fee Stores whose accountant wants invoices born in the accounting system Needs an order-to-accounting integration (see below)

Whichever you choose, configure it once and then verify three things on real test orders: the number sequence increments with no gaps across a cancelled order, the per-rate VAT breakdown matches the order exactly, and a reverse charge test order produces the 0% invoice with both VAT numbers and the note. Also set the credit note behaviour – refunds should generate a numbered credit note, not a deleted invoice. Invoices contain personal data, so they also fall under your privacy obligations; retention is typically ten years for tax purposes, which your privacy policy should reflect – the practical side of that lives in my GDPR compliance guide.

OSS reporting: getting usable exports out of WooCommerce

Every quarter, the OSS return wants one thing: for each EU country you sold into, the taxable amount and VAT collected, broken down by rate. WooCommerce stores all of that on every order – but its built-in reports will not hand it to you in that shape. You have three routes, and I have built all three for clients:

  • A compliance plugin’s report. EU VAT Compliance for WooCommerce exists largely for this: it records the evidence per order and produces a per-country, per-rate report for the quarter that you can read straight into the OSS portal form. For a store owner doing their own filing, this is the pragmatic choice and the subscription pays for itself the first quarter.
  • A tailored CSV export. A developer (this is a two-to-four-hour job) adds an export that pulls completed orders for the quarter, groups them by shipping country and rate, splits out reverse charge orders and refunds, and emails the accountant a CSV on the first of the month after quarter end. No subscription, exactly the columns your accountant asked for.
  • Push orders into the accounting system. The most robust version: every order flows via API into the accountant’s tool (Xero, Lexware Office, sevDesk and their peers all have APIs), and reporting happens where the accountant lives. This is integration work – the kind I do under WordPress API integration – and it eliminates the quarterly export ritual entirely.

Whatever the route, two details decide whether the numbers survive the accountant’s scrutiny. Refunds must be included as negative amounts in the quarter they happen, not netted invisibly. And the report must exclude what does not belong in OSS: domestic sales (normal return), reverse charge B2B sales (recapitulative statement) and non-EU exports. If your export mixes those in, the totals will never reconcile and every quarter becomes an argument.

Digital products: rates and evidence requirements

Digital products – downloads, courses, SaaS-style memberships – follow the destination principle with no lower bound once you are past the same EUR 10,000 combined threshold, and they bring one extra obligation: evidence of where the customer belongs. Because there is no shipping address for a download, the rules ask you to hold two pieces of non-contradictory evidence of the customer’s location – typically the billing address plus the IP-address country, with the payment provider’s card country as a tie-breaker. (Smaller sellers under an annual cross-border ceiling may need only one piece; ask your accountant which regime applies to you.)

Practically: WooCommerce records the billing address; the geolocation of the IP needs to be captured and stored per order, which the EU VAT Compliance plugin does, storing both pieces against the order so the evidence exists if anyone ever asks. If the two disagree – a German billing address on a French IP – the plugin flags it and you follow your documented tie-break rule rather than improvising per order.

Rates are the other trap: several countries tax ebooks and some other digital publications at reduced rates rather than the standard rate, which is exactly why digital products get their own tax class with their own country table instead of riding along in Standard. If you sell a mix – say, a physical book, an ebook and a course – you may genuinely have three classes, and the per-product class assignment becomes something to check on every new product, not just at setup.

Selling into the EU from outside: IOSS in brief

If your store ships from outside the EU – a UK store post-Brexit, a US or Indian store with EU customers – the scheme that matters is IOSS, the Import One Stop Shop. For consignments up to EUR 150, IOSS lets you charge the destination country’s VAT at checkout, file one monthly return through an EU intermediary, and ship parcels that clear customs without the courier ambushing your customer for VAT plus a handling fee on the doorstep. That doorstep ambush is the alternative, and it is a review-killer – customers do not distinguish “customs charged me” from “this store tricked me”.

The WooCommerce mechanics are familiar: destination-rate tables for EU countries, tax charged at checkout, IOSS number transmitted to the carrier with the shipment data. Above EUR 150 per consignment, IOSS does not apply and the import VAT and duty question lands on the customer or on your carrier arrangement (DDP shipping), which is a shipping-strategy decision more than a store-configuration one. Non-EU sellers should treat this whole area as accountant-first: the registration itself typically runs through an EU-established intermediary, and whether IOSS is worth it depends on your volume and parcel values. The store configuration is the easy half.

Common misconfigurations I get hired to fix

A short tour of the actual tickets, roughly ordered by frequency:

  • Tax calculated on the shop base address. Every EU customer charged the home rate for two years. The fix takes one minute; quantifying the damage for the accountant takes rather longer.
  • Shipping taxed wrongly or not at all. Shipping tax class hard-set to Standard when the cart is reduced-rate, or shipping rows missing the tax flag entirely. Small per order, systematic across every order.
  • The missing-country hole. The rate table was imported before the store started selling to, say, Croatia – no row, so checkout charged 0% and nobody noticed until the export showed a country with revenue and no VAT.
  • Products with no tax class. New products added after launch defaulted to a class nobody configured. This is why “assign tax class” belongs on the product checklist, not in someone’s memory.
  • Domestic B2B zero-rated. The VAT ID plugin removed tax for every validated number, including home-country buyers. The store owes that VAT whether or not it was collected.
  • Prices entered inconsistently. Half the catalogue entered gross, half net, after a mid-life settings change. Every price had to be audited by hand.
  • Rounding mismatches. Tax rounded per line in WooCommerce, per document in the accounting tool – a cent here and there, and an accountant who now checks everything manually. Round at subtotal level and align the invoice plugin with it.
  • Display confusion. Product pages showing net prices to consumers who then meet a bigger number at checkout. Legal problem in some markets, conversion problem in all of them.

Every one of these is invisible on a quick look at the store and obvious in a fifteen-minute test-order session. If you have never placed test orders against a rate calculator, do it this week.

The quarterly routine and when plugins earn their fee

A healthy store runs VAT on a boring calendar. Quarterly, in the first weeks after quarter end: run the OSS export, reconcile its total against the payment provider’s payouts for the quarter (they will not match to the cent because of timing, but they must match in shape), send it to the accountant or file it, and pay. Twice a year: review the rate tables against current published rates and re-import if anything changed. On every new product: assign the tax class. Once a year: place a fresh round of test orders across countries and classes, including one reverse charge order, and check the invoices they generate. Written down like that it is perhaps a day of routine per year plus the filing itself – which is the point. VAT stress comes from not knowing whether the numbers are right; the routine replaces the dread with a checklist.

And the plugin question: a compliance plugin subscription (the EU VAT Compliance plugin, the official VAT Number extension, or a SaaS like Quaderno at the heavier end) earns its fee when it replaces work you would otherwise pay for – maintained rate tables, stored evidence, VIES validation, quarterly reports. For a store under the EUR 10,000 threshold selling standard goods domestically, none of that is needed yet and the free tax engine plus a manual table is enough. For a cross-border store filing OSS every quarter, EUR 50-100 a year of plugin against an hour of an accountant’s billing rate is not a difficult sum. The honest rule: buy tooling for the parts you must repeat every quarter, not for the one-time setup – the setup you do once, properly, and it stays done.

Want your store’s VAT set up properly – once?

I configure EU tax handling on WooCommerce stores as part of my WooCommerce development work: rate tables, B2B validation, compliant invoices and the quarterly export your accountant actually wants – built, test-ordered and documented, with the accountant sign-off loop included. See the portfolio for recent stores, or describe your store and markets and I will reply with a fixed quote within 24 hours.

Frequently asked questions

How does WooCommerce VAT work for EU stores?

WooCommerce applies rates from tax tables you configure: home-country VAT for domestic sales, and – once you pass the EUR 10,000 cross-border threshold – the customer’s country rate for B2C sales into other EU countries, reported through a single quarterly OSS return.

Do I need to register for OSS?

If your combined cross-border B2C sales to other EU countries exceed EUR 10,000 per year, destination rates apply and OSS is the practical way to report them with one registration. Confirm your specific situation with your accountant.

Should prices be entered including or excluding tax?

B2C stores selling across the EU usually enter prices including tax, so every customer sees the same gross price and the margin absorbs rate differences. B2B-focused stores often work in net prices. Decide before entering the catalogue.

How do I handle B2B customers with a VAT number?

Validate the VAT ID against VIES at checkout via a plugin, zero-rate qualifying cross-border orders under the reverse charge, keep charging home VAT domestically, and store the validation evidence on the order.

Does WooCommerce generate legal EU invoices?

Not by default – order emails are not invoices. Add a PDF invoice plugin with sequential numbering, per-rate VAT breakdowns, credit notes for refunds and reverse charge wording for B2B orders.

How do I get OSS reports out of WooCommerce?

Either a compliance plugin’s per-country, per-rate quarterly report, a custom CSV export built to your accountant’s spec, or an API integration that pushes orders into your accounting system continuously.

What changes for digital products?

Destination rates apply with the same combined threshold, some countries tax digital publications at reduced rates, and you must store two pieces of location evidence per order – typically billing address plus IP country.

Written by Vishal Bhisara

Full Stack WordPress Developer & AI Solutions Expert with 12+ years of experience and 500+ projects delivered worldwide. I help businesses and agencies build fast, secure, SEO-ready websites - custom themes, plugins, WooCommerce stores, and AI automation that actually grows revenue. Based in Bhavnagar, India, working with clients across the globe. More about me →

Need Expert WordPress Support?

Reading great content is the first step. Implementing the right strategy is what delivers results. If you need professional help with your WordPress website, WooCommerce store, AI automation, or custom development project, I'm here to help.

Have a Project in Mind? Let's Make It Happen.

Start a Project
Vishal Bhisara Your WordPress & AI partner
Get a Free QuoteGet a Free Quote