Skip to content

PRD: Fare & Tax Pricing Engine

ModulePricingPRD IDPRD-FARE-001
StatusReady to devFEATFARE
EpicPlaneBANA-1513
Date2026-06-05Versionv1.0
Packages@nx/pricingURDFARE
SurfaceBackendClient · Owner/Mgr
OwnerPhát Nguyễn

What the Fare & Tax Pricing Engine is

Every product variant has a fare set - the container for its base fare and any conditional child fares; the system auto-creates a fare set + base fare the moment a variant appears, so every variant is priceable right away. An owner sets a parent fare under one of two strategies - OVERRIDE (always wins) or SALE (competes as a discount) - then adds child fares carrying their own price and eligibility rules (quantity, time window, and so on). The engine picks the winning fare by resolving the highest-priority tier first; within that tier an OVERRIDE fare always beats a SALE fare, and among valid fares of the same kind the lowest price wins; with no valid child fare it falls back to the base price.

Alongside that, an owner attaches percentage, fixed, or per-unit taxes to a variant's tax set, chooses inclusive (baked into the price) or exclusive (added on top), and taxes can compound on top of earlier ones in priority order. At checkout the sale flow calls one pricing simulation; the result is an immutable pricing snapshot - the applied fare and taxes per line plus order totals - so pricing is consistent and auditable every time. A line with no tax configuration still prices fine, just at zero tax - it is never blocked by missing configuration.

Why one engine is needed

Prices used to be hard-coded on the product or computed ad hoc at checkout - no consistent home for taxes, rule-based prices, or an auditable breakdown. Merchants need one engine that selects the right fare per variant, computes taxes correctly (inclusive/exclusive, compound, item-level), and returns one consistent priced result the sale flow consumes at checkout without re-implementing pricing logic. That is the foundation for reliable cost, tax, and margin reporting in the HKD/SME bookkeeping BANA targets.

The engine builds fare selection and tax computation on top of the product-variant catalog, confines every record to the user's own merchant, and exposes a pricing simulation the sale flow consumes.

One example, start to finish

Variant "White T-shirt" has a base price of 100,000 VND. The owner adds a SALE parent fare with a child fare priced at 80,000 VND, carrying the rule "quantity purchased is 10 or more". This variant's tax set attaches a 10% VAT, exclusive.

StepWhat happensResult
A customer buys 12 shirtsThe engine evaluates the quantity rule: 12 ≥ 10, the child fare is validThe 80,000 VND child fare wins, not the 100,000 VND base price
Tax is computed on the selected unit price10% exclusive VAT, added on topTax per shirt = 80,000 x 10% = 8,000 VND
The pricing simulation returns the line snapshot12 shirts, unit price 80,000 VNDsubtotal 960,000 VND, tax 96,000 VND, total 1,056,000 VND
A customer buys 5 shirts (a separate order)The quantity rule fails (5 < 10), the child fare is eliminatedThe engine falls back to the base price of 100,000 VND per shirt, with no error

The easiest thing to get wrong

The base price competes at its own priority tier too

The base price doesn't automatically lose to a child fare sitting in the same priority tier. The base price defaults to priority 0; a child fare also set at priority 0 has to compete on price fairly against the base price, like any other pair - having a child fare present doesn't automatically make it win.

Conversely, when a valid OVERRIDE fare is present in the tier that is currently winning, it wins immediately, with no price comparison against anyone else in that tier - not even a cheaper SALE fare.

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.