How Taxes Work in WooCommerce
- Defining Prices
- Tax Calculations (simplified)
- Cross-border/country/region taxes
- Showing 0 value taxes
Some confusion is present to the way WooCommerce does its tax calculations. This post should hopefully clear that up.
Prices for products can be defined:
- Including tax
- Excluding tax
Note: shipping prices are always defined excluding tax in the current system, although a change is being considered.
When we say defined including tax, we are referring to the taxes of the store's base country. e.g. A store with base country GB (United Kingdom) would define their prices with their GB rate of 20%.
To work out how much tax is applicable to a given price there is a calculation like as follows.
Tax calculations are performed per line, not per item. For a tax rate of 20%, the following would be used:
For tax exclusive prices
Tax = Line Price * 0.2
For tax inclusive prices
Tax = Line Price - Line Price / 1.2
Note how the tax is not exactly 20% of the line price when prices include tax already. Doing a regular percentage calculation would essentially be taxing the tax already applied :)
Calculating taxes across various countries for tax exclusive prices is simple; you take the tax exclusive price and multiple by the tax rate.
For prices including tax this is slightly more complicated.
Example 1: Let's take an example of selling from GB (with their 20% tax rate) to Germany. The price of the product is 9.99 including tax. GB based sellers do not need to charge tax for physical goods in Germany so:
New price = 9.99 / 1.2 = 8.325
The German would pay 8.33 for the product.
Example 2: Let's take the same above example, but consider a digital good where tax would apply of the rate 19%.
First you would strip the GB tax, then you would need to apply the German tax like so:
New price = ( 9.99 / 1.2 ) * 1.19 = 9.90675
The German would pay 9.91.
A common feature request is to charge the same amount everywhere and absorb the differences in taxes. To enable this feature in 2.5 you would use the code:
add_filter( 'woocommerce_adjust_non_base_location_prices', '__return_false' );
This would result in the following results, based on the previous 2 examples.
Example 1: Selling from GB (with their 20% tax rate) to Germany. The price of the product is 9.99 including tax. GB based sellers do not need to charge tax for physical goods in Germany.
Price = 9.99 (the same)
Tax = 0 (no tax is charged
The German would pay 9.99 for the product, the same as GB people.
Example 2: Let's take the same above example, but consider a digital good where tax would apply of the rate 19%.
Price = 9.99 (the same)
Tax = 9.99 / 1.19 = 8.39 (slightly less than GB)
The German would again pay 9.99.
These are hidden by default. To show empty taxes, use the snippet:
add_filter( 'woocommerce_order_hide_zero_taxes', '__return_false' );
WooCommerce is an open source commerce platform built for WordPress and lovingly crafted by Automattic and the WooCommerce community 💜. Come and work with us!
Contribution
- Set up development environment
- Our Git Flow
- SCSS and JS minification
- Naming conventions
- CSS SASS coding guidelines and naming conventions
- Critical Flows
- API Critical Flows
- String localisation guidelines
- Translating WooCommerce
- Deprecation in core
- Adding Actions and Filters
- Common Issues
- Writing high-quality testing instructions
Release Notes
- Release Testing Instructions
- 3.6.x notes/FAQ
- 2.6.x to 3.0.0 Developer Migration Notes
- Select2 fields not working in 3.0.x
- Thumbnail Image Regeneration in 3.3+
- Customizing image sizes in 3.3+
REST API and CLI
CRUD & Data Descriptions
- Database Description
- CRUD Objects in 3.0
- Order and Order Line Item Data
- Coupon Data
- Customer Data
- Product Data
- Data Stores
Internal APIs
Theming
- Enabling product gallery features (zoom, swipe, lightbox)
- Template File Guidelines for Devs and Theme Authors
Examples / Guides