# 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`.

```csharp
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.

```csharp
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:

```csharp
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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev.smartstore.com/framework/commerce/tax.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
