Tax
Overview
Smartstore abstracts tax calculation into two parts: a provider resolves the tax rate and a calculator applies that rate to prices. Everything is driven by TaxSettings
which determine whether amounts are entered and displayed inclusive or exclusive of tax.
Tax categories
Every product is assigned to a tax category so the system knows which rate to apply. Categories are simple records with a name and display order and can be edited in the admin area under Configuration → Taxes.
Tax providers
The active provider is selected via ITaxService
and returns a TaxRate
for a given TaxRateRequest
. Smartstore ships with a fixed rate provider and a region‑based provider in the Smartstore.Tax module, but you can implement your own by registering an ITaxProvider
.
public class CustomTaxProvider : ITaxProvider
{
public Task<TaxRate> GetTaxRateAsync(TaxRateRequest request)
{
// return 7% for books, otherwise 19%
var rate = request.TaxCategoryId == 5 ? 7m : 19m;
return Task.FromResult(new TaxRate(rate, request.TaxCategoryId));
}
}
Calculating tax
ITaxCalculator
exposes helpers for products, checkout attributes, shipping and payment fees. The calculator looks up the applicable rate, applies rounding and returns a Tax
structure containing both net and gross values.
public async Task<Money> GetGrossPriceAsync(Product product, decimal netPrice)
{
var tax = await _taxCalculator.CalculateProductTaxAsync(product, netPrice, inclusive: true);
return _taxService.ApplyTaxFormat(tax.Price);
}
Display and formatting
To append legal suffixes such as “incl. VAT” use ITaxService.ApplyTaxFormat
and its shipping/payment variants. Suffix visibility and whether prices include tax are governed by TaxSettings.DisplayTaxSuffix
and TaxSettings.PricesIncludeTax
and must be passed to the method ITaxService.ApplyTaxFormat
to take effect.
VAT numbers and exemptions
ITaxService
also validates EU VAT numbers and checks whether a product or customer is tax exempt:
var vat = await _taxService.GetVatNumberStatusAsync("DE123456789");
bool exempt = await _taxService.IsVatExemptAsync(customer);
Tax settings
Injecting TaxSettings
gives access to configuration such as the default tax address, whether shipping or payment fees are taxable and which provider is active.
Last updated
Was this helpful?