This article describes how to customize your E-commerce checkout process, so that tax (e.g. VAT) is applied on the shipping charge, not only on the products.
In summary, you could calculate tax in the CalculateShipping
method, where you can store the calculated tax into the cart.ShoppingCartCustomData
hashtable and then in the EvaluateShoppingCartContent()
method you can acquire it to display it in tax summary.
method will ensure adding tax to shipping using information about the shipping address. The tax will be applied to shipping anytime shipping will be acquired.
You can find some more information and a similar example in the E-commerce guide
Please refer below to see the necessary steps with a sample code for the involved methods;
Complete modified codefiles are also included in this zip package
, where you can see placement of this code into these code files. It matches 5.x versions code. However, it will work in 4.x as well.
The code doesn't take into account subjects exempt from paying taxes (supplied Tax ID), but this can be done quite easily.
It also doesn't allow for flat fees (absolute tax value), but these are probably never used.
For future usage, some optimizations could be carried out.
1. Calculate tax in CalculateShipping
2. Store tax in Hashtable steps are in the CalculateShipping
(the code is in CustomShippingOptionInfoProvider.cs
from the custom ecommerce providers project.)
public double CalculateShipping(object cartObj, string siteName)
CMS.Ecommerce.ShoppingCartInfo cart = cartObj as CMS.Ecommerce.ShoppingCartInfo;
if (cart != null)
// Get shipping address details
CMS.Ecommerce.AddressInfo address = CMS.Ecommerce.
// Get shipping address country and state
CountryInfo country = CountryInfoProvider.GetCountryInfo(address.AddressCountryID);
StateInfo state = StateInfoProvider.GetStateInfo(address.AddressStateID);
// Add tax to standard shipping price for countries/states with specified "ShippingTax"
CMS.Ecommerce.TaxClassInfo shippingTaxClassInfo = TaxClassInfoProvider.GetTaxClassInfo("ShippingTax");
if (shippingTaxClassInfo != null)
// tax will be zero if no value found for state/country
if (state != null)
double shippingTax = 0;
CMS.Ecommerce.TaxClassStateInfo tcsi = CMS.Ecommerce.TaxClassStateInfoProvider.
if (tcsi != null)
shippingTax = tcsi.TaxValue;
CMS.Ecommerce.TaxClassCountryInfo tcci = CMS.Ecommerce.TaxClassCountryInfoProvider.
if (tcci != null)
shippingTax = tcci.TaxValue;
// Perform calculation of shipping charge for current shopping cart
double shippingWithoutTax = CMS.CMSEcommerce.ShippingOptionInfoProvider.CalculateShipping(cart, siteName);
// Calculate tax amount
double calculatedShippingTax = TaxClassInfoProvider.GetTaxValue(shippingWithoutTax, shippingTax, false);
// Store calculated tax amount into shop.cart custom data
cart.ShoppingCartCustomData["ShippingTax"] = calculatedShippingTax.ToString();
// Return shipping charge including calculated tax
return shippingWithoutTax + calculatedShippingTax;
// Get standard shipping price in other cases
return CMS.CMSEcommerce.ShippingOptionInfoProvider.CalculateShipping(cart, siteName);
The next step - 3. Get tax into tax summary in EvaluateShoppingCartContent
from the custom ecommerce providers project):
public void EvaluateShoppingCartContent(object shoppingCart, bool evaluateForInvoice)
CMS.Ecommerce.ShoppingCartInfo cart = shoppingCart as CMS.Ecommerce.ShoppingCartInfo;
if (cart != null)
CMS.Ecommerce.TaxClassInfo tci = TaxClassInfoProvider.GetTaxClassInfo("ShippingTax");
if (cart.ShoppingCartCustomData["ShippingTax"] != null)
DataRow dr = cart.ShoppingCartTaxTable.NewRow();
dr["TaxClassID"] = tci.TaxClassID;
dr["TaxClassDisplayName"] = tci.TaxClassDisplayName;
// Get the added tax value from cart custom data hashtable
double taxValue = double.Parse(cart.ShoppingCartCustomData["ShippingTax"]);
// Add the shipping tax summary into the tax table
AddTaxSummary(cart.ShoppingCartTaxTable, dr, taxValue);
add a call of the ShoppingCartInfoProvider.EvaluateShoppingCartContent(ShoppingCartInfoObj)
method before the "return true;" command within the "try" statement in the ProcessStep()
method in the ShoppingCartPaymentShipping.ascx.cs
file. (line approx. #170). It's located in ~\CMSModules\Ecommerce\Controls\ShoppingCart\
within the web project folder. It enforces the reloading of shopping cart content and loads the new value of the calculated tax.
Also add the following line in bold into the ~\CMSModules\Ecommerce\Controls\ShoppingCart\ShoppingCartPaymentShipping.ascx.cs
file as shown below:
public override bool ProcessStep()
// Cleanup the ShoppingCart ViewState
ShoppingCartInfoObj.ShoppingCartShippingOptionID = ValidationHelper.GetInteger(drpShipping.SelectedValue, 0);
ShoppingCartInfoObj.ShoppingCartPaymentOptionID = ValidationHelper.GetInteger(drpPayment.SelectedValue, 0);
// Update changes in database only when on the live site
catch (Exception ex)
lblError.Visible = true;
lblError.Text = ex.Message;
Finally, you will need to add the tax class in CMSDesk -> Tools -> Ecommerce -> Configuration -> TaxClasse
s with codename "ShippingTax
" (it must be the same string as used in the code) and define values (in %) for the countries (states) where it should be applied.
Kentico CMS 4.x, 5.x
Created on 10/8/2010 5:00:17 AM