Korant

The discount stacking rules that quietly kill your margin

What the numbers say

  1. 01

    Shopify sorts discounts into 3 classes and applies them in a fixed order: product first, then order on the reduced subtotal, then shipping last.

    Shopify Help Center, combining discounts

  2. 02

    A 15% product discount, a 25% order discount and a 10% wallet redemption compound to a 46.6% giveaway on a Rs 2,000 order, against a 31.05% break-even.

    Modelled on stated assumptions: Rs 2,000 list, 35% gross margin, Rs 79 shipping absorbed.

  3. 03

    That stack turns a Rs 700 gross margin order into a Rs 231.50 loss once free shipping is absorbed.

    Modelled on the same assumptions, with COGS of Rs 1,300.

  4. 04

    Capping a wallet redemption on list price rather than on the running subtotal deepens the same stack from 46.6% to 50.2% and the loss from Rs 231.50 to Rs 304.

    Modelled on the same assumptions, varying only the base the wallet cap is computed against.

Three classes and a bilateral permission model

Shopify groups every discount into one of three classes, fixed at creation and not editable afterwards.

ClassApplies toCombines with itself
ProductSpecific items or collectionsNo, best one wins per line
OrderThe cart subtotalYes, when both permit it
ShippingDelivery costNo

Combination is a permission, not a default. Each discount declares which classes it may combine with, and both discounts have to grant permission before they stack.

That bilateral requirement is why stacks fail silently. A merchant enables combination on the new campaign, the old automatic discount was never updated, and only one applies with no error anywhere.

Two constraints are worth memorising. Where two product discounts target the same line, only the better one applies, so items are not double-discounted at product level. And items inside a Buy X Get Y promotion are ineligible for further product discounts.

Everything else can coexist. Order, product and shipping discounts can all apply to the same order, which is where the margin problem lives.

The order of operations that decides the damage

The sequence is fixed and it decides everything that follows.

StepWhat happens
1Product discounts apply, reducing line prices
2The order subtotal is calculated from the reduced lines
3Order discounts apply to that reduced subtotal
4Shipping discounts apply last

The consequence is that an order discount is never taking a percentage of list price. It is taking a percentage of a number that a product discount already lowered.

That sounds like it should limit the damage, and it does, slightly. It also means the stated depths on your discounts do not correspond to what any of them actually costs, so a team reasoning in percentages is reasoning about the wrong numbers.

Anything computed outside this sequence, such as a wallet redemption capped against list price, breaks the containment. That case is worked through below.

Worst case on a Rs 2,000 order

Assume a Rs 2,000 order, 35% gross margin, therefore Rs 1,300 of COGS and Rs 700 of gross contribution. Assume Rs 79 of shipping absorbed when the order qualifies for free delivery.

The break-even depth is contribution minus absorbed shipping, over list price. That is 31.05%. Any stack deeper than that loses money on the order.

Now stack four discounts, none of which looks unreasonable on its own.

StepDiscountSubtotal
StartRs 2,000.00
1Sitewide sale, 15% productRs 1,700.00
2Zone offer, 25% orderRs 1,275.00
3Wallet redemption, 10% capped on running subtotalRs 1,147.50
4Free shipping, Rs 79 absorbedRs 1,068.50 net

Total giveaway is 46.6% against a 31.05% break-even.

Margin on the order is negative Rs 231.50. The same order at full price would have contributed Rs 700.

No individual decision in that chain was wrong. A 15% seasonal sale is ordinary, a 25% zone offer is defensible, a 10% wallet cap is conservative, and free shipping is table stakes. Four reasonable choices produced a Rs 931 swing.

The compounding is invisible to each person who approved a step, because nobody was looking at the same order.

Where the wallet cap should sit

The third row is the one worth designing carefully, and it is where a referral wallet either behaves or does not.

SB&R is a Shopify app for chained referral rewards. Every referral link belongs to someone who has already bought. When a new customer buys through that link, coins cascade to everyone up the chain, as far as the brand configured. Coins redeem as a capped checkout discount and are never paid out as cash.

The phrase doing the work is capped checkout discount. A cap needs a base, and the choice of base changes the outcome materially.

Cap baseRedemptionNet after shippingGiveawayMargin
Running subtotalRs 127.50Rs 1,068.5046.6%Negative Rs 231.50
List priceRs 200.00Rs 996.0050.2%Negative Rs 304.00

Capping on list price costs an extra Rs 72.50 on this order, because the redemption is computed from a number that stopped being relevant two steps earlier.

Three design rules follow.

Cap on the running subtotal, so the wallet joins the multiplicative chain rather than sitting outside it.

Set the cap as an order-class discount, so Shopify’s own sequencing applies to it and it does not need separate reasoning.

Add a margin floor as a second constraint, not only a percentage. A 10% cap that would take the order below break-even should redeem less, and the shopper’s remaining balance should stay in the wallet.

That third rule is the one most implementations skip, and it is the only one that actually prevents the negative row.

Why multiplicative is not the reassurance it looks like

A common defence is that discounts multiply rather than add, so a 15%, 25% and 10% stack is not 50%.

That is arithmetically correct. Multiplicatively the three come to 42.6% rather than 50%.

It is not a defence. The break-even was 31.05%, so 42.6% is comfortably past it, and the 7.4 percentage points of containment bought by multiplication are irrelevant to whether the order made money.

Multiplication also stops applying the moment any component is computed on a different base, which is exactly what a list-price wallet cap does. The reassurance holds only while every discount stays inside the sequence, and one exception outside it removes the property.

Treat multiplication as a small mercy rather than a control. The control is the permission settings and the margin floor.

The pre-launch audit

Run this before every campaign. It takes twenty minutes and it is the only thing between four reasonable decisions and a negative order.

List every active and scheduled discount with its class and its combination permissions. Scheduled matters, since a discount going live in nine days will overlap with the campaign you are approving today.

Include app-generated discounts. Bundles, subscriptions, loyalty and referral apps all create discounts that may not appear where you are looking.

Compute the worst case. Deepest product discount, then deepest order discount on the result, then any wallet redemption, then absorbed shipping.

Compare against break-even depth. Contribution minus absorbed shipping, over list price, per product tier rather than as a blended figure.

Change a permission if the worst case exceeds it. Turning off one combination setting is faster than discovering the problem in a margin review a month later.

Run the audit per product tier. A blended break-even hides the fact that your lowest-margin SKU went negative while the average stayed positive.

Zone-gated offers belong in the same list, because an automatic discount that applies without a code is easy to forget when nobody had to type anything.

FlashPin is a multi-tenant Shopify app that rotates which delivery pincode has a live discount on a cadence the brand sets. Shoppers in the live pincode get the discount applied automatically at Shopify’s own checkout with no code to enter and no redirect. Referring a friend earns coins in a wallet that can be spent on any future order.

When stacking should be allowed

Blanket anti-stacking is the wrong correction and it destroys mechanics that were working.

Allow it where the second discount is buying something the first did not. A referral reward stacking on a seasonal sale is paying for an introduction, and refusing it punishes the customer who brought you a new buyer.

Allow it on high-margin lines, where the break-even depth is far enough above any plausible stack that the arithmetic never binds.

Refuse it on clearance, where the margin has already been spent, and on your lowest-margin tier regardless of what the blended figure says. Whether the campaign should have run at all is a separate question, answered in the five minute discount window.

SB&R is not for cash-payout affiliate programs, and it is not for B2B or wholesale referral. Coins redeem as a capped checkout discount and are never paid out as cash, which is also what keeps a referral reward inside the discount stack where the margin floor can reach it.

The limitation worth stating is that a margin floor protects the order and not the relationship. A shopper who has accumulated a wallet balance and finds it redeeming less than expected has been told, correctly, that the offer is capped, and no explanation of contribution arithmetic will make that feel good at checkout.

Design the cap so it is legible before the shopper reaches the payment step, and accept that a floor which never disappoints anyone is set too low to do its job. The frequency question that produced the overlapping discounts is in flash sales without the brand damage, and the credibility requirement is in scarcity you can defend.

The tool for this · Shopify app SB&R SB&R handles the chain, the cap, and the append-only ledger underneath it. Also relevant · Shopify app FlashPin FlashPin time-boxes the offer and applies it at checkout without a code, so there is nothing to screenshot and share.

Questions people actually ask

How do Shopify discount combinations work?

Every discount belongs to one of three classes: product, order or shipping. Each discount declares which other classes it may combine with, and the permission has to be granted on both sides before two discounts stack. A one-sided setting is not enough, which is why stacks often fail silently rather than erroring.

In what order does Shopify apply discounts?

Product discounts apply first, before the order subtotal is calculated. Order discounts then compute against that reduced subtotal. Shipping discounts apply last. The sequence matters because an order discount is always taking a percentage of an already-discounted number rather than of list price.

Can two product discounts apply to the same item?

Not natively. Where two product discounts target the same line, only the better one applies, so items are not double-discounted at product level. Items that are part of a Buy X Get Y promotion are also ineligible for additional product discounts, which prevents a common unintended stack.

Where should a wallet or loyalty redemption sit in the stack?

As an order-class discount capped against the running subtotal rather than against list price. Capping on list means the redemption is computed from a number no longer relevant to the order, which quietly deepens every stack it joins. The cap should also be checked against a margin floor, not only against a percentage.

How do you audit a stack before launching a campaign?

List every active and scheduled discount with its class and combination settings, then compute the worst case by applying the deepest product discount, the deepest order discount on the result, and any wallet redemption on top. Compare that figure to your break-even depth including absorbed shipping. If the worst case exceeds it, change a permission before launch.

Written by Nayak — Builds checkout, referral and attribution tooling for Shopify D2C brands