Many countries have what is referred to as a value-added tax (VAT). When a country uses VAT, tax is included in the price of each item. This means that no additional tax needs to be applied during checkout. However, most tax jurisdictions still require stores to show the amount of VAT that the customer paid.
In the admin, the Settings -> Taxes -> Tax Rates page allows administrators to create any tax rate. They can create VAT-style taxes by using the "Included in price" checkbox.
Solidus's solidus_frontend
gem lists all of the VAT and other price
adjustments below the item total on the checkout summary page.
When you set up products in Solidus, you can set the price to the exactly what you want the customer to pay. Then, you can use your VAT-style tax rates to allocate a percentage of the gross price to taxes.
consumer_price / (1 + tax_rate) = expected_revenue
consumer_price - expected_revenue = vat
Solidus's Spree::Calculator::DefaultTax handles sales tax and VAT. If a tax rate is VAT and should be included in the price, it calculates all of the line items that share that tax rate on the order:
if rate.included_in_price
round_to_two_places(line_items_total - ( line_items_total / (1 + rate.amount) ) )
...
end
Spree::Adjustment
sNote that while VAT does not adjust an order's total, Solidus still creates
Spree::Adjustment
objects to store tax amount. These objects have an
included
value of true
so that the tax is not added to the price.
In the following example, we will still refer to VAT as "adjustments", since that is how Solidus stores the tax amounts.
Our United Kingdom-based company is required to follow these tax regulations:
If a customer orders a single clothing item:
17.99 - (17.99 / (1 + 0.05)) = 0.86
.
£17.99 – 1 x T-shirt
£0.86 – Clothing tax (5%)
£17.99 – TOTAL
If a customer adds a second clothing item to the order:
37.98 - (37.98 / (1 + 0.05)) = 1.81
.
£17.99 – 1 x T-shirt
£19.99 – 1 x T-shirt
£1.81 – Clothing tax (5%)
£37.98 – TOTAL
If a customer adds a consumer electronics product to the order:
37.98 - (37.98
/ (1 + 0.05)) = 1.81
.16.99 - (16.99 / (1 + 0.10)) = 1.54
.We can now show the display the final included VAT in the price when the UK-based customer arrives at the checkout summary page:
£17.99 – 1 x T-shirt
£19.99 – 1 x T-shirt
£16.99 – 1 x Power adapter
£1.81 – Clothing tax (5%)
£1.54 – Consumer electronics tax (10%)
£54.97 – TOTAL
If the provided model in core does not fit your business needs, you can easily customize the VAT generation logic by defining your own VAT generator class. Let's walk into this with an example:
Let's suppose you need to show the same gross price across different countries, no matter what the VAT is but still keeping the VAT tax to be visible in checkout.
You need to customize the logic used by Solidus to generate the price
in countries that use VAT (with a TaxRate that has included_in_price
set to true
).
You can create your own class that implements this logic. It has to be compliant with the interface of the class provided by default in Solidus core, which is Spree::Variant::VatPriceGenerator .
We suggest to inherit from that class and override only the method that you need to be different, for example:
# frozen_string_literal: true
module Spree
class Variant < Spree::Base
class CustomVatPriceGenerator < VatPriceGenerator
def run
# Early return if there is no VAT rates in the current store.
return if !variant.tax_category || variant_vat_rates.empty?
country_isos_requiring_price.each do |country_iso|
# Don't re-create the default price
next if variant.default_price && variant.default_price.country_iso == country_iso
foreign_price = find_or_initialize_price_by(country_iso, variant.default_price.currency)
foreign_price.amount = variant.default_price.amount
end
end
end
end
end
Now that you have created your custom class, you can easily ask Solidus to use it, by setting the following configuration in an initializer:
Spree::Config.variant_vat_prices_generator_class = 'Spree::Variant::CustomVatPriceGenerator'
Solidus is an open source platform supported by the community. We encourage everyone using Solidus to contribute back to the documentation and the code.
If you’re interested in contributing to the docs, get started with the contributing guidelines. If you see something that needs fixing and can’t do it yourself, please send us an email.