{"title":"How Promotion v2 discounts are calculated","slug":"how-promotion-discounts-are-calculated","url":"https://support.storeconnect.com/articles/how-promotion-discounts-are-calculated","url_markdown":"https://support.storeconnect.com/articles/how-promotion-discounts-are-calculated.md","subtitle":null,"summary":"Work out what a cart will actually be charged when several Promotions v2 apply: independent against cumulative calculation, how a subtotal discount is spread across lines, how fixed price for N groups items, and the caps that limit a discount.","type":"Help_Documentation","video_url":"","keywords":"promotion calculation, promotions v2 discount, independent, cumulative, calculation strategy, subtotal discount spread, proportional discount, fixed price for n products, discount cap, shipping discount tax, promotion rounding, exclude discounted, promotions.calculation_strategy","last_modified":"2026-10-25T21:42:50+0000","body_markdown":"Use this topic when a cart is charged an amount you did not expect, or when you are designing an offer that will run alongside others and need to predict the total. It covers the arithmetic the engine applies after it has decided which promotions qualify. For how that decision is made, see [About Promotions v2](advanced-promotions).\n\n## Independent or cumulative\n\nThe store variable `promotions.calculation_strategy` decides what a `discount_on_subtotal` reward is measured against. See [Store variables](store-variables).\n\n| Value | A subtotal reward is sized on |\n|---|---|\n| `independent` | The subtotal of the lines it can discount. This is the default |\n| `cumulative` | That subtotal less the recorded discounts of every promotion without a subtotal reward, and less those subtotal promotions ranked ahead of it by **Priority**. A shipping promotion's recorded discount is subtracted too, and so is any discount this promotion's own product rewards have already taken |\n\nThe lines a subtotal reward can discount are the product lines, less any that the reward's own exclude scopes name and any product set to **Exclude From Price Reductions** with the **Promotions** value. A register sizes the reward the same way.\n\nOn a cart holding one $100 product, carrying both a $30 off products promotion and a 50% off subtotal promotion:\n\n- `independent`: $30 plus $50, a **$80** discount.\n- `cumulative`: $30, then 50% of the remaining $70, a **$65** discount.\n\nCumulative is the choice when you want a stated percentage to mean \"off what is left\". Independent is the choice when each offer should stand on its own, which is easier to explain to a customer but can discount a cart more deeply than intended.\n\n## How a subtotal discount is spread across lines\n\nA `discount_on_subtotal` reward is not recorded against the cart. It is divided across the product lines in proportion to what each line still has left after the other promotions already on it.\n\nOn a $100 line and a $50 line, $30 off the subtotal splits into $20 and $10.\n\nIf a product promotion has already taken $40 off the $100 line, the two lines have $60 and $50 left, so the same $30 splits into **$16.36** and **$13.64**.\n\nShares are worked to the cent so that they add back to the reward exactly. Each share is rounded down, then any leftover cents are handed out one at a time to the lines with the largest remainders, and on a tie to the line added first.\n\n## Fixed price for N products\n\nA `fixed_price_for_n_products` reward takes items in groups of **Quantity**, in cart order. When **Max Eligible** is set, **Apply first to** sorts the items most or least expensive first before they are grouped. Each group is charged **Fixed Amount**, and the saving is spread across that group's items in proportion to their prices. A group that already costs less than the fixed price saves nothing.\n\nWith **Frequency** set to `once`, only the first group is repriced. With `no_limit`, one group is repriced for each time the condition was met, up to the number of complete groups.\n\n:::warning\nOn the web a group is counted in cart **lines**, not units. A single line holding three of the same product counts as one item toward a \"3 for $50\" reward, not three. Offers of this shape work as intended only where the customer adds distinct products.\n:::\n\nA \"3 for $50\" reward with **Frequency** `no_limit` and a condition of 3 items, on six separate items priced $30, $25, $20, $15, $10, and $5, is met twice and so forms two groups. The first group is worth $75 and saves $25. The second is worth $30, already below $50, and saves nothing. The cart is discounted by **$25**.\n\n## Shipping discounts\n\nA `discounted_shipping` reward is sized on the delivery line's price and then capped at it, so a discount can never exceed the charge. On a tax-exclusive store the reward is sized on the charge before tax; on a tax-inclusive store the price already includes tax and is used as it stands.\n\nA 50% reward on a $100 delivery charge with 10% tax added takes off $50, leaving $50 plus $5 tax, a **$55** delivery charge.\n\n## Caps\n\nTwo limits apply whichever calculation strategy is set.\n\n- **Per line.** A products, subtotal, or shipping reward takes no more from a line than that line still has left, counted from its sale price less what promotions have already taken.\n- **Per promotion.** A promotion's recorded discount cannot exceed the product subtotal plus the delivery charge. That subtotal is measured gross, on the sale price, so it does not shrink as other promotions apply.\n\n:::warning\nA fixed-price saving is not capped by what the line has left. On an already discounted line, the recorded discount can exceed the line's own value even though the price the customer pays stops at $0.\n:::\n\n:::note\nA line priced by a **Block Price** takes no Promotions v2 discount, and its value is left out of the subtotal that sizes a subtotal reward and caps a promotion. It still counts toward a promotion's conditions.\n:::\n\n## Exclude discounted on the web\n\nA reward with **Exclude Discounted** set skips a line that is on sale (priced below the list price), that carries a share of a discount on the whole sale, or that a staff member's discount or another promotion has already reduced. At a register, a promotion ranked after this one does not count. **Exclude Discounted** applies to `discount_on_products` and `fixed_price_for_n_products` rewards. A subtotal or shipping reward ignores it, so a sale item still counts toward a subtotal discount. See [How Promotions v2 run at the register](promotions-v2-at-the-register).\n\n:::warning\nThe check reads the discounts left on the line by the previous calculation, and that record includes promotions ranked after this one. Where two promotions discount the same line and one of them excludes discounted items, that one applies on the first calculation, then drops off on the next refresh and does not come back. Set **Exclude Discounted** only where a single promotion touches the line.\n:::\n\n## Checking the result\n\nOpen a test cart on the storefront and compare the cart totals against the figures above. Each promotion is listed as its own row in the totals, and every line's price is already net of the promotions recorded against it, so the totals and the line prices should agree without any further subtraction."}