Taxation is one of the most debatable problems in e-commerce since the approach is very different depending on the country of business operation.
Firstly taxes can be part of the price (e.g. European VAT system) or can be excluded from price (e.g. USA, Canada).
Furthermore tax rate itself can differ depending on type of product or specific area. For example in Netherlands (as in 2015) the tax is levied on the sale price and the general rate is 21%. A lower rate of 6% applies for certain goods and services, such as food products, books, medicines, art, antiques, entry to museums, zoos, theatres and sports. Therefore a bottle of wine priced at EUR 4.99 has EUR 0.87 tax and net price value EUR 4.12, and a book worth EUR 19.99 has EUR 1.14 tax and net price EUR 18.85 with customer ending up paying EUR 4.99 for wine and EUR 19.99 for book.
To complicate things even further some items may incur combined tax rates. For example various states in USA have state tax and local sales tax thus the overall tax amount for an item is total of state and local tax amounts. For example state of California (as in 2015) has state tax 7.5% and average local tax 0.94% giving a combined rate of 8.44% (This example is simplified as local tax is average but in reality there are several local tax rates depending on the product or service). Therefore a bottle of wine priced at USD 4.99 has USD 0.42 tax and gross price value USD 5.41, and a book worth USD 19.99 has USD 1.69 tax and gross price USD 21.68 with customer ending up paying USD 5.41 for wine and USD 21.68 for book.
The challenge of any e-commerce platform is to provide users with flexible tax framework to accommodate all business users needs regardless of their geo location.
The platform offers autonomous tax framework which allows tax rates data to be managed independently from the rest of the data in the system. The foundation of the taxation management lies with two data objects: Tax and TaxConfig (or tax configuration).
Tax object provides the definition for the tax applicable within certain shop for certain currency at specific tax rate and whether this rate is excluded from or included in price (as in price record maintained in price lists).
Coming back to the Netherlands example there would be two Tax definitions: VAT 21% (included) and VAT(L) 6% (included), whereas the California example would have one Tax definition: Combined 8.44% (excluded).
TaxConfig objects allow to specify location (country and/or state) and/or product for which Tax is applicable. Tax must have at least one TaxConfig to be activated during tax calculation.
Therefore in the Netherlands example a possible configuration might be: VAT Tax with TaxConfig that defines country code as NL and has blank state code and product. VAT(L) Tax would have TaxConfig for each product for which lower tax is applicable where country code is NL and product SKU is defined.
During cart calculation process the platform fetches all combinations of tax configurations applicable for a given item in cart or shipping option depending on billing address location. Sometimes this results in several possible tax configurations, which are resolved in the following order of priority:
|1||Product state specific tax||has country code, state code and SKU filled in|
|2||Product country specific tax||has country code and SKU filled in|
|3||Product specific tax||has SKU filled in|
|4||State specific tax||has country code and state code filled in|
|5||Country specific tax||has country code filled in|
|6||Shop specific tax||has all blank values|
Referring back to the Netherlands example suggested configuration a Book would result in two applicable tax configurations "VAT for NL" (rule 5) and "VAT(L) for NL and Book" (rule 2). Since "VAT(L) for NL and Book" has higher priority rate of 6% is used for the book.
Tax management section offers searching capabilities and tax data management. Each tax definition is associated with shop + currency pair it is applicable for. For shops that use multiple currencies separate tax definitions must be created for each currency.
The other two crucial parameters are tax % which is tax rate value and type which denotes whether tax is inclusive or exclusive of price. Net (included in price) denotes that prices in the price lists are gross prices which already include tax, Gross (added on top of price) denotes that prices in the price list are net prices which require tax to be added to form the final price.
Illustration of how tax setting influence web view can be seen in figure below:
Tax configuration is the linking of tax definition in respect to specific location and/or product. When tax definition is selected the "configs" tab allows to search and manipulate configuration data for given tax.
Each config has three properties: country code, state code and SKU, all of which are optional. Country code and state code must be the same as defined in locations management section to work properly but can be input upfront without locations records existing. For delivery cost taxes specific rules you can use carrier SLA Id as SKU in the tax config entry.
To give a little perspective to the rules of taxation framework we consider the following situation:
- Shop has default VAT rate of 20% for EUR (we will refer to this shop rule as "rule A")
- Shop has lower VAT(L) rate of 6% for EUR on several items. (we will refer to product CB5-571-C4Y3 specific rule as "rule B")
- Shop has a free gift promotion of "Trigger-Z" keyboard on orders over 2500. (to demonstrate tax calculation on zero value products in cart)
These rules and their effect on cart tax calculation can be seen in the figure below.
The tax calculation of cart contents can be manually verified:
|Item / SKU||Price||Total||Tax Rule||Tax Amount|
|CB5-571-C4Y3 / NX-MUNET-002||799.37||799.37||B @ 6%||181.00|
|ReadyNAS 312 / RN31200-EUS100-2X4TB||1542.87||1542.87||A @ 20%||257.15|
|WT465 / 90XB0090-BMU000||730.80||730.80||A @ 20%||121.80|
|Trigger-Z / SGK-6010-GKCM1-DE||0.00||0.00||0.00|
This example provides insight into how multiple tax configurations and tax definitions can be configured in order to provide flexible rules for tax calculation.
It is anticipated that complex tax management will be done via import/export facility automatically.
If however tax framework provided by platform is not flexible enough it is possible to use alternative implementations of TaxResolver service that potentially could use third party systems to calculate tax.
Tax calculations and configuration
The calculations depend on whether inclusive or exclusive taxation is used.
For net tax the price in price lists assumed to be gross (i.e. includes the taxes) and therefore tax is calculated using formula:
TAX = round( GROSS_PRICE / (1 + TAX_RATE) * TAX_RATE )
Example NET calculation
GROSS_PRICE = 100.00 TAX_RATE = 20% TAX = 100.00 / (1 + 0.2) * 0.2 = 16.66666667 ~= 16.67 (rounded to 2 decimal places) NET_PRICE = 100.00 - 16.67 = 83.33
For gross tax the price in price lists assumed to be net (i.e. excludes the taxes) and therefore tax is calculation using formula:
TAX = round( NET_PRICE * TAX_RATE )
Example GROSS calculation
NET_PRICE = 83.33 TAX_RATE = 20% TAX = 83.33 * 0.2 = 16.666 ~= 16.67 (rounded to 2 decimal places) GROSS_PRICE = 83.33 + 16.67 = 100.00
Tax calculation is bound to have rounding errors especially for prices with fractional part.
For example consider UK VAT tax at 20%. If the gross price to pay by the customer is 4.99 then tax is 4.99/1.2*0.2 = 0.831666667 with net price being 4.158333333. Of course these must be rounded before being presented to the customer. However the question is whether to round the tax to 0.83 and have net price as 4.16 in which case the tax is less than 20%, or round up the tax to make sure we are not underpaying it to 0.83 and have net price 4.15?
This may not be much of an issue if you do not display tax information to the customers (e.g. B2C) and let your accounting department sort out the paperwork. However in B2B it is often that the prices are shown with accompanying tax information. This exposes rounding errors to the customers.
In order to minimise exposure of these rounding errors we recommend the following:
|Price displayed||Tax shown||Recommendations||Notes|
|GROSS||Basic EU style B2C|
|NET||Basic US & Canada style B2C|
|GROSS||B2C with tax (e.g. Switzerland)|
|NET||Typical B2B style|
Validating tax calculations and configuration
Price tester is a great tool that will allow validating various scenarios and see how tax calculations are affected.