How to Configure Tax Calculation
This document provides a step-by-step guide on how to configure and integrate the Tax Calculation Flow in Commerce. The Tax Calculation Flow connects Commerce to an external tax microservice that calculates destination-based sales tax for each basket item during checkout.
This integration is particularly useful for markets where tax rates vary by jurisdiction — for example, US state and county taxes — and where each basket item may carry a different tax rate based on the shipping address.
1. Overview
When a customer selects or changes their shipping address or shipping option during checkout, Commerce sends a request to the configured tax microservice. The service returns a tax breakdown per basket item, which Commerce applies to the basket.
Key characteristics of this flow:
Destination-based tax: Tax is calculated based on the shipping address jurisdiction.
Per-item breakdown: Each basket item receives its own tax total and a breakdown of individual tax entries (e.g. state tax, county tax).
Non-blocking: If the tax microservice is unavailable or returns an error, checkout continues without applying tax.
Exclusive tax at basket phase: Tax is displayed separately from the product price during checkout.
Inclusive tax at order phase: When the order is placed, tax is incorporated into the order item price.
2. Setup
The Tax Calculation Flow is configured via the TAX_CLIENT_CONF dynamic setting in Omnitron.
2.1. Configuring TAX_CLIENT_CONF
Log in to Omnitron using your own credentials.

Navigate to Sales Channels → Sales Channel Settings → Dynamic Settings.

Search for TAX_CLIENT_CONF in the search box and click on it in the list.

Update the configuration on the edit screen with the following fields.

enabled
Set to true to activate the tax flow. When false, no tax requests are made.
base_url
The base URL of your tax microservice.
auth.username
Username for HTTP Basic Authentication.
auth.password
Password for HTTP Basic Authentication.
Example configuration:
When enabled is false, Commerce skips the tax calculation step entirely.
3. How the Flow Works
3.1. Trigger
The tax calculation is triggered during checkout whenever:
The customer selects a shipping address, or
The customer changes their shipping option.
Commerce checks whether the basket state has changed since the last tax calculation (dirty-check). If nothing relevant has changed, the microservice is not called again — avoiding redundant requests.
3.2. Checkout Phase
Once Commerce receives the tax response, it stores the tax data in each BasketItem.attributes under the tax key:
mode: "exclusive" means the tax is displayed on top of the product price — the basket item price does not include tax.
The pre-order summary (PreOrderSerializer) exposes a tax field that aggregates all item taxes:
3.3. Order Phase
When the order is placed, each BasketItem is converted to one OrderItem per unit. Commerce adjusts the tax data accordingly:
The tax total and each breakdown amount are divided by the basket item quantity to produce per-unit values.
The mode is changed from
"exclusive"to"inclusive"— tax is now baked into the order item price.
This means the OrderItem.price reflects the full unit price including tax, and OrderItem.attributes["tax"] records the per-unit tax breakdown for reporting purposes.
3.4. Clearing Tax
If the customer removes their shipping address or the basket state changes in a way that invalidates the previous tax calculation, Commerce clears the tax attribute from all basket items and recalculates on the next trigger.
4. Implementing the Extension Service
To integrate a tax microservice, you need to implement an HTTP endpoint that Commerce will call during checkout. Once the extension service is deployed, set its URL as the base_url in TAX_CLIENT_CONF to connect it to Commerce. For the full API specification — including request/response structure, field descriptions, and error handling — refer to the Extension Tax Flows documentation.
Last updated
Was this helpful?

