WooCommerce prices, locations & VAT

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

Enter prices including or excluding VAT

Through

WooCommerce » Settings » Tax » Tax options

you can set whether prices are entered including or excluding VAT.

All WooCommerce tax settings

Which rate is applied?

When you enter prices including VAT, it is assumed that this is your local VAT rate; the VAT rate associated with the store address
Product fields Tax status and Tax rate are the additional fields to determine the exact tax rate

See → WooCommerce prices entered including VAT for details

Keep having pretty prices?

The reason why I was interested in the possibility of entering prices including VAT: I would like to have pretty prices (e.g. 9.95 instead of 8.84), regardless of the VAT rate. I hoped that if you enter prices including VAT, you will always get pretty prices.

Unfortunately that is not the case: Customers in areas with other VAT rates, see the amounts recalculated. There isn't a standard way to keep prices including VAT the same, regardless the applied VAT rate.

Gemakkelijk wisselen van valuta?

Als ik de valuta van een site aanpas, zou het handig zijn als de prijzen gelijkblijven. Dat bleek in april 2021 het geval te zijn voor een site met prijzen inclusief BTW. Ik denk dat dit echter niet afhankelijk is van de manier waarop de prijzen zijn ingevoerd.

Default Customer Location

wp-admin » WooCommerce » Settings » General » Default customer location

Note: Geolocate really works, but only if you enter a MaxMind License Key at

wp-admin » WooCommerce » Settings » Integration » MaxMind Geolocation

BTW-tarieven

Je kunt in WooCommerce meerdere BTW-tarieven beheren. Voorbeeld WP-CLI (zie ook afbeelding elders in dit artikel):

$ wp --user=4 wc tax list

+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
| id | country | state | postcode | city | rate    | name | priority | compound | shipping | order | class    |
+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
| 1  | NL      |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 0     | standard |
| 2  | DE      |       |          |      | 19.0000 | MwSt | 1        |          | 1        | 1     | standard |
| 3  |         |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 2     | standard |
+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+

Waar de verschillende velden betrekking op hebben:

id

Het veld id is gewoon een primaire sleutel. Het boeit verder niet wat er staat.

Country, state, postcode & city

Via de velden country, state, postcode en city specificeer je op welke geografie het tarief van toepassing is. Amerikaanse verkoopbelasting kan bv. tot op gemeente-niveau afwijken. Waarschijnlijk is dat de reden dat je dit hier zo fijnmazig kunt instellen.

Rate

rate betreft gewoon het BTW-percentage. Als ik dit via de WP-CLI invoer, voegt WooCommerce zelf de nullen toe. Voorbeeld:

$ wp --user=4 wc tax create --country="BE" --rate=21% --name="BTW"
$ wp --user=4 wc tax list

+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
| id | country | state | postcode | city | rate    | name | priority | compound | shipping | order | class    |
+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
| 1  | NL      |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 0     | standard |
| 5  | BE      |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 0     | standard |
| 2  | DE      |       |          |      | 19.0000 | MwSt | 1        |          | 1        | 1     | standard |
| 3  |         |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 2     | standard |
+----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+

Name

name is de naam die verschijnt in de checkout-procedure:

Waarschijnlijk kan dit prima de land-specifieke benaming zijn voor BTW (als die er is)

Waarschijnlijk kan dit prima in de taal van de site. Voorbeeld van vier sites gericht op België:

  • Vlaamse site: BTW
  • Waalse site: TVA
  • Duitstalige site: MWSt
  • Engelse site: VAT: Ik ben niet bekend met een specifiekere Engelstalige benaming voor BTW in België.

Ik denk niet dat het nodig is om aan tegen dat dit het BTW-tarief van een bepaald land betreft. Als bezoekers het per se op dit moment willen weten, kunnen ze dat zelf wel afleiden aan de hand van het sommetje + uitleg ergens op een algemene pagina over hoe BTW berekend wordt.

Priority

  • Gelden er meerdere BTW-tarieven tegelijkertijd voor een bepaalde geografie? Geef ze dan verschillende prioriteit, zodat WooCommerce snapt in welke volgorde deze regels toegepast moeten worden
  • Andersom geformuleerd: Er wordt maar één regel per prioriteit toegepast. Voorbeeld: Een klant in NL krijgt het tarief voor country=NL en niet ook nog eens de algemene regel zonder geographische specificatie
  • Wat dit veld niet is: De volgorde waarin tarieven worden getoond aan bezoekers, want ze worden nergens getoond.

Compound

compound geeft aan of regels bovenop andere regels toegepast moeten worden. Ik snap niet hoe dat werkt in relatie tot priority. Tot op heden nog niet nodig gehad.

Standaardwaarde: false.

Shipping

shipping geeft aan of dit tarief ook van toepassing is op bezorgkosten. Volgens Nederlandse BTW-regels is dat zeker het geval: Het tarief van de goederen bepaald het tarief van de bezorgkosten. Vooralsnog neem ik aan dat hetzelfde geldt voor de andere EU-landen.

Standaardwaarde: true.

Order

Het veld order komt alleen voor via WP-CLI en niet via de interface. De reden blijkt practisch te zijn: Hiermee kun tarieven sorteren:

$ wp man wc tax list

NAME

  wp wc tax list

DESCRIPTION

  List all items.

SYNOPSIS

  wp wc tax list [--context=<context>] [--page=<page>] [--per_page=<per_page>] [--offset=<offset>] [--order=<order>]
  [--orderby=<orderby>] [--class=<class>] [--fields=<fields>] [--field=<field>] [--format=<format>]

OPTIONS

  [--context=<context>]
    Scope under which the request is made; determines fields present in response.

  [--page=<page>]
    Current page of the collection.

  [--per_page=<per_page>]
    Maximum number of items to be returned in result set.

  [--offset=<offset>]
    Offset the result set by a specific number of items.

  [--order=<order>]
    Order sort attribute ascending or descending.

  [--orderby=<orderby>]
    Sort collection by object attribute.

  ...

BTW-tarieven & landen - Situatie tot 1 juli 2021

Totaan de zogenaamde drempelomzet moet je het BTW-tarief aanhouden van het land van vestiging van de site. Boven dat bedrag het BTW-tarief van het land (of landen) waar je de omzetdrempel hebt gepasseerd. Dan moet je ook apart BTW-aangifte doen in die landen. Vanaf 1 juli 2021 verandert dat: Dan kun je er voor kiezen om één gespecificeerde BTW-aangifte in Nederland te doen. De Belastingdienst sluist die gelden vervolgens door naar de verschilende landen.

Casus: Aparte BTW voor Duitsland

Dit betreft een webshop waar voor Duitsland de omzetdrempel van € 100.000 is gepasseerd. Leveringen naar Duitsland worden dus belast met het Duitse BTW-tarief van 19%. Voor overige landen is de omzetdrempel nog niet bereikt.

Belasting is gebaseerd op het Customer shipping address. Niet het factuurbedrag. Het gaat er immers om, waar die goederen daadwerkelijk heen gaan (anders zouden bv. Britten de gevolgen van Brexit moeiteloos kunnen omzeilen door een factuuradres binnen de EU te gebruiken)
Apart tarief voor Duitsland + Nederlands BTW-tarief voor de rest van de wereld (inclusief Nederland)
Testproduct. Ik weet niet hoe het BTW-tarief is bepaald. Misschien is dit gewoon de prijs inclusief BTW zoals ingevoerd. Of hanteert WooCommerce de meest 'algemene' regel. Of de regel die van toepassing is op het land van de site
Verzendadres in Nederland: Ordertotalen zien eruit zoals verwacht
Verzendadres in Duitsland: Ordertotalen worden gelijk aangepast aan het Duitse BTW-tarief. Heel goed! Klein nadeel: Het totaalbedrag blijft niet € 9,95. Dus ook al voer je prijzen inclusief BTW in, deze worden toch aangepast als je van tarief wisselt
Home page: Nu ik een afleveradres in Duitsland heb gebruikt, worden de prijzen voortaan inclusief Duits BTW-tarief getoond. Jammer (want geen mooie getallen), maar niet onoverkomelijk

Default Customer Location & mooie getallen

Er zijn verschillende manieren om de default customer location te bepalen, maar er is geen manier om gewoon expliciet het land te selecteren waarop een site gericht is. Da's problematisch: Nu wordt in de praktijk steeds Nederland gekozen, omdat de site daar gevestigd is (en daar valt niet aan te tornen). Nadelen:

  • Bij de checkout moet de bezoeker onder land Nederland vervangen voor zijn/haar eigen land - Beetje suf voor een site die in het Frans is, en op Frankrijk is gericht
  • De prijzen veranderen. In het geval van NL → FR niet al te veel, want 21% BTW → 20% BTW.

Overigens: Het Nederlandse tarief van 21% is vermoedelijk het meestvoorkomende tarief. Dus de prijzen zullen voor de meeste landen niet al te heftig veranderen nadat het duidelijk is in welk land een klant gevestigd is.

Voordeel van dit alles: Je hebt mooie getallen, totdat het moment dat een klant gaat afrekenen.

Casus: BTW-configuratie voor een grote internationale site (vanaf 1 juli 2021)

Deze casus betreft een klant met een aantal webwinkels, waarbij de BTW-drempel gehaald wordt. Deze situatie zal waarschijnlijk van toepassing zijn voor veel internationaal leverende webwinkels met minimaal € 10.000 omzet per jaar.

Uitgangspunten

  • Het drempelbedrag van € 10.000 wordt gehaald. Er wordt voor uitvoer naar elk EU-land apart BTW geheven. De aangifte geschiedt via het OSS (One Stop System) van de Belastingdienst
  • Voor klanten in alle EU-landen moet het 'gewone' (hoge) BTW-tarief worden gehanteerd dat geldt voor het betreffende land
  • Het land van een klant wordt vastgesteld ahv. het bezorgadres
  • Het betreft momenteel vijf webwinkels. Elke webwinkel is voor een bepaald land bedoeld. Desalniettemin mag de hele wereld kopen bij alle vijf deze webwinkels
  • De webwinkels zijn gevestigd in Nederland (WooCommerce » Settings » General)
  • Idealiter heeft elke shop als standaard-tarief het BTW-tarief van het land waarop het primair gericht is (het is de vraag of dit lukt)
  • Bij voorkeur voeren alle webshops 'mooie' prijzen, zoals € 9,95 ipv. € 8,84. Op het moment dat het BTW-tarief voor een bepaalde transactie verandert (omdat blijkt dat de klant ergens anders woont dan in het land waarvoor de betreffende webwinkel is bedoeld), zou bij voorkeur het 'mooie' bedrag gehandhaafd blijven, en het omzetbedrag aangepast worden aan het BTW-tarief en het beoogde verkoopbedrag - Waarschijnlijk is dit echter te ambitieus, tenzij je in een webshop per land aparte prijzen zou gaan bijhouden - Dat is te veel werkand.
  • Als blijkt dat een klant (particulier of zakelijk) zich buiten de EU bevindt, dan geldt het 0-tarief.

Script

Met dit script worden voor een handjevol sites alle BTW-klasses & -tarieven ingesteld:

#!/bin/bash
#
# Update tax rates
################################################################################
#
#
################################################################################
# Initialisation
################################################################################
#
echo ""
echo ""
echo "########## $0 - Start ##########"
echo ""


################################################################################
# Define function "set_vat_settings"
################################################################################
#
set_vat_settings()
{
	echo "Function set_vat_settings"
        echo "CWD: $pwd"
	echo "vat_name: $vat_name"


	# Overview of current VAT settings
	########################################
	#
	wp --user=4 wc tax list
	#
	# +----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
	# | id | country | state | postcode | city | rate    | name | priority | compound | shipping | order | class    |
	# +----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+
	# | 1  | NL      |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 0     | standard |
	# | 2  | DE      |       |          |      | 19.0000 | MwSt | 1        |          | 1        | 1     | standard |
	# | 3  |         |       |          |      | 21.0000 | BTW  | 1        |          | 1        | 2     | standard |
	# +----+---------+-------+----------+------+---------+------+----------+----------+----------+-------+----------+


	# Overview of current tax rates
	########################################
	#
	wp --user=4 wc tax_class list
	#
	# +--------------------+--------------------+
	# | slug               | name               |
	# +--------------------+--------------------+
	# | standard           | Standard rate      |
	# | gereduceerd-tarief | Gereduceerd tarief |
	# | nultarief          | Nultarief          |
	# | reduced-rate       | Reduced rate       |
	# | zero-rate          | Zero rate          |
	# +--------------------+--------------------+


	# Delete redundant tax classes
	########################################
	#
	# * Stick to EN names
	# * Keep the reduced-rate, just to be reminded that it exists
	#
	wp --user=4 wc tax_class delete gereduceerd-tarief --force=true
	wp --user=4 wc tax_class delete nultarief --force=true


	# Delete all existing rules
	########################################
	#
	wp --user=4 wc tax list --field=id | xargs -n1 wp --user=4 wc tax delete --force=true 


	# Create EU country tax rules
	########################################
	#
	wp --user=4 wc tax create --country="AT" --rate=20% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="BE" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="BG" --rate=20% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="CY" --rate=19% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="CZ" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="DE" --rate=19% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="DK" --rate=25% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="EE" --rate=20% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="EL" --rate=24% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="ES" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="FI" --rate=24% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="FR" --rate=20% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="HR" --rate=25% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="HU" --rate=27% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="IE" --rate=23% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="IT" --rate=22% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="LT" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="LU" --rate=17% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="LV" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="MT" --rate=18% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="NL" --rate=21% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="PL" --rate=23% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="PT" --rate=23% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="RO" --rate=19% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="SE" --rate=25% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="SI" --rate=22% --name=$vat_name --class="standard"
	wp --user=4 wc tax create --country="SK" --rate=20% --name=$vat_name --class="standard"


	# Create non-EU zero rate
	# ######################################
	#
	wp --user=4 wc tax create --rate=0% --name=$vat_name --class="zero-rate"
	

	# Show the results
	# ######################################
	#
	wp --user=4 wc tax list;
}


################################################################################
# Main
################################################################################
#
cd /var/www/example.com
vat_name="VAT"
set_vat_settings

cd /var/www/voorbeeld.nl
vat_name="BTW"
set_vat_settings

cd /var/www/voorbeeld.be
vat_name="BTW"
set_vat_settings

cd /var/www/example.fr
vat_name="TVA"
set_vat_settings

cd /var/www/example.be
vat_name="TVA"
set_vat_settings


################################################################################
# Finish
################################################################################
#
echo ""
echo "########## $0 - Finish ##########"
echo ""
echo ""

Testproduct inclusief BTW

Prijzen worden inclusief BTW ingevoerd. De shop is gevestigd in Nederland. Ik voer daarom deze prijs in van € 121

Verkoop binnen Nederland

Op het moment dat een bezoeker tijdens de afrekenprocedure zijn of haar land selecteert, vindt de definitieve BTW-berekening plaats. In dit geval verandert er dus niets

Verkoop aan een klant in Hongarije

Nu blijkt deze klant in Hongarije te wonen (met 27% het hoogste BTW-tarief van de EU). Wat er verandert:
  • De omzet blijft € 100,--, maar het BTW-bedrag verandert van € 21,-- naar € 27,--
  • Alle prijzen op de site worden nu getoond conform het Hongaarse BTW-tarief. Eventuele mooie prijzen zoals € 9,95, worden nu verminkt. Aan de andere kant: De klant heeft de bestelling al bijna afgerond, dus het is geen ramp. Plus dat deze site niet op Hongarije is gericht, maar op Engelstalige bezoekers in Nederland

Verkoop aan een klant in het VK

Nu blijkt deze klant in het Verenigd Koninkrijk te wonen te wonen (dus buiten de EU). Wat er verandert:
  • De omzet blijft € 100,-- en het BTW-bedrag wordt € 0,--
  • Alle prijzen op de site worden opnieuw aangepast aan de BTW-situatie van de klant

Webwinkel gevestigd in Luxemburg

Wat gebeurt er als ik nu via WooCommerce » Settings aangeef dat deze webwinkel in Luxemburg is gevestigd (met 17% het laagste BTW-tarief van de EU)?:

Via een nieuwe gast-sessie bezoek ik de site. Het testproduct kost nog steeds € 121 (logisch)
Het default-land is Luxemburg, en daarom is het verkoopbedrag precies € 121
Het bezorgland is gewijzigd in Nederland. Nu wordt de verkoopprijs (121/117)*121 = € 125,14

Conclusies

Het werkt allemaal prima.

Alternatieve aanpak

Het werkt allemaal prima. Wil je het echter tot op het bot optimaliseren:

  1. Zorg ervoor dat het land waarop een site is gericht, expliciet als default customer location wordt gekozen - Dat zal vast niet al te moeilijk zijn
  2. Stel de prijzen opnieuw vast, zodat ze allemaal 'mooi uitkomen' voor de default customer location - Het maakt waarschijnlijk niet uit of prijzen in- of exclusief BTW worden ingevoerd.

Alternatieve alternatieve aanpak

Wil je per se dat je voor alle landen mooie getallen krijgt? Dan ervoor zorgen dat je prijzen per land apart kunt specificeren - Overkill, maar ongetwijfeld kan het.

Case: Default customer location changed? - 2022.10

I thought I had it all worked out:

  • wp_admin » WooCommerce » Settings » General » Store address: This is a location within The Netherlands
  • Prices are entered including VAT. This means including Dutch 21% VAT, as this is the applicable rate
  • A common price was 11,95
  • Nevertheless, in a guest sesstion, I get prices like 12,15.

Conclusion: For once, geotargeting for Default Customer Location is functioning, and I get prices according to Polish VAT, as I'm located in Poland. Checking these prices confirms this:

Pn=((1+Rn)/(1+Ro))*Po

* Pn: Price new
* Rn: New rate: 23%
* Ro: Old rate: 21%
* Po: Price old: 11,95

Pn=(1,23/1,21)*11,95 = 12,15

Case: Still confusing, but as intended - 2023.06

The problem?

Message from a shop manager:

"Are these prices correct? At example.uk (left), prices are considerably higher than at example.nl (right)

Additional information

  • Note that at example.uk (left), the shop manager is not logged in, while at example.nl (right), he is logged in
  • When logged in, a shop manager sees the prices, as how they were originally entered. I think that's with Dutch VAT. You can tell that this is probably the case, for the price at example.nl, nicely ends in ,95, as intended to be displayed to visitors (who are not logged in, plus the site is aimed at Dutch customers)
  • When nog logged in (like at example.uk (left), prices are probably displayed as they are in the target market, including VAT. In this case, that's the UK and since delivery is from The Netherlands, this price is actually with 0% VAT
  • If I remember correctly, the nominal prices were kept the same (to make up for higher delivery costs). E.g., a product at example.nl might cost € 11.95 (including Dutch VAT). This same product at example.uk, is supposed to cost £ 11.95 (including British VAT)
  • Once an address is entered at the checkout page of any of these sites, the prices are updated to the prices for that specific market.

Test

At example.uk:

  • Start a Gues session in Google Chrome
  • Put a product in the basket
  • Go to checkout. Fill in some address information, including country (maybe this is all you )
  • Check if the price is correct →

Conclusion

Once United Kingdom was selected for delivery, the price as updated - As they should be for visitors from the UK
The prices on the home page were also updated accordingly

As a final check: Can we verify how the price of £ 70.12 is derived from € 57.95?

It's probably just 57.95 + 21% = 70.1195 ⇒ 70.12 - Indeed.

See also

Bronnen