Skip to main content

Price Calculation

note

The calculations described in this section are applicable both to checkout and order.

Introduction

There are multiple factors affecting the final price of an order. In a nutshell, Saleor first seeks the variant price and shipping cost for a specific channel, then applies all discounts, and finally calculates taxes.

Undiscounted price

​​Firstly, Saleor is looking for a variant price and shipping cost for a specific channel. There is an option to override the prices by providing a price argument in orderLineCreateInput, checkoutLineInput or checkoutLineUpdateInput. In case of checkout mutations, overriding prices can be done only by app with HANDLE_CHECKOUTS permission. Whether the price was taken directly from the channel or overridden, it is reflected as an undiscounted price.

Discount application

Base price

We first apply line-level discounts which decrease unit prices, resulting in the so-called base price:

base_unit_price = undiscounted_price - (manual_line_discount or (catalogue_promotion + line-level_voucher))

base_line_price = base_unit_price * quantity

base_subtotal = Σ(base_line_priceS)

base_shipping_price = undiscounted_shipping_price - shipping_voucher

warning

Some of the line discounts are mutually exclusive:

  • manual line discount overrides all other line discounts
  • only one voucher can be applied

Untaxed price

Having line-level discounts applied, we can sum up all the lines and calculate the base subtotal, which will be the basis for applying order-level discounts:

untaxed_subtotal = base_subtotal - (manual_order_discount or entire_order_voucher or order_promotion)

untaxed_shipping = base_shipping_price - manual_order_discount

warning

All order-level discounts are mutually exclusive and can't be combined.

  • The entire order voucher decreases the subtotal price and doesn't affect the shipping price.
  • The order promotion can either decrease the subtotal or grant a gift, which will be added to the order as an extra order line with zero price.
  • The manual discount decreases both subtotal and shipping prices. If the fixed value is provided, Saleor proportionally computes the subtotal and shipping portion.

After the application, when using flat rates or Avatax plugin tax strategies, the discounts are proportionally propagated to the order lines, decreases the unit and total prices. When a custom tax app is used to calculate taxes, this is done by the app itself.

Tax calculation

After handling the discounts, Saleor calculates taxes to reflect gross prices (or net if pricesEnteredWithTax is set to True). Tax calculation can be omitted by chargeTaxes setting or tax exemption API. Saleor offers three tax calculation strategies.

Assumptions

  • The line.totalPrice is the primary source of truth for price calculations.
  • Taxes are applied at the line level, with line.totalPrice reflecting all applied discounts.
  • The line.unitPrice is calculated from line.totalPrice by dividing it by the line.quantity. However, due to rounding, the product of line.unitPrice and line.quantity may not exactly equal line.totalPrice.
  • The order.total is determined as the sum of all line.totalPrice values.

Flat rates

When using flat rates, all the calculations are done by Saleor itself. It applies static tax rates, defined by the user, associated with products, product types, shipping methods or countries. Taxes are applied to the line total prices. The taxed unit_price is calculated by dividing the taxed total_price by the line quantity.

Tax app

Over CHECKOUT_CALCULATE_TAXES and ORDER_CALCULATE_TAXES sync webhooks, Saleor serves TaxableObject, which can be used as a payload for custom tax apps. In return, Saleor expects final line prices and shipping price, with all discounts included and tax rates applied. The prices obtained from the tax app are considered final and take precedence over both net and gross prices. The only thing Saleor calculates are undiscounted gross prices based on received tax rates.

Avatax plugin

warning

The Avatax plugin will be removed in Saleor 4.0.

Avatax plugin is a built-in integration with Avalara. Similar to custom tax apps, final data relies on extrenal tax service, but in this case Saleor is responsible for handling Avalara response data and applying it to the prices.