Documentation · Cartnorm B2B

EU VAT and VIES

Cartnorm B2B is not on WordPress.org yet. These pages describe version 0.3.0, the version that will be published. Pro features are marked as planned.

This page explains what the plugin does. It is not tax advice. Cartnorm B2B applies the general EU rules for business-to-business sales (Articles 138 and 196 of Directive 2006/112/EC). Special cases such as triangular trade, goods that are not dispatched to another member state, special schemes and national rules are not covered. Please confirm with your tax adviser how these rules apply to your business.

The VAT ID field

The field appears in the classic checkout, the checkout block (added with WooCommerce’s Additional Checkout Fields API, WooCommerce 8.9+), My Account › Account details and the user profile in wp-admin. A number saved in the account is prefilled at checkout.

Settings in WooCommerce › Settings › B2B › VAT ID & display:

SettingOptionsDefault
VAT ID field for retail customersOptional · Required · HiddenOptional
VAT ID field for B2B groupsOptional · RequiredOptional
Country that decides about VATBilling address · Shipping addressBilling address
When VIES says a VAT ID is not validShow an error · Accept the order and charge VATShow an error
Label of the VAT ID fieldyour own text“VAT ID”, translated

How a number is checked

  1. Format check for all 27 member states and Northern Ireland (XI). Greece uses the prefix EL. Spaces, dots and dashes are removed. If the customer leaves out the prefix, the country of the address is used.
  2. Live check in VIES, the official database of the European Commission (https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number). Your own VAT ID is sent as the requester, so VIES returns a consultation number.
  3. Cache: valid results are kept for 7 days, “not valid” results for 1 day, and “VIES unavailable” for 1 hour, so checkout stays fast and the same number is not sent again and again.

Only the country code and number of the VAT ID (and your own VAT ID as requester) are sent to VIES. Nothing else leaves your shop, and the plugin does not contact cartnorm.com.

When VAT is 0%

0% VAT is applied only when all of these are true:

  • the VAT ID is valid in VIES,
  • your shop is in the EU,
  • the customer’s country (billing or shipping address, see the setting) is an EU country other than your shop’s country,
  • the country of the VAT ID matches that address country.

Otherwise VAT is charged as usual, and the reason is stored on the order:

Reason storedMeaning
same_countryThe customer is in your own country. Domestic sales always include VAT.
outside_euThe customer is outside the EU. The VAT ID rules do not apply; your WooCommerce tax settings decide.
country_mismatchThe VAT ID is from another country than the address.
invalid / format_invalidVIES says the number is not valid, or its format is wrong.
unavailableVIES could not be reached (see below).
shop_outside_euYour store address is not in the EU.

Two kinds of 0%, two different notes

The legal reason for 0% is not the same for goods and services, and the invoice must say which one applies:

What is soldLegal basisNote stored on the order (English)
Goods (physical products)Tax-exempt intra-Community supply, Art. 138 Directive 2006/112/ECTax-exempt intra-Community supply (Art. 138 Directive 2006/112/EC)
Services and virtual productsReverse charge, Art. 196 Directive 2006/112/ECReverse charge: VAT to be paid by the recipient (Art. 196 Directive 2006/112/EC)
Both in one orderBothBoth notes

By default virtual products count as services, everything else as goods. Use the filter cartnorm_b2b_is_service if that is not right for your products.

Both notes are built in for all 24 official EU languages, so they do not depend on installed translations. Examples:

  • German: “Steuerfreie innergemeinschaftliche Lieferung (Art. 138 MwStSystRL)” and “Steuerschuldnerschaft des Leistungsempfängers (Reverse Charge, Art. 196 MwStSystRL)”
  • Polish: “Wewnątrzwspólnotowa dostawa towarów (art. 138 dyrektywy 2006/112/WE)” and “Odwrotne obciążenie (art. 196 dyrektywy 2006/112/WE)”
  • French: “Exonération de TVA, article 138 de la directive 2006/112/CE” and “Autoliquidation : TVA due par le preneur (article 196 de la directive 2006/112/CE)”

The note is stored in the language of the order: from WPML or Polylang, otherwise the language of the shop at checkout. It is shown on the thank-you page, in My Account, in the order emails and on the admin order screen. Change the wording with cartnorm_b2b_legal_phrases, cartnorm_b2b_legal_note_goods or cartnorm_b2b_legal_note_services, and the language with cartnorm_b2b_order_language.

Evidence stored on the order

Every order with a VAT ID stores, as order meta, a snapshot of the check:

  • the VAT ID with country prefix and its country,
  • the country that decided about VAT,
  • the VIES result (valid, invalid, unavailable, format_invalid) and the consultation number,
  • the time of the check (UTC),
  • the trader name and address, if VIES returned them (some countries, for example Germany, do not),
  • the decision (standard, intra_community_supply, reverse_charge, mixed, pending_verification) and its reason,
  • the legal notes, the customer group and the language of the notes.

You see this in a box on the order screen, and an order note summarises it. Invoice plugins can read it (meta keys in Developers). The evidence stays when you deactivate or delete the plugin, because it belongs to your order records.

When VIES is down

National VAT databases behind VIES are sometimes unavailable. Cartnorm B2B never turns that into a broken checkout:

  1. The checkout is not blocked: the customer can order as usual.
  2. VAT is charged, the order is accepted and marked pending verification (“VIES unavailable, pending verification” in the VAT box of the order).
  3. The number is checked again automatically in the background (with Action Scheduler) after about 1, 3, 6 and 12 hours, 1 day and 2 days: up to six times over about four days.
  4. If VIES then confirms the number, the evidence is updated and you get an order note, so you can issue a corrected invoice or credit the VAT. If it still cannot be checked, a final note tells you so.

Order totals are never changed automatically. The customer paid with VAT; correcting the invoice is your decision.

A forced re-check that cannot reach VIES never replaces an earlier valid result.

Re-checking customers over time

The free plugin checks a number when it is used (checkout, registration, quote acceptance) and caches valid results for 7 days. Automatic periodic re-checks of approved customers are planned for Cartnorm B2B Pro.

Customers outside the EU

For customers outside the EU (for example in the UK, Switzerland or Norway) the VAT ID logic does not apply, and your WooCommerce tax settings decide whether VAT is charged. Export rules and evidence of export are not handled by the plugin.

Something unclear or missing? Write to [email protected].