Area: Episerver Commerce
Applies to versions: 10 and higher


Recommended reading 

Note: This section explains how to work with tax calculations using the older APIs. Episerver recommends using the abstraction APIs to manage tax calculations, as described in Tax calculator.

Episerver Commerce includes a tax subsystem, incorporated into checkout workflows, that calculates a cart's totals, including discounts, shipping costs, and pricing applicable to a particular customer. The tax subsystem, configurable via Commerce Manager, lets you set rates for different locations and SKU tax category.

Classes in this topic are available in the following namespaces:

  • Mediachase.Commerce.Workflow.Activities.Cart. Contains CalculateTaxActivity.
  • Mediachase.Commerce.Workflow. Contains CartPrepareWorkflow.
  • Mediachase.Commerce.Catalog.Managers. Contains CatalogTaxManager.
  • Mediachase.Commerce.Orders. Contains OrderContext.

Key classes and files

  • CartPrepareWorkflow.xml. Executed after shipping addresses are provided. It includes a cart's tax calculation and other checkout activities.
  • CalculateTaxActivity.cs. Part of the CartPrepareWorkflow workflow, performs a cart's tax calculations.
  • CatalogTaxManager.cs. Provides tax category information for SKUs.
  • OrderContext.cs. Provides the GetTaxes() method to return the tax rate for items based on tax category and jurisdiction.

How it works

During checkout, Microsoft Workflow Foundation workflows calculate the cart total. One workflow, CartPrepare, is run prior to rendering the page where customers confirm their order.

This workflow performs these tasks:

  • Determines whether the item is still available, based on the Active status and the item's start and end dates. If the items is not available, it is removed from the cart and an error message is returned and displayed in the CartView.ascx.
  • Determines whether the cart items are still available based on remaining stock in inventory, reserved inventory stock, and whether backordering is permitted. If not available, the items are removed and an error message is returned.
  • The price for each cart item, based on tiered pricing. If pricing has changed, a message regarding the change is returned, which can be displayed to the user.
  • Calculates the extended price for each cart item, for instance multiplying the price by the quantity purchased.
  • Calculates discounts.
  • Splits line items into their respective shipments, if multiple shipments are created.
  • Adds shipping costs to the cart.
  • Adds applicable taxes to the cart.

The last action, adding applicable taxes, is done inside the CalculateTaxActivity activity.

Tax calculations are performed in the CalculateTaxes method. For each shipment in a cart, applicable taxes are applied to the Orderform of the cart, based on whether the shipping address is in a jurisdiction with taxes and its tax category. You can apply multiple tax rates (for example, a state and city tax).

The CalculateTaxes method ultimately calls the TaxManager.GetTaxes() method, which executes a stored procedure called ecf_GetTaxes. This procedure retrieves the rows of data from the Tax table where shipping address properties (for instance country or state) and tax category match a tax entry's properties and tax category, and where a shipping address property is null in the shipping address or tax rate rows.

Tax rates are based on jurisdiction parameters (which designate a physical region) and SKU tax categories.

The parameters are:

  • Country
  • State
  • ZipPostalCodeStart
  • ZipPostalCodeEnd
  • District
  • County
  • City
  • TaxCategory

The stored procedure only matches tax rates for a shipping address, where the property of the rate matches the properties of the shipping address. Null/empty values do not prevent a match. For example, if a tax rate for the State of New Jersey had the following settings:

  • Country = US
  • State = NJ
  • ZipPostalCodeStart = empty
  • ZipPostalCodeEnd = empty
  • District = empty
  • County = empty
  • City = empty
  • TaxCategory = empty

This tax rate matches all shipping addresses going to New Jersey, US.

Here is another scenario:

  • Country = US
  • State = CO
  • ZipPostalCodeStart = 80101
  • ZipPostalCodeEnd = 80113
  • District = empty
  • County = empty
  • City = empty
  • TaxCategory = empty

This tax rate only applies to shipping addresses in Colorado, US with zip codes ranging between 80101 and 80113. It does not apply to the zip code 80115, for example. If the zip code range is invalid for the State of Colorado, it does not apply to any shipping addresses.

Conversely, you can apply a tax rate for all shipping addresses in UK for products with a tax category of "Soda" like this:

  • Country = UK
  • State = empty
  • ZipPostalCodeStart = empty
  • ZipPostalCodeEnd = empty
  • District = empty
  • County = empty
  • City = empty
  • TaxCategory = Soda

Configuring a tax system

To set up tax rates, add or import them through Commerce Manager or use the TaxImportExport class. For more information about configuring tax rates and jurisdictions, see Configuring Taxes in the Commerce User Guide.

Example: using TaxImportExport class to import Tax rates.

using Mediachase.Commerce.Orders.ImportExport;

public void ImportTaxes()
            var taxImportExport= new TaxImportExport();
            var csvFilePath = "[the file path of imported csv file]";
            taxImportExport.Import(csvFilePath, ',');
The format of csv file is described below.  Download a sample csv file.
Order Column name Description
1 JurisdictionName The jurisdiction name
2 StateProvinceCode The state or province code
3 CountryCode The country code
4 ZipPostalCodeStart The zip/postal code start
5 ZipPostalCodeEnd The zip/postal code end
6 City The city
7 District The district
8 County The county
9 GeoCode The geo code
10 JurisdictionCode The jurisdiction code
11 JurisdictionGroupName The jurisdiction group name
12 JurisdictionGroupCode The jurisdiction group code
13 TaxNativeName The tax native name
14 TaxName The tax name
15 SortOrder The sort order
16 LanguageCode The language code
17 TaxCategory The tax category
18 Percentage The percentage
19 EffectiveDate The effective date
20 TaxType The tax type: SalesTax or ShippingTax

Customizing taxes

To customize tax calculations, create a workflow that mirrors CartPrepareWorkflow, but substitute the CalculateTaxActivity activity with your own implementation.

Your implementation can access any internal or external tax calculation service. For the activity to work properly with other activities that calculate cart totals, your activity must set the TotalTax property of each OrderForm in the cart.

Related topic

Do you find this information helpful? Please log in to provide feedback.

Last updated: Oct 24, 2016

Recommended reading