WooCommerce European (EU/UK/Norway/Switzerland) VAT Compliance – Frequently Asked Questions

As well as the documentation below, note that if you go to the VAT Compliance control centre in your dashboard (WooCommerce -> VAT Compliance), then all of the plugin’s features and capabilities are collected there in a single handy place, and there is substantial in-line help available with each function. Consequently, if you go through the various things you can find there, you will usually find what you are looking for. The FAQs below do not generally repeat information that is already there.

N.B. The FAQs here are for the Premium version of the plugin, as well as the free. If you are running the free version and the below references a feature you do not have, then that is the likely reason.

WooCommerce EU/UK VAT Compliance – Documentation index

Questions applying to all our commercial WordPress plugins

How long do you provide access to new plugin releases and support for?

All plugin purchases come with included access to support and access to downloads for 12 months. After 12 months, you can renew access if you want to.

If you do not want to renew, then your existing plugin will not be de-installed or de-activated or changed in any other way. Of course, we cannot guarantee what level of compatibility it will have with future releases of WordPress or (if relevant) WooCommerce.

Do you have a trial version of your plugins available / what is your refund policy?

We do not have trial versions of our plugins available, or refund trial purchases. However, we are committed to providing support for any technical issues you have with any of our plugins, and all plugins include 12 months of support. If the plugin does not do what the product description says it does, then you can have a refund (this should be requested within 10 days of purchase), subject to allowing us to investigate the problem.

This policy specifically excludes third-party failures; for example, if a plugin depends upon a third-party service which malfunctions or closes down, you will not be eligible for any refund for the plugin purchase. It also explicitly excludes failed attempts by the customer to implement PHP code customisations to the plugin, and faults in third-party code. Refunds are not offered for “speculative” purchases where the customer is hoping that the software can do something which is not advertised; plugins are priced cheaply and you should check your requirements before purchase. This policy allows us to keep prices down for our customers (i.e. means they don’t subsidise the support and non-refundable-to-us transaction fees for speculative purchases that get refunded).

For EU customers, your right to a refund of digital goods that you have not requested a download of remain intact. You can request a refund of goods that have not yet been downloaded for up to 14 days after purchase. These requests will be verified using our download logs.

How can I download a PDF invoice/receipt for my purchase?

You can download a PDF invoice/receipt for plugins purchases from your account page, here.

How many licences should I buy?

You will need a separate licence for each individual WordPress installation which you wish to receive plugin updates (i.e. future releases), or to request support for.

A WordPress Network is a single installation of WordPress, so only requires one licence, regardless of how many blogs you have on the network.

What is your support and updates policy?

All customers will have access to future releases of the plugin, and for support to help with trouble-shooting, for 12 months.

Whilst we are happy to give general advice as part of support, support has reasonable limits. For example, hiring a developer (if one is available) to extend or customise the plugin for you, or trouble-shooting problems in other plugins on your site (or other things beyond scope – e.g. problems in your printer, or other third-party products), is not included in the purchase price.

Note that this does not affect your ability to continue using an installed plugin. Your installed plugins will remain installed forever. What is limited to 12 months is access to our future work on the plugin and support.

Can you write some code for me, to customise the plugin?

Plugin purchase prices do not include hand-written code, even if it is only a few lines.

At commodity prices, and including 12 months of updates to new versions (including compatibility with future releases of WordPress and (where relevant) WooCommerce), and personal support, the margins when selling plugins are small. As a result, plugin sellers rely upon selling to many customers – and personal customisations are not economic (even if potentially useful for other customers).

You are, of course, welcome to send in ideas for new features. If you need a developer to customise for you, though, then we suggest Codeable – https://codeable.io – where there is a large marketplace of WordPress and WooCommerce experts offering their services.

Where can I download my plugin purchase?

After purchasing one of our WordPress plugins, you can download from any of three or four places:

  1. The “thank you” page in your web browser, that appears immediately after completing payment.
  2. From your Simba account, here.
  3. Using the link in your order confirmation email.
  4. If you have already installed and begun using the plugin, you can obtain updates (when available) from the “Plugins” page in your WordPress dashboard.

How do I install my plugin?

If you’ve purchased one of our WordPress plugins, then thank you! Here’s how to install…

1. Go to the “Plugins” page in your WordPress dashboard, and press “Add New”

Add a new plugin

2. Press the “Upload Plugin” button

Upload a plugin

3. Press the button to select a zip file. Select the zip file for your plugin. Then press “Install Now”.

Uploading the zip file

4. When the plugin has uploaded, press the “Activate” button.
Activate

N.B. If you have the free version of any of our plugins (e.g. WooCommerce EU VAT Compliance, or Two Factor Authentication), then you should also de-activate and de-install the free version. Your settings will be retained by the paid version. It does not matter whether you de-activate and de-install before, or after, installing the paid version.

When buying a plugin, what is the difference between manual or automatic renewal?

All our plugins come with included access to personal support and updates (new versions of the software) for 12 months (more information). After this 12 months, you can keep on using the software, without any restrictions. However, if you want to renew, you can either do so manually (i.e. come back to the shop and make a fresh purchase) or automatically (i.e. an order will automatically be created and emailed to you, and payment taken if you have a payment method on your account). We offer a discount to those who choose automatic renewal. You can cancel a subscription at any time (yes, even 5 minutes after you purchased it).

Where can I see the plugin changelog?

For a plugin that you have purchased, the changelog is in the file “readme.txt” in the plugin zip.

For our current on-sale version (i.e. the latest version), you can see the changelog by going to the shop, and then going to the product page, and then clicking the link “Plugin changelog” from the left-hand side of the page.

How do I change which site is using a licence?

If you wish to stop using one of your plugin licences on one site, and instead use it on another, then do this:

1. Disconnect the “old” site.

Go to the “Plugins” page in the WordPress dashboard, and find the plugin’s entry. Press the “Disconnect” button.

Disconnecting

2. Connect the “new” site.

Go to the “Plugins” page in the WordPress dashboard on the new site, and connect.

Connecting

I have found a problem in the plugin, or a question not answered here. Where do I get personal support?

Please go here and open a support ticket. (Or, if you forgot your login details for your account with us, then please go here).

Is this plugin still supported and maintained?

Yes. If it ever stops being, then we would withdraw it from sale.


WooCommerce EU/UK VAT Compliance

How can I have multiple countries treated as my base country?

In the VAT plugin settings, there are several settings which make your “base country” differ from other countries. The “base country” is set within your WooCommerce core settings.

Occasionally, a business wants another country to also be subject to the “base country” rules which the VAT compliance extension applies.

This can be done with a few lines of code placed in an mu-plugin, or in your functions.php. The filter to use is wc_eu_vat_get_base_countries. You should use the two-letter country codes used internally by WooCommerce.

add_filter('wc_eu_vat_get_base_countries', 'my_wc_eu_vat_get_base_countries');
function my_wc_eu_vat_get_base_countries($countries) {
// Add Germany to the existing array of countries;
$countries[] = 'DE';
return $countries;
}

How can I provide goods from multiple countries and apply base-country rules?

Some complicated stores sell goods from multiple countries, on a single WooCommerce installation. WooCommerce only has a single “store base country” setting. This is a problem for such stores, because under VAT rules, goods provided within the country of supply (i.e. where the customer’s taxation country is the same as the customer of supply) are treated differently – specifically, VAT is always charged in-country. Our plugin has some “base country” settings to handle in-country supply, but if there is more than one base country, then the default setup cannot handle it.

(N.B. If your question is about something else, then you should stop reading – this FAQ deals with the scenario just-described and no others).

In this situation, it is possible to make the plugin deal with your setup, by doing the following:

  1. Put goods that are under separate tax regimes (which includes being supplied from separate countries) into their own tax class. i.e. Goods supplied from different countries should not be in the same tax class. This is something you ought to be doing anyway. But when you do so, you should include the country code in the tax class name, surrounded by two underscores, e.g. _de_ for Germany, _nl_ for the Netherlands. (Whether upper-case or lower-case does not matter). So, an example tax class would be Physical_Goods_de_Class. If you prefer not to do this, then you must instead list all your tax classes (in WooCommerce’s internal text format) in the code that is used below at the last step.
  2. In WooCommerce -> Settings -> Taxes, create a tax class with a name like “Unused Tax Class – Do Not Delete”. You do not need to create a tax table for this tax class; it is unused. Its sole reason for existing is to cause certain code paths to be chosen in order to enable the solution. If you delete it, the solution may stop working, so do not delete it.
  3. In our VAT plugin settings, make sure that any tax classes that you wish to be exempt upon supply of a valid VAT number are selected in the relevant setting for exemptions, but that the unused tax class above is not selected.
  4. In our VAT plugin settings, make sure that users in your base country are allowed to enter a VAT number, and that they are set to be eligible to be VAT exempt.
  5. Finally, add the “must-use plugin” below to your WordPress install. This means that you should create the folder wp-content/mu-plugins if it does not already exist, and must save the code below as a .php file in that folder, e.g. as wp-content/mu-plugins/multiple-vat-base-countries.php . You must edit the line where it says “On this line, list the country codes for which you have places of supply” to list your relevant country codes, or instead edit the list of tax classes shown (either way works):
    <?php
    
    add_filter('wc_vat_woocommerce_product_get_tax_class_zero_rate_class', function($new_class, $original_class, $product, $zero_rate_reason) {
    
      $zero_rate_class = apply_filters('wc_vat_exempt_zero_rate_tax_class', 'zero-rate', $original_class, $product);
    
      // We only want to get involve if a decision as made to zero-rate due to the product being in a specified tax class
      if ($new_class !== $zero_rate_class || $original_class === $zero_rate_class || 'in_partially_exempt_class' !== $zero_rate_reason) return $new_class;
    
      // Define the country from which goods in specific tax classes are being sold, if your class names do not follow the convention in the instructions above
      $base_country_for_tax_class = array(
        'example_class' => 'DE',
        'another_example_class' => 'NL',
       );
    
      // Only get involved if the product tax class is one of those we are interested in, or follows the same patterns (to allow for future changes in tax class names)
      if (in_array($original_class, array_keys($base_country_for_tax_class))) {
         $product_sold_from = $base_country_for_tax_class[$original_class];
      // On the line below, list the country codes for which you have places of supply
      } elseif (preg_match('/_(de|nl|ca)_/i', $original_class, $matches)) {
        $product_sold_from = strtoupper($matches[1]);
      } else {
        return;
      }
    
      $wc = WC();
    
      $wc_session = isset($wc->session) ? $wc->session : null;
    
      $tax_country = $wc_session ? $wc_session->get('vat_country_checkout') : '';
    
      if ('' == $tax_country || '??' == $tax_country || 'none' == $tax_country) $tax_country = $wc->customer->get_billing_country();
    
      if ($product_sold_from !== $tax_country) return $new_class;
    
      // Country is being sold from the base country for this product; reverse the zero-rating
      return $original_class;
    
    }, 10, 5);

    If you have done all that correctly, then you should now find that which country is counted as your “supply” country varies on a line-item-by-line-item basis for goods in different tax classes.

How can I change the position of the VAT number box on the WooCommerce checkout page?

You can do this using the wc_eu_vat_number_position and wc_eu_vat_number_priority filters. You should set the first filter value to be any position which your WooCommerce template supports, using WordPress’s standard filtering mechanism. The second is a priority, for when there are multiple items using the same position. In this context, a “position” means an WordPress action which your template calls.

The default position is woocommerce_checkout_billing (this corresponds to the WordPress action of that name; it is the default because all templates will somewhere call that action) and the default priority is 40. Here is an example of changing the position to woocommerce_checkout_after_customer_details:

add_filter('wc_eu_vat_number_position', function () { return 'woocommerce_checkout_after_customer_details'; });

To know what positions (actions) exist in your template, you need to either read its code (if you know how to do that), or to speak to a competent developer, or the theme author. Unfortunately it is not easy to automatically get such a list, and beyond the scope of the VAT plugin.

Note that not every template position is a technical possibility – you need to keep it within the main body of address selection. This is because of assumptions (which may not stay the same over time) that WooCommerce makes about the internal structure of the checkout page.

Concerning customisation of the above code, if you do not have your own PHP developer working on the project: this FAQ may also be relevant: Can you write some code for me, to customise the plugin?

A customer is not being charged the correct VAT rate – how do I resolve this?

1. Cases in which the problem is to do with VAT exemption or lack of VAT exemption

This means, that you expected the customer to be VAT-exempt – but VAT was charged on the order; or, you expected the customer to not be VAT exempt, but no VAT was charged, and the order details (please look in the WooCommerce order details to confirm that) state that the customer was exempted.

Whether VAT exemption applies depends upon several of your settings, and the customer’s taxable address. It can also depend upon other plugins – for example, there are some “wholesale” plugins that will automatically set all customers with a “business” role to be VAT-exempt. Firstly, you should look for such plugins, de-activate them, and run through the same purchase procedure, and see if the problem still exists or not. Unfortunately, there is no mechanism to indicate automatically which plugin informed WooCommerce that a customer should be VAT-exempt, or not – it’s only possible to record (which the plugin does) the fact itself.

The next thing to do is to work systematically through the order details, together with your settings. Firstly, check the taxable country on the order (in the WooCommerce order details). Note which VAT zone (e.g. EU, UK) this country is in. Check what your WooCommerce base country is. Check the settings in the plugin for VAT exemption, and include in your checks those settings which result in a different result for the base country.

Note also that the delivery method can be involved. For example, for a “local pick-up” delivery method, the taxable country will be the country where the order is collected, not the country where the customer was ordering from, or their billing country.

If comparing your settings with the results does not reveal where the issue lies, then for testing purposes you should temporarily de-activate all other plugins (you may wish to do this on the staging version of your site, or create one with a tool like UpdraftClone), except for WooCommerce, and attempt to reproduce the issue. If the issue no longer exists, then re-enable them all, and then attempt to reproduce.

If this procedure does not reveal the cause of the problems, then please contact support. When you do so, please provide a list of relevant settings (including relevant tax tables), a copy of all the VAT audit information for the affected order, plus the steps to reproduce the problem (e.g. 1) Visit this product page, http://example.com/product/something, and put a quantity of 2 in your cart. (Remember to tell us which product tax class this product is in). 2) Follow the link to the checkout page, and set your billing country as X, and your shipping country as Y, ….. 3) Enter this VAT number, Z, …., etc.) If you do not supply this information then our first response will likely be to request this information from you – the number of combinations of things that can happen (settings, billing country, shipping country, taxation country, business/consumer/etc.) is so high that without it, it is hard to give any useful practical help, so please be as detailed (but relevant) as possible.

2. Other VAT calculation issues (not when the problem is VAT exemption or lack of VAT exemption)

All tax calculations in WooCommerce are carried out by WooCommerce core, according to the tax rate tables you have configured in the WooCommerce settings. They are not altered by this plugin – because it does not need to (WooCommerce core already has complete features in this area). The only way that this plugin gets involved is by setting a flag for an order to be exempted from tax, if a valid VAT number has been entered. Otherwise, all taxes are calculated according to your tax rate tables, which you can find in your dashboard in WooCommerce -> Settings -> Taxes -> (Tax Rate Tables). For official documentation on taxes in WooCommerce, go here. The things you will want to look at most closely are the tax class that your product is in, the tax table for that product class, and the taxation country for your customer. If the order has been placed, then you can look on the WordPress dashboard order screen for the order to see all the details that are relevant (the plugin helps you with this by recording some of those details for audit, including some that are not recorded by default by WooCommerce at the time the order is placed: i.e. WooCommerce makes calculations, but does not record all the details at the time that were used as the inputs for those calculations, but the plugin adds those records to help with post-order investigations). If you are looking at a product page, then you can add this to your wp-config.php file …

define('WC_VAT_DEBUG', true);

… and then view the HTML source of the page in your web-browser (the option to do so is usually in the “Developer” or “Tools” menu of your browser), search in the HTML source for the word “debug”, and then see what country WooCommerce is using for the visitor’s taxation country. Note that if you are using caching/minifying tools on your HTML output, then this comment may have been removed by those tools, so you may need to disable those first to see the relevant HTML comment.

You should make sure that you keep your tax rates up to date; so, you should make sure that you are aware of changes to VAT rates across the EU and/or UK (e.g. by following news on a website like VAT Live). To help you keep your rates up to date, the plugin provides two facilities which you can use:

1) In your dashboard, in WooCommerce -> VAT Compliance -> Readiness Report, the plugin will report on whether it believes your VAT rates are up to date.

2) In WooCommerce -> Settings -> Taxes -> (Tax Rate Tables), there is a button to press that can update your current tax rate table entries to match a full set of current VAT rates (at either standard, or reduced rate).

How can I display a widget allowing a visitor to pre-select their country, when viewing products (and thus set VAT accordingly)?

There is a widget for this; so, look in your dashboard, in Appearance -> Widgets. You can also display it anywhere in page content, using a shortcode, optionally including an option for displaying prices without taxes. The shortcode is euvat_country_selector, and optionally takes parameters:

  • “include_notaxes” which you can set to “true” or “false”.
  • “include_which_countries” which can take the values “all” (default), “shipping” or “selling”, depending upon whether you want to display all countries, or just those that WooCommerce is configured to ship to, or sell to.

I want to make everyone pay the same prices, regardless of VAT

This is not strictly a VAT compliance issue, and so does not come under the remit of this plugin (suggestions that can be found on the Internet that charging different prices in difference countries breaks non-discrimination law have no basis in fact). Nevertheless, WooCommerce has an experimental feature which is not exposed in its settings to enable you to do this. You can activate it from the VAT compliance settings (in the ‘Settings’ tab). Note that the only effect of the setting is to turn on the feature in WooCommerce core; if that feature does not work, we cannot provide further support for it.

Can customers be shown the correct VAT rate as soon as a visitor comes to the site / some prices seem to be wrong?

What is meant here is, is it possible to detect which country a visitor is coming from (using their IP address), and then base the prices that they see upon this, by assuming initially that their IP address country is the same as their taxation country?

The answer to this question is yes: this is now a feature of WooCommerce core which you simply need to turn on – the setting for the default customer address in Settings > General – set it to “Geolocate”. WooCommerce core will then use the visitor’s country for its tax calculations. The visitor can over-ride this in various ways, for example by explicitly choosing a country using a widget or drop-down menu, or choosing their country at the checkout.

Here is a screenshot of the WooCommerce setting in Settings -> General:

Geolocation setting in WooCommerce

Note that once a country has been selected in a widget or drop-down, this is then saved in the visitor’s session (or one may be set from the customer’s saved address if they log in to the site). If you, for example, decide to test your store by visiting it in the same browser using different VPNs to come from different countries, you may not see what you expected because of this. A genuine test needs to start with a new, completely empty browser session (e.g. by closing all windows of the browser, and opening a new ‘private’ or ‘incognito’ window when you re-open it).

This behaviour, of saving a visitor’s previous selection, includes saving that prices should be shown without VAT, if relevant (e.g. if that option was selected from a menu or widget).

If you wish to turn off this auto-detection behaviour, then add this in your wp-config.php file, after the opening <?php line:

define('WC_VAT_NO_COUNTRY_PRESELECT', true);

Investigating problems

Note that the above feature is not compatible with naive page cacheing, i.e. having the same cached version of a page served to all visitors from all countries. Your page cache needs to be country-aware (e.g. WP Optimize Premium, with the appropriate setting turned on).

If you add these two lines (the second being for compatibility with expected future changes) in your wp-config.php file, after the opening <?php line …

define('WC_VAT_DEBUG', true);

… then you can visit a page, use your browser’s “View Source” function to see the HTML of the page, scroll down to near the bottom, and you should be able to see a debugging comment in the HTML to tell you which country was detected (using the standard ISO two-letter country code):

Debugging HTML comment

How do I deal with the EU’s (import) one-stop shop regulations?

This question refers to the EU’s IOSS (import one-stop shop) and OSS (one-stop shop) regulations, in effect from July 2021 onwards.

Scope of this FAQ (please read this first)

Firstly, here are a couple of important and overlapping points to understand:

  • Our software documentation focuses on aspects to do with setting up our software. Software documentation complements, but does not remove the need for, reading tax documentation and understanding your own local tax rules. That is to say, to learn about the EU’s IOSS/OSS schemes, you should read their documentation about them, available here for OSS, and here for IOSS. It is not an aim of this plugin to provide shop-owners with a short-cut to understanding the tax systems that they operate under. You can also use your preferred search engine to easily find various other guides and answers to specific questions about these VAT regimes.

    The EU’s documentation on cross-border selling and thresholds, here, is also relevant.

  • Related to this, we do not provide tax consultancy or accountancy services. If you need help in understanding how these schemes apply to your particular business, then you need to find a tax consultant or accountant to assist you. We provide a specific software tool (plugin) for WooCommerce to allow you to implement the rules that apply to you, but cannot advise you as to which particular rules, tax rates, etc. do apply to your business.

This is to say: by all means, request help from us on how to implement the rules that you understand you need to implement if it is not clear to you in the plugin settings; but if you ask us for help in understanding your legal/taxation obligations, we will reply to advise you to find an accountant/tax advisor. If you need to register for one of the OSS/IOSS schemes, then you will need to do so; the plugin is not an end-to-end service: it will help you to quickly obtain the figures you need to report, but you must still actually submit those reports to the relevant authorities.

Along similar lines, we assume that you are familiar with core WooCommerce tax concepts, such as product tax classes and tax tables. If you are not, then you should use the official WooCommerce taxation documentation, available here. We are not attempting to provide general WooCommerce tutorials or information, since this is available already (and again, you can use your preferred search engine to find many other tutorials and guides if you find anything in the official WooCommerce documentation to be unclear).

Features of the plugin relevant to OSS/IOSS

Depending on what requirements you are obliged to adhere to under these schemes, you may find the following plugin or WooCommerce features relevant:

  1. VAT that varies according to the customer’s location

    If you are selling goods that are subject to VAT that depends upon the customer’s location (i.e. the “place of supply” is that of the customer, not the shop), then these products should go in a separate WooCommerce tax class from other goods that are not subject to these rules. The tax table for that tax class should contain an entry for each destination country. Setting up tax classes and tax tables is covered in the core WooCommerce tax documentation; please see the section above (“Scope of this FAQ (please read this first”) for the link and other relevant information. The plugin adds a convenient button to WooCommerce tax table screens, allowing you to add all EU/UK rates at once (i.e. sparing you from adding them all one row at a time); if you did not need the UK you can then delete that row.
    Add tax rates button Remember also in the plugin settings to indicate which tax classes are subject to these “customer place of supply” rules (in WooCommerce -> VAT Compliance -> Settings -> WooCommerce VAT Settings):

    Selecting tax classes

  2. Quarterly reports of VAT due

    When making your OSS/IOSS reports, you can use the figures in your WP dashboard, in WooCommerce -> VAT Compliance -> VAT Reports. This will show you a table sufficient to allow making of a report. If you have the Premium version, you can also make a CSV download of all relevant orders and manipulate it in your spreadsheet program for more sophisticated analytics.

    Remember also to ensure that any currencies that you must use when making reports are configured in WooCommerce -> VAT Compliance -> Settings -> WooCommerce VAT Reporting Currencies, so that the plugin knows to record the relevant exchange rates (and potentially mention them on PDF invoices).

  3. Monitoring your approach to the EU’s €10,000 cross-border internal sales threshold, and changing tax rates upon hitting it

    If these rules apply to you, then please see this FAQ/article: Please explain the “tax class translations” feature (cross-border threshold selling).

  4. VAT exemptions based on order value to specified destinations

    Some countries (e.g. the EU, UK) have laws under which the buyer is liable to account for VAT if the purchase value exceeds a specified amount. i.e. The order itself should not have VAT added. You can configure this behaviour in WooCommerce -> VAT Compliance -> Settings -> WooCommerce VAT Settings:

    Destination/value settings
    Look also at the setting “Invoice footer text (VAT exempted)” if you must or desire to add particular information to PDF invoices in this situation.

  5. Other settings

    There are many and various other settings which are not unique to the OSS / IOSS schemes (e.g. reverse-charges based upon supply of a valid VAT number). In all circumstances, users of the plugin are recommended to review all their settings in the WooCommerce -> VAT Compliance -> Settings tab (all sections), to make sure that they have configured the plugin correctly, and are aware of how different features work (most settings either contain or are linked to relevant descriptions), and perhaps to learn of VAT-related concepts that they might not have been aware of.

How do I make my quarterly IOSS/OSS submissions? Can the plugin do it?

Firstly, it is important to note that we are software developers, not tax advisors or accountants. You should not treat our attempts to provide assistance as a replacement for formal advice. We have personal experience of the One-Stop Shop systems that began operation in January 2015 (via “MOSS”, the “mini one-stop shop”), and offer some assistance based on what we have learned since then. Our help is also not intended to replace reading the EU’s own guidance on IOSS and OSS.

The plugin cannot make an IOSS / OSS (henceforth just “OSS”) submissions directly, because we do not have any special relationship with any of the EU 27 tax authorities, and we are not aware of any of them that provide access to their OSS systems via automated interfaces. This means that you need to make those submissions yourself, from your web browser. What the plugin does is makes it easy to gather the figures necessary for the submission. (In our use of MOSS, we could generally complete this procedure in about 15 minutes, once every three months, by downloading data from the plugin and uploading it to the website).

If you, as a merchant, are using an OSS scheme, then you obliged to choose one of the EU’s 27 national tax authorities (N.B. this no longer includes the UK, of course), and register directly for the scheme (whether OSS or IOSS) with them. Having done so, each quarter you must then use whatever facility that particular authority is providing for IOSS submissions, which is likely to be a website. If you are not yourselves in the EU, then that is a “non-Union registration”. If you are in the EU, then that is a “Union registration” (and would be made with your own country’s authority).

If you prefer to operate in English, then it is possible you’ll find the Irish revenue’s facility to be convenient. We have not used it ourselves. It is here: https://www.ros.ie/vatoss-web/vatoss.html?execution=e1s1. Malta also has English as a national language, and it’s quite possible that some authorities provide their websites in multiple languages.

No doubt you can find an agent who will do this for you. Experience shows that these aren’t essential, though presumably you may then benefit from their experience. As stated at the beginning, the aim of this FAQ is to informally give you the benefit of our experience.

Please explain the “tax class translations” feature (cross-border threshold selling)

This feature (which exists in release versions 1.22+ of the plugin, from May 2021)  relates to VAT territories (such as the EU) which have cross-border registration thresholds. It was designed particularly with the June 2021- rules in mind. These rules allow sellers of physical goods who have a presence in one EU country (e.g. France) but who sell to other EU countries (e.g. Belgium, Holland) to treat the first €10,000 (total, not per-country) of their cross-border sales as having a place of supply in their own country (rather than in the customer’s). This results in less bureaucracy – it removes the need to account for VAT separately for the other EU countries until that threshold is met.

Before you read any further (this is important!)…

  • You must make sure that you are familiar with all standard WooCommerce tax concepts, as explained in the WooCommerce tax documentation, including product tax classes, tax tables, and taxation based upon customer location.
  • You must understand that we are no accountants or tax lawyers. VAT can get complex. We provide tools, not consultancy. The tools allow you to set up your store according to a great variety of possible configurations; but it is entirely your responsibility to understand what configuration is correct for you and that you comply with all relevant requirements.
  • If you are under this EU regime, then you should familiarise yourself with its basic ideas, by reading the EU’s guidance, available here.

Here’s what you need to know to correctly use this feature…

WooCommerce (as you know, if you’ve not ignored the material above!), places products in tax classes. A tax class is the concept used to group together goods (products) which are subject to the same tax rules.

If you have products which are potentially (if you happen to go over the sales threshold) subject to being taxable in the customer’s country (rather than in your, the supplier’s, country), then you should follow the steps below. Note that the example given here is for the EU July 2021- regime. If you are operating under a different regime, you should adjust the details to fit your case.

  1. Create a WooCommerce tax class / table for these products, and put those products in that tax class. You should do that even if you have not yet reached the threshold, the reason for which will become clearer in subsequent steps. That tax class will have an entry for each separate country, with its own tax rate, because if you meet the threshold, those products are going to be deemed as having been supplied in the buyer’s country (not the store’s country), taxed there, and you will be liable to remit taxes country-by-country (using, if you so choose, the EU’s One Stop Shop system to reduce the bureaucracy; that system is beyond the scope of this article or indeed our support, since it is a tax-paying arrangement between you and the EU).
    Setting up new tax classes is done in your WordPress dashboard in WooCommerce -> Settings -> Tax, in the ‘Additional tax classes’ setting. When you have saved that setting, a new tab will appear within the ‘Tax’ tab that you are on, and in that new tab you can set up the rates. (Please see the WooCommerce tax documentation linked near the top of this article).
    If you have done this correctly, then the tax table will have different rates for each EU country, like so:
    VAT rates varying by country
  2. You should choose the tax class(es) from 1. in our plugin’s setting “Tax classes used for customer place-of-supply goods”, found in WooCommerce -> VAT Compliance -> Settings -> WooCommerce VAT Settings:
    Selecting relevant classes
  3. You should also create a separate tax class and table for the products to control how they will be treated when your total sales are below the threshold (i.e. like in step 1, but this time a table of flat rates, one for each EU country). If done correctly, this will look like this:Rates the same for each country
  4. You may need to repeat the above steps for different types of products that you have – e.g. if you have some products subject to reduced VAT rates. Once you have created all the needed tax classes/tables (and assigned your products to the appropriate tax classes), you are now ready to configure the VAT plugin to dynamically. Go to the plugin’s settings in WooCommerce -> VAT Compliance -> Settings -> WooCommerce VAT settings, and find the setting “Tax class translations”. Press “Create a new translation rule…”. Inspect and edit the rule to fit your situation. Then, go to the bottom and save the settings. Here is an example screenshot:
    Tax class translation ruleNow it is hopefully clear why you assigned your products to the “variable” class, even before hitting the threshold for the year. The above configuration will cause WooCommerce (via the workings of the VAT plugin) to treat the product as actually being in the “fixed” (second-mentioned) class, until the threshold has been hit. The rule becomes active if, and only if, the product being considered is in the “variable” class.
    Don’t forget to save your settings!

Notes

  • The plugin will run its reports to take a total of all sales for the current year (beginning January 1st) twice-daily. i.e. On the day on which you pass the threshold, the adjustment will only be made once this 12-hourly point in time is reached. Our understanding is that this is an acceptable practice (i.e. it doesn’t have to be “at the very instant”), but all users are reminded that we are neither tax consultants nor lawyers. Shop owners can always trigger a full recalculation by clearing all transients (e.g. using this tool).
  • If you start mid-way through the year, and have not previously been using the plugin, then you will need to make your own calculation (e.g. using WooCommerce’s existing report / analytics facilities) of your current cross-border sales, and instead of entering the full year’s value in your settings (e.g. 10,000), first subtract the existing sales that were not counted by the plugin. (e.g. If you have made 2,500 worth of sales already, then 10,000 – 2,500 = 7,500, so enter that figure (without commas)).
  • Your sales to-date for the year is calculated using orders with any states (see WooCommerce documentation, here) except Pending Payment, Failed, Cancelled, Refunded. By default this means that the statuses counted are “Processing”, “Completed” and “On hold”. When shops add new order statuses, these tend to be post-payment statuses, which is why the default is to include other states. A PHP developer can adjust this using the provided filter wc_vat_compliance_report_year_to_date_totals_exclude_statuses.

How can I disable any checkout notice that I do not wish to be displayed?

The easiest way to do this is to add a CSS rule to your site that tells browsers never to display the element.

To do this, first, identify the CSS class of the notice. The easiest way to do this is to right-click on it, and choose your browser’s “Inspect Element” option. This will bring up the browser’s DOM inspector:

DOM inspector

In the above screenshot, the element has a DOM ID of wcvat_notpossible. Therefore, a CSS rule to always hide that element would look like:

#wcvat_notpossible { display: none; }

There are many ways to add a CSS rule to your site; see here for a guide.

When downloading a detailed CSV, I want to calculate another column / filter / sort etc.

Short answer: the best way to do this is to use the facilities for that in your chosen spreadsheet program (LibreOffice, Microsoft Excel, etc.).

Explanation: lots of our customers have opinions on the importance of including other columns (calculated from the existing ones), or filtering them, or sorting them. And of course, they are all correct: if they want this, then it should be done! The thing is, though, that they don’t all agree with each other – each has their own needs for their own situation. However, this does not need to be a problem. The detailed CSV exists precisely because it can be manipulated exactly as you desire. It comes out of the VAT plugin in a raw form; you can then calculate, filter or sort it just as needed for your situation.

When downloading a detailed CSV, how can I add an extra column?

A PHP developer can do this by using the hooks built-in to the plugin. We assume that the desired column has been stored in your database as an ‘order meta’ item. (If it is not, then you will need more complex processing). Below is a code example which takes an order meta item with key “PayPal Transaction Fee” and adds it to a new “PayPal Fee” column in the CSV. A developer can use and customise this example to achieve the desired result. As another example, the exact same code as below but replacing PayPal Transaction Fee with _order_shipping and PayPal Fee with Shipping Amount will add a column for the order shipping amount. A more complicated example that adds new computed columns, removes others, and re-orders them, is available here.

Note: This requires version 1.28.0 or later of the plugin. Earlier versions used a different filter (wc_eu_vat_compliance_report_meta_fields) in the first code fragment which is now deprecated and should no longer be used. If you are updating your code from an earlier version, then please look at the updated example in the first fragment below.

// Make sure that the order meta field 'PayPal Transaction Fee' is fetched from the database when selecting data for the report.
add_filter('wc_eu_vat_compliance_report_extra_meta_fields', 'my_wc_eu_vat_compliance_report_extra_meta_fields', 10, 2);
function my_wc_eu_vat_compliance_report_extra_meta_fields($fields, $print_as_csv) {
if ($print_as_csv) $fields[] = 'PayPal Transaction Fee';
return $fields;
}

// Give the order meta field ‘PayPal Transaction Fee’ the (internal) key ‘pp_fee’
add_filter(‘wc_eu_vat_compliance_get_report_results_store_key’, ‘my_wc_eu_vat_compliance_get_report_results_store_key’, 10, 2);
function my_wc_eu_vat_compliance_get_report_results_store_key($store, $res) {
return (‘PayPal Transaction Fee’ == $res->meta_key) ? ‘pp_fee’ : $store;
}

// Add a column header ‘PayPal Fee’ to the spreadsheet
add_filter(‘wc_eu_vat_compliance_csv_header_columns’, ‘my_wc_eu_vat_compliance_csv_header_columns’);
function my_wc_eu_vat_compliance_csv_header_columns($columns) {
$columns[] = ‘PayPal Fee’;
return $columns;
}

// For the ‘PayPal Fee’ column, insert the value that we fetched earlier (pp_fee)
add_filter(‘wc_eu_vat_compliance_csv_data_entries’, ‘my_wc_eu_vat_compliance_csv_data_entries’, 10, 3);
function my_wc_eu_vat_compliance_csv_data_entries($data, $order_id, $order) {
$data[‘PayPal Fee’] = isset($order[‘pp_fee’]) ? $order[‘pp_fee’] : ”;
return $data;
}

 

I want/need to use currency conversion data from a different date than the order date when making reports

We have been made aware that when physical goods are sold from Northern Ireland to the EU (governed by the special Northern Ireland regulations), then in the resulting OSS report, vendors are expected to use the European Central Bank’s currency conversion rate from the last day of the reporting quarter, and not the conversion rate from the date of the order. (More information available here: https://www.gov.uk/guidance/completing-a-one-stop-shop-vat-return).

This can affect sellers whose shop base address is not Northern Ireland, if, for example, they are based elsewhere but have a warehouse in Northern Ireland.

This is slightly awkward, since of course on the date of the sale itself (unless it happened to be on the very last day of the quarter), that currency conversion rate is not yet known/published, being in the future. This means that the true data for the report due to the order will not be known until the quarter has ended.

If your shop is in this situation, then one way to deal with it is to download the detailed CSV download (which has a line for every order) into your spreadsheet program. This CSV can be fetched from the “Reports” tab of the plugin. Then, find the column for the conversion rate, and replace it with the proper ECB exchange rate. If this issue only applies to some orders and not to others, then you will need to take further steps (i.e. filter down to, and replace only, the affected orders).

You can also use the following code (as a WordPress “mu-plugin”) to automatically apply this conversion to data in the “Reports” tab (including CSV downloads) for any reports from past quarters (i.e. not the current, open quarter). To do so, follow these steps:

  1. Create a directory called “mu-plugins” in your wp-content folder in your WordPress installation. i.e. The name of the folder should be wp-content/mu-plugins
  2. In that folder, create a file whose name is of your choice, but which ends in .php, e.g. wp-content/mu-plugins/change-currency-rate-date.php
  3. In that file, insert the content of the code shown below. If when you reload your site there is a white screen, then you introduced an error, and should remove the file and try again.

Note that it is assumed that in your plugin settings (in the “Settings” tab) you have chosen the European Central Bank to use for your currency conversion rates. N.B. This code fragment requires version 1.27.6 or later of the plugin and will not work in any earlier version.

<?php

// Do not use conversion rates stored with the order at order time
add_filter('wc_vat_compliance_currency_converted_order_data_use_order_saved_data', '__return_false');

// If the order is from a previous quarter, then use the date of the end of the quarter for looking up the desired conversion rate
add_filter('wc_vat_compliance_currency_converted_order_data_use_conversion_time', function($time, $raw, $order_currency, $conversion_rates, $get_items_data_for_order, $refunds_data_for_order, $reporting_currency) {

  if ('EUR' !== $reporting_currency || !isset($raw['date_gmt']) || !preg_match('/^(\d+)-(\d+)-(\d+) /', $raw['date_gmt'], $matches)) return $time;

  $order_year = (int) $matches[1];
  $order_month = (int) $matches[2];

  $end_of_quarter_year = $order_year;
  $end_of_quarter_month = ($order_month-1) + 3 - (($order_month-1) % 3);

  $end_of_quarter_day = cal_days_in_month(CAL_GREGORIAN, $end_of_quarter_month, $end_of_quarter_year);

  $end_of_quarter_epoch_time = mktime(12, 0, 0, $end_of_quarter_month, $end_of_quarter_day, $end_of_quarter_year);

  // If this is still future, then do not filter the value - only filter for past quarters
  if ($end_of_quarter_epoch_time > time()) return $time;

  return $end_of_quarter_epoch_time;

}, 10, 7);

I am creating an order manually in the WooCommerce back-end – how can I make it VAT-exempt?

In general, when manually creating an order in dashboard, you should expect to manually set up the taxes too. The WooCommerce manual order creation page shouldn’t be expected to behave like a customer checkout, since it is not designed for that purpose. If you don’t want taxes, then, don’t press buttons that add taxes. (And if you did, then you can press the buttons to remove them afterwards).

Under the hood, when creating a manual order, when you calculate the taxes down in the product section, WooCommerce doesn’t actually provide any other details to the back-end code other than the product line items. i.e. The VAT number and any/all other billing fields aren’t actually sent to the back-end, and no hooks are provided to do so, so it’s not actually currently technically possible for the back-end to do anything with these details (until WooCommerce change how the admin page works).

Having said that, in response to previous customer requests, there is one exception we have been able to achieve, based upon what is possible. If you: 1) fill the billing address fields from an existing user (i.e. use the facility there to pre-fill the address from a WordPress user’s account details), and 2) if those fields include a VAT number (i.e. already saved on their account), then when you save the order, the first time, using the button for saving the new order in the top right, then the customer’s VAT number will be used to remove any taxes if there were any. So if you do want to automate the process, that is the way to do it (and as explained above, the only way that WooCommerce’s manual order page makes possible to do it).

Is a customer’s VAT number stored in their user profile (usermeta) ?

Yes, it is stored in their profile, and can be edited on their profile page or in their WooCommerce account section. It is stored in the database (usermeta table) using the meta key vat_number.

I want to forbid VAT numbers from specified countries

If you want to not allow valid (according to your configured VAT number validation services) VAT number from certain countries, you can do this using the following code fragment (but adapt it according to the country code that you wish to use; the example below will forbid VAT numbers everywhere except Ireland, IE):

add_filter('wc_eu_vat_check_vat_number_country', 'my_wc_eu_vat_check_vat_number_country', 10, 2);

function my_wc_eu_vat_check_vat_number_country($allowed_country, $country) {
  // If it is not Ireland, then forbid it
  if ('IE' != $country) return false;
  // Otherwise, let the existing value pass through
  return $allowed_country;
}

Note that you will like want to also change the message shown. The default is “You cannot use a VAT number for which the country (country name) is outside of (VAT area name, e.g. the EU).”. The code fragment below changes the message to make it more appropriate for our example above:

add_filter('wc_eu_vat_disallowed_country_message', 'my_wc_eu_vat_disallowed_country_message', 10, 2);
function my_wc_eu_vat_disallowed_country_message($error, $country) {
  return sprintf(__('You cannot use a VAT number for this country (%s) - we only accept them from Ireland.', 'woocommerce-eu-vat-compliance'), $country);
}

How can I compare the customer’s billing address with the address from VIES (or other national VAT service)?

In short, you can’t. Firstly, services like VIES contain the registered business address of the holder of the VAT number; this does not have to match either their trading address or the billing address of the payment they are using at your WooCommerce checkout. In many cases it will be the address of their company’s accountant, which can legitimately be the address of a different business entirely. Secondly, the data is not returned by VIES in any structured form; it is simply returned as one long sequence of text data. That is to say, VIES won’t tell you which part is the street address, which is the town, county/state, etc. Even individual national VAT authorities within the EU do not appear to enforce any consistent standard for which parts of an address they require to be included. Perhaps somebody could create an AI-like tool to generate a statistical probability to say whether any address you obtain at the WooCommerce checkout is truly the same address as what is in VIES; but this would be a large undertaking and it would be impossible in advance to predict how many false positive matches and false negative failures-to-match you would obtain from doing so.
In any case, if your aim is to prevent fraud by requiring an advanced address match, then this is also a hopeless task, since VIES and other VAT databases are public. Anyone who can look up a VAT number can also obtain the registered business address for that VAT number, and supply it. It can never be a demonstration that the person entering details at the checkout had any secret knowledge that only the true business owner would be able to supply.

Customers are not seeing the VAT field at the checkout – why might that be?

Whether customers are shown the VAT field depends upon a number of things, so you should check each of them:

  1. What taxation zone have you configured, and where is the customer’s taxable address?
    If, for example, you have configured the EU as your taxation zone, and the customer is from Denmark, then they won’t see the VAT field because they are not in the EU. So, you will want to check all relevant settings such as the taxation zones and the rules for deciding where your customer’s taxable address is (based on billing address, shipping address, and whether self-certification can be involved; and remember that for the “local pickup” delivery method, the taxable address is the pickup location, not the customer’s location).
  2. Are your base country settings involved?
    If the customer’s taxation country is the store’s “base country”, then settings related to this come into play. (In many tax regimes, customers in the base country should always be charged VAT, so won’t be offered the chance to enter their VAT number unless you specifically turn on the setting to require that their VAT number is collected anyway).
  3. Is the shopping basket/cart taxable?
    If there are no taxable items in the cart, then the customer will not be offered the opportunity to establish that they are tax-exempt. So, check what tax class you have put the product in, and what tax table entries there are for that tax class (in combination with the customer’s taxation country).
  4. Is your theme broken, or another plugin causing an incompatibility?
    For testing purposes, temporarily de-activate all other plugins (except WooCommerce), and switch to a default theme (e.g. TwentyTwenty). Then reload the checkout page. Is it now present? If so, then another component has introduced an error on the checkout page which prevents other components from working; you will need to use a process of elimination (selectively re-activating and de-activating) to identify which component is culpable.

If after this you still cannot find the cause, please raise a support ticket, and tell us what you learned at every stage above, and supply instructions on how to reproduce the problem (i.e. what product to put in the cart; what country to choose for billing/shipping, etc.)

 

I am also using your “WooCommerce Minimum and Maximum Orders” plugin and wish to have different minimum/maximum amounts depending on whether the customer has a valid VAT number or not?

This refers to our “WooCommerce Minimum and Maximum Orders” plugin, found here, and not any other similarly-named plugin. This can be done using a code fragment. You should ask your PHP developer to adapt this code fragment to your particular situation. The example below will change the minimum purchase amount to £145 (assuming your store uses British pounds sterling) if the customer is not VAT exempt, and if the chosen shipping method has a WooCommerce identifier of legacy_local_pickup :

<?php

add_filter('woocommerce_minima_maxima_settings', function($settings, $for_frontend) {
	
	// Only alter the settings when making front-end decisions
	if (!$for_frontend) return $settings;
	
	/**
	 * e.g.
	 * 
	 * Array
	 * (
	 *    [allowallexcluded] => 1
	 *    [count_all_if_any_included] => 1
	 *    [minamount] => Array
	 *        (
	 *            [default] => 15
	 *            [flat_rate__I-2] => 40
	 *            [flat_rate__I-3] => 30
	 *            [flat_rate__I-6] => 15
	 *            [free_shipping] => 15
	 *            [local_pickup__I-5] => 20
	 *            [legacy_international_delivery] => 100
	 *            [legacy_local_pickup] => 15
	 *     )
	 *    ...
	 */
	
	$wc = WC();
	
	$customer = $wc->customer;
	
	if (!is_object($customer)) return $settings;
	
	if (!$customer->is_vat_exempt()) {
		foreach (array_keys($settings['minamount']) as $key) {
			// On the following line, change the expression to match the shipping methods you are targetting. This uses the slugs, not the visible names in the user interface.
			if (!preg_match('/^legacy_local_pickup$/', $key)) continue;
			$settings['minamount'][$key] = 145;
		}
	}
	
	return $settings;
}, 10, 2);