Skip to content
Building a Shopify app or a SaaS product?Chat on WhatsApp
Promotions & Offers

Why Shopify Discounts Won't Stack, and How to Fix It

Two offers that each work alone frequently do nothing together, and “can't combine with other automatic discounts” sends people looking in the wrong place. The full combination matrix, the pairings that are genuinely impossible, and what to build instead.

AK
Aashish Kaushik · 14 min read · updated 28 October 2026
Female hand using a credit card while shopping online on a laptop from a top view angle.
On this page

Key takeaways

  • Shopify sorts discounts into three classes — product, order and shipping — and the combination setting is per discount, off by default, and must be ticked on both sides of a pairing.
  • Two order discounts never combine, and neither do two shipping discounts; no setting, app or Function changes that.
  • Two product discounts can combine across different cart lines, but only one applies per line unless you are on Plus and have configured two-way tag matching.
  • Buy X Get Y stacks only on the “customer gets” items, never on the “customer buys” items, which is usually the opposite of what the campaign intended.
  • Scripts stopped executing on 30 June 2026; the replacement is a Discount Function, which can return product, order and shipping savings from one discount instead of two hoping to combine.

A merchant builds a 20% collection discount in September and a free-shipping-over-threshold offer in October. Both work. In November a customer qualifies for both, gets one, and emails to ask why the site lied to them.

Nothing is broken. Shopify applied its combination rules, which nobody configured, and the defaults did not match what anyone assumed. This is the most common discount problem on the platform and it is almost entirely a settings problem.

The short version

Shopify sorts every discount into one of three classes — product, order and shipping. A discount combines with another class only if you ticked that class in its own Combinations settings, and those boxes are off by default. Within the product class, only one discount applies per cart line unless you are on Plus and have configured tag-based stacking.

The three types, and why the distinction matters

Every Shopify discount is one of three things, and the type determines what it can combine with.

Product discounts reduce the price of specific items — a percentage off a collection, a buy X get Y, an amount off particular products.

Order discounts reduce the order total — a percentage or amount off everything, usually with a minimum spend.

Shipping discounts reduce or remove shipping cost.

The rule that follows: discounts of different classes can be configured to combine, and you have to configure it. Two order discounts and two shipping discounts never combine at all. Two product discounts can combine across different cart lines, but on the same line only one applies unless you are on Plus. The table in the next section is the whole matrix.

This catches merchants because it is not how discounts feel from the customer side. A shopper does not experience "a product discount and an order discount"; they experience two offers. The distinction is a platform implementation detail that leaks directly into your promotional planning.

Combination settings are per discount, and default to off

The second thing that surprises people. Combination is not a global store setting. Each discount carries its own configuration specifying which other types it may combine with.

That means a discount created without touching those checkboxes will not combine with anything, even where the types would permit it. Two compatible offers built weeks apart by someone not thinking about the other will simply not stack, and nobody will have made a decision to that effect.

The practical implication is that combination has to be planned across your whole promotional calendar rather than per offer. Before creating any discount, know what else could be active — including codes already in circulation — and configure deliberately in both directions.

The failure is silent, which is what makes it expensive

If discounts errored when they failed to combine, this would be a minor annoyance. They do not.

The shopper qualifies for two offers, receives one, and sees a total lower than full price but higher than the landing page promised. From their side this looks like a store that overstates its discounts. Some ask; most leave.

You will not see this in your reports. There is no failed-discount metric. The order either happened at a total you did not expect, or did not happen at all, and neither shows up as an error anywhere.

What combines with what, and what never does

PairingCan it combine?What decides it
Product + OrderYesBoth discounts must tick the other's class in Combinations. Off by default on each.
Product + ShippingYesSame: each discount must allow the other's class.
Order + ShippingYesSame. This is the pairing most merchants assume is automatic and it is not.
Product + Product, different cart linesYesAllowed when both tick productDiscounts. A 20% off shirts and 10% off hats can both land in one cart.
Product + Product, same cart lineOnly on PlusBy default one product discount applies per line. Plus adds tag-based stacking (below); everyone else gets one.
Order + OrderNoTwo order-total discounts never combine. Shopify applies one.
Shipping + ShippingNoTwo shipping discounts never combine. Shopify applies one.
Buy X Get Y + another product discountPartlyStacking happens only on the “customer gets” (GY) items, never on the “customer buys” (BX) items.

“Can't combine with other automatic discounts”: what that message actually means

This is the single most-searched version of the problem, and the wording misleads people into looking in the wrong place.

It does not mean the two discounts are structurally incompatible. In almost every case it means one of them — usually the one you are editing — has not been told it may combine with the other's class. Shopify stores that as three booleans on each discount: whether it combines with product discounts, with order discounts, and with shipping discounts. All three start off.

Two things follow, and they are the two mistakes that produce most of these tickets.

The setting is one-directional per discount, so you have to set it on both. Ticking “combines with shipping discounts” on your 20% product offer does nothing if the free-shipping offer has not ticked “combines with product discounts” in return. Each discount independently declares what it tolerates, and the combination only happens where both agree. A merchant who edits one discount, retests, and sees no change concludes the pairing is impossible; it was half-configured.

If the message appears while you are editing, it is naming a real conflict in your store right now. Shopify surfaces it because something currently active occupies a class this discount refuses, which means it is also telling you which other discount to go and open. Treat it as a pointer, not a verdict.

The genuinely impossible pairings are short and worth memorising: two order discounts, and two shipping discounts. Those never combine regardless of settings, and no app or Function changes that — Shopify picks one. If your campaign needs “15% off the order and £10 off the order”, that is not a combination problem, it is a brief that needs rewriting as a single 20%-ish order discount, because the platform will never express it as two.

The Plus-only exception: two product discounts on one line

There is one real exception to “one product discount per line” and it arrived quietly in the Admin API, so most merchants do not know it exists.

On Shopify Plus, a product discount can carry a set of tags identifying itself and a second set naming the tags it agrees to apply alongside. Two discounts apply together on the same cart line only when the match holds in both directions: each must allow at least one tag the other carries. Tag discount A with LOYALTY and let it apply with SEASONAL; tag discount B with SEASONAL and let it apply with LOYALTY; both now land on the same line. Any number can stack this way, provided every pair in the group satisfies the same mutual match. It also requires the ordinary “combines with product discounts” flag to be on.

Two caveats before you plan a campaign around it. It is Plus-only, so it is not an answer for a store on Grow or Advanced. And the two-way rule means a group of four stacking discounts needs every pair checked, not just each new discount against the first — which is exactly the kind of combinatorial check that is easy to get wrong in the admin and worth writing down before you build.

Buy X Get Y stacks on half of itself

A specific trap worth its own paragraph, because it produces complaints that look like a bug.

In a Buy X Get Y discount, other product discounts stack only on the “customer gets” items — the GY side. They never stack on the “customer buys” items. So a cart where the shopper buys two jackets to get a free scarf will apply your separate 20%-off-outerwear discount to the scarf if it qualifies, and not to the jackets, which is the opposite of what the merchant usually intends and the opposite of what the shopper assumes. If your BXGY campaign overlaps any other product offer, walk that exact cart before launch.

The Functions route, now that Scripts are gone

Everything above describes what native discounts can express. When the campaign needs something they cannot, the answer used to be Shopify Scripts. It no longer is: Scripts became uneditable on 15 April 2026 and stopped executing entirely on 30 June 2026. Any stacking logic that still lives in a Script is not running, and if your combination behaviour changed sometime last summer without anyone touching it, that is where to look first.

The replacement is the Discount Function API, and it is better suited to stacking than Scripts ever was for one structural reason: a single function processes one discount but can apply savings across all three classes at once. One function can reduce the order total and the delivery cost together, which means an outcome that previously needed two discounts hoping to combine now needs one discount that simply computes the whole result. That is the real fix for most “won't stack” briefs — stop asking two discounts to cooperate and write the combined outcome once.

Three operational limits to design against, all from Shopify's own Function documentation:

Twenty-five. That is the maximum number of discount functions you can have activated on a store. Generous for most merchants, tight for one that has accumulated an app-installed function per campaign over several years. Audit before a peak period rather than discovering the ceiling in November.

They cannot see each other. All discount functions run concurrently and have no knowledge of each other. A function cannot ask “did the other discount already apply?” and branch on the answer. If two offers genuinely depend on one another, they have to be one function, not two that coordinate.

The combination rules still apply on top. What a function outputs is a candidate, and that candidate is still subject to the same combination and stacking settings on the discount node. Writing a Function does not exempt you from ticking the boxes; the merchant who assumes it does spends a day debugging working code.

If you are still carrying Script-era logic, the migration path is in Shopify Scripts to Functions, and what Functions can build today is in discounts with Shopify Functions.

How to detect it before customers do

  • Build every offer that could overlap and walk the customer path for each pairing
  • Include discount codes already emailed and not expired
  • Test a cart that qualifies for two offers and confirm which one wins
  • Check the total against what the campaign page promises
  • Watch order-level margin for movement after any new offer goes live
  • Confirm the Combinations boxes are ticked on BOTH discounts, not just the one you edited
  • For a Buy X Get Y offer, check the “customer buys” items specifically, since stacking only reaches the “customer gets” side
  • Count how many discount functions are activated, against the limit of 25 per store
  • Confirm no combination behaviour still depends on a Shopify Script, which stopped executing on 30 June 2026

A worked example of diagnosing one complaint

A customer emails saying the site promised 20% off and they only received free shipping. Working through this on the actual order, rather than guessing, takes a few minutes and settles it definitively.

Open the order in the Shopify admin and look at the Discount line in the order summary, which shows exactly what applied and, in most cases, the name of the discount. If only the shipping discount is listed, the product discount did not apply to this order, and the question becomes why.

Next, open the discount itself from Discounts in the admin and check its Combinations section, which lists which of the other two types, product, order or shipping, it is permitted to combine with. If the 20% offer is a product discount and its combinations do not include shipping discounts, that setting alone explains the outcome: both offers were live, both were valid for this customer, and Shopify applied the one it was told to apply rather than both.

Also check the discount's Active dates and Minimum purchase requirements against the actual order, since a threshold calculated per line item rather than per order is a common reason an order that looks large enough on the customer's screen does not actually qualify. If the customer's cart mixed several variants of the same product, check whether the discount counts variants separately, since a threshold written as a certain quantity of one product can silently exclude a cart holding that quantity spread across different sizes or colours.

Once the cause is confirmed, the reply to the customer can be specific rather than apologetic in the abstract: state which discount applied, why the other did not combine with it, and whether that combination rule is one you intend to change. That specificity is usually what turns a complaint into an accepted explanation rather than a repeat contact, and it is also the moment to add this pairing to the list described later in this article, so the same question does not arrive from the next customer who hits it.

Codes and accelerated checkouts

A separate stacking-adjacent problem that costs real revenue during promotions.

Automatic discounts apply at the platform level. They survive every checkout path, including Shop Pay, Apple Pay and Google Pay.

Discount codes require the shopper to enter them somewhere. Accelerated checkout buttons frequently compress or skip the step where that field appears. A shopper using a wallet button may have no opportunity to enter your code at all.

This means a campaign built entirely on a code will structurally fail for a portion of your traffic, and that portion is growing. Where the offer is unconditional, use an automatic discount. Reserve codes for cases where you genuinely need to gate the offer behind knowledge of the code.

When the cart shows one thing and checkout another

Worth distinguishing from ordinary stacking problems, because the cause is different.

Native discounts and Shopify Functions apply at checkout. What appears in the cart and what is charged are the same computation, so they cannot disagree.

If you see a discount in the cart that vanishes at checkout, the discount is probably not being applied at the platform level. It is being applied by something modifying the cart — an older app using cart rewrites, draft orders, or line-item manipulation. Those approaches are bypassed by accelerated checkouts and can be overridden by anything else touching the cart.

The fix is not configuration. It is moving to an implementation that applies at checkout, which since 30 June 2026 means Shopify Functions — legacy Scripts stopped running on that date.

Making complex combinations actually work

Sometimes the offer you want genuinely cannot be expressed as two native discounts that combine. The supported answer is to stop trying to make two discounts cooperate and express the combined outcome as one.

Shopify Functions lets you write the logic that produces the final result — evaluate the cart, decide what the customer should receive, and emit that as a single set of discount operations. Instead of hoping two discounts resolve correctly, you compute the intended outcome directly.

This is more work and needs a developer, but it eliminates the entire class of problem. There is no combination setting to get wrong because there is one discount, and no ambiguity about which offer won because the logic decided explicitly rather than the platform arbitrating between two things that were never designed to meet.

Choosing an approach

SituationApproach
Two offers of different typesNative discounts, combinations configured on both
Two offers of the same typeRethink as one offer, or make them mutually exclusive
Conditional on customer tag or historyShopify Functions
Multi-rung tiered thresholdsShopify Functions
Simple, unconditional, storewideNative automatic discount
Offer that must be gated by knowledgeDiscount code, accepting accelerated-checkout limits
Two product offers that must land on one cart linePlus only: tag-based same-line stacking, with a two-way tag match on every pair
An outcome spanning order total and shipping at onceOne Discount Function returning both classes, instead of two discounts combining

Telling the customer what is happening

A large share of the damage from non-stacking offers is communication rather than mechanics. The shopper does not know your discount types; they know they were promised two things and got one.

Three practices that remove most of the friction without changing any logic:

Say what combines, on the offer itself. A single line — "cannot be combined with other discounts" — on the campaign page and in the email costs nothing and prevents the entire expectation gap. Merchants avoid this line because it feels like it weakens the offer. It does not weaken it nearly as much as a shopper discovering the limitation at checkout.

Apply the better discount, and say so. Where two offers compete, the shopper should end up with whichever is worth more to them, and the cart should say that is what happened. "Your 20% collection discount has been applied instead of code SAVE10" turns an apparent failure into evident fairness.

Itemise in the cart and at checkout. A total that is simply lower reads as arbitrary. A total showing which discount applied and what it saved is checkable, and checkable totals generate far fewer support contacts.

The support inbox is your best diagnostic

Discount problems reach you as customer emails long before they show up in any report. If two people in a week ask why a code did not work, that is not two confused customers — it is a configuration problem with a much larger silent majority behind it. Treat the second email as the signal.

The planning habit that prevents all of this

Most stacking problems are not technical failures but planning failures, and one habit prevents nearly all of them: maintain a single list of every discount that could be active, with its type, its dates, and its combination settings.

Most merchants cannot produce this list on request, which is precisely why the problems occur. Offers accumulate. Codes from old campaigns keep working because nobody set an expiry. An agency created something two years ago that nobody has thought about since.

Before any promotional period, review that list, expire what should be dead, and explicitly decide what may combine with what. That review is twenty minutes and prevents the failure mode that costs the most during peak trading.

Set expiry dates on everything

A discount code with no end date is a permanent liability. It will be found, shared, and used during a period when you are also running something else. Every code should have an expiry, even ones you expect to extend — extending is one click and forgetting is expensive.

For offer strategy and what each mechanic does to margin, see promotions and offers. Checkout behaviour is covered in checkout and payments, and the Functions migration in Shopify development.

Frequently asked questions

What does “can't combine with other automatic discounts” mean on Shopify?
Almost always that one of the two discounts has not ticked the other's class in its own Combinations settings. Each discount independently declares whether it combines with product, order and shipping discounts, all three start off, and the combination only happens where both discounts agree. Set it on both, not just the one you are editing.
Can two automatic discounts apply to the same order?
Yes, if their classes are compatible and both have ticked the other's class. Product with order, product with shipping and order with shipping can all combine. Two order discounts and two shipping discounts never combine.
Can two product discounts stack on Shopify?
Across different cart lines, yes, when both allow product discounts. On the same cart line, only one applies by default. Shopify Plus adds tag-based stacking: each discount carries tags and names the tags it will apply alongside, and two discounts stack on one line only if each allows a tag the other carries.
How many Shopify discount functions can I have?
A maximum of 25 activated discount functions per store. They all run concurrently and have no knowledge of each other, so two offers that genuinely depend on one another have to be written as one function rather than two that coordinate.
Do discounts stack on a Buy X Get Y offer?
Only on the “customer gets” (GY) products. Other product discounts never stack on the “customer buys” (BX) products. If a BXGY campaign overlaps another product offer, walk that exact cart before launch.
Why is my Shopify discount code not working?
The usual causes, in order of frequency: a combination setting preventing it from applying alongside an active automatic discount, a date range not yet started or already ended, customer eligibility narrower than intended, minimum requirements not met because variants are counted separately, or a usage limit already reached.
Can a customer use a discount code and an automatic discount together?
Yes, if the combination settings on both permit it and their classes are compatible. This needs to be configured explicitly on each discount.
Did Shopify Scripts stacking logic stop working?
Yes. Scripts became uneditable on 15 April 2026 and stopped executing on 30 June 2026. If your combination behaviour changed around then without anyone touching it, a Script is the first place to look.

Building a Shopify app or a SaaS product?

ByteInfy designs, builds and ships them. Tell us what you are making.

Chat on WhatsApp

Or reach us directly

About the author

Aashish Kaushik

Founder

Builds Shopify apps and SaaS products at ByteInfy.

More from Aashish

Get new articles by email

No more than one a week. Unsubscribe in one click.

Comments

Comments are reviewed before they appear.

Keep reading

A customer making a contactless payment with a smartphone at a grocery store checkout counter.

Shopify Functions for Discounts: What Replaced Scripts

A Function computes the outcome you intended rather than hoping several discounts cooperate. That single property removes most of the failure modes merchants live with.

20 October 2026 · 7 min readRead
A businessman working in an online store packing shoes in a cardboard box.

What to Offer After BFCM So Buyers Come Back

You just acquired a large number of first-time buyers at the highest cost of your year. What happens in the next fortnight decides whether that was worth it.

27 October 2026 · 8 min readRead
Laptop and smartphone with Bitcoin symbol, depicting digital shopping

Tiered Discounts on Shopify: Thresholds That Raise AOV

A threshold set at a round number rewards customers who were already spending that much. Set it from your own distribution and it changes behaviour instead.

17 October 2026 · 8 min readRead
WhatsApp