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_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
Note 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
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.