Pricing
Vendure uses a multi-stage pipeline to determine the price a customer actually pays. Rather than storing a single "final" price, the system starts with a base price and transforms it step-by-step through strategies, promotions, and tax calculations. This makes it possible to support complex scenarios like channel-specific pricing, dynamic discounts, and tax-inclusive or tax-exclusive display.
The price pipeline
When an item is added to an order, Vendure resolves its price through the following stages:
- ProductVariantPrice — The base price stored in the database. Each
ProductVarianthas one or moreProductVariantPricerecords, scoped by channel and currency. - ProductVariantPriceSelectionStrategy — Selects which
ProductVariantPriceto use when multiple prices exist for the active channel and currency. - OrderItemPriceCalculationStrategy — Determines the unit price and whether it includes tax. This is the main extension point for custom pricing logic such as customer-specific pricing, tiered pricing, or time-based deals.
- Promotions — Any active promotions that apply order-level or item-level discounts are calculated and applied as adjustments.
- Tax calculation — The applicable tax rate is determined (based on tax category, zone, and strategy) and applied to produce the final tax-inclusive price.
The result of this pipeline is exposed in the GraphQL API as a pair of fields on every taxable price: a base field and a WithTax field. For example, an OrderLine exposes linePrice and linePriceWithTax, and the Order itself exposes subTotal / subTotalWithTax, total / totalWithTax, and so on.
Channel-specific pricing
Because ProductVariantPrice records are scoped to a specific channel and currency, the same product variant can have entirely different prices in different channels. This is essential for multi-region or multi-vendor setups where each storefront operates with its own currency and pricing structure.
A single variant might have a price of $30 USD in the US channel and 25 GBP in the UK channel. If a channel supports multiple currencies, the variant can even have more than one price within that channel.
The price vs priceWithTax convention
Throughout the Vendure GraphQL APIs, monetary values always come in pairs:
price— The amount without tax (or the tax-inclusive amount if the channel is configured for tax-inclusive pricing, in which case tax has been back-calculated).priceWithTax— The amount with tax included.
This convention applies to individual line items, order subtotals, shipping costs, and the order total. Your storefront can choose which value to display based on local regulations and conventions.
All monetary values in Vendure are stored as integers in the smallest currency unit (e.g., cents for USD). See Money & Currency for details on how Vendure handles monetary arithmetic.
Promotions and adjustments
After the base price is resolved, Vendure applies any qualifying promotions. Promotions never modify the base price directly. Instead, they add adjustments to the order or order line, which are tracked separately. This means the original price is always preserved, and discounts can be clearly itemized for the customer.
There are two levels of adjustment:
- Order-level adjustments — Applied to the order as a whole, such as "10% off your entire order" or "$5 off when you spend over $50".
- Item-level adjustments — Applied to individual order lines, such as "buy one get one free" on a specific product.
Both types are stored alongside the order and are visible in the API, so your storefront can show the customer exactly which discounts were applied and how much they saved.
Extending the pipeline
The pricing pipeline is designed to be customized at each stage. The two most common extension points are:
- OrderItemPriceCalculationStrategy — For scenarios where the price depends on runtime context such as the logged-in customer, the quantity, or external data.
- ProductVariantPriceSelectionStrategy — For controlling which stored price is selected when multiple options exist.
Both strategies are configured at the server level and apply globally. For details on implementing custom strategies, see the TypeScript API reference.
Related topics
- Money & Currency — Integer-based monetary values and currency handling
- Taxes — Tax categories, rates, zones, and calculation strategies
- Promotions — Discount rules and coupon codes
- Channels — Multi-storefront pricing and currency configuration
- Products — Product variants and how prices relate to variants