Blog·August 2, 2026

How to block discount codes on sale items in Shopify

Marked-down products taking discount codes on top is the most common margin leak in Shopify. Here's why it happens and two ways to stop it.

Say you mark a hoodie down from $60 to $40. That’s a decision. You looked at the margin, decided what you could give, and priced it.

Then someone applies WELCOME15 at checkout and takes another $6 off, and your decision quietly stops mattering. Multiply that by every sale item and every live code and you get the number that surprises most merchants when they finally measure it. Discounts landing on already-discounted products are usually the single biggest line in their unintended discount loss.

Why Shopify allows this

To Shopify, your sale price is just the price. The compare-at field draws the strikethrough on your storefront, but discount codes don’t look at it. A 15% code means 15% off whatever the price happens to be, marked down or not.

There’s no native setting to change this. Nothing in the discount editor says “skip sale items.” You can build a discount that only targets certain collections, but you can’t tell an order-level code, or a code from some other app, to keep its hands off your markdowns.

So the fix has to happen at checkout, which is where PromoLock works.

First, know what “on sale” means

Everything below runs on one definition: a product is on sale when its current price is below its compare-at price. $40 price, $60 compare-at, that’s a sale item. If the compare-at is empty or equal to the price, it’s not.

This has a practical consequence. If you end a markdown by raising the price but leave the old compare-at sitting above it, that product still counts as on sale. Clearing compare-at when a sale ends is worth making a habit.

The store-wide fix: block codes when sale items are in the cart

In PromoLock’s Controller there’s a switch called Lock Discount Usage On Sale Items. It applies to every code entered at your checkout, including codes created by other apps, and it has two modes.

Block if the cart has any sale item. One marked-down product anywhere in the cart and codes stop working. Maximum protection, but blunt: a customer buying one clearance sock with $200 of full-price stock also loses their code, and that’s a support email.

Block when sale items exceed a percentage of the cart. This is the one most stores want. Set the threshold to 50 and a mostly-full-price cart keeps its code, while a cart that’s mostly markdowns doesn’t. The percentage is measured on money, not item count, so it maps to what the cart costs you.

Either way, you write the rejection message the customer sees. “Discounts can’t be used on sale items” does fine. It’s honest, and an honest message gets you fewer confused emails than a mystery error.

The per-discount fix: your own offers skip sale items by default

Discounts you create through PromoLock come with an On-sale items guard, and a new discount ships with it set to No discount. The discount never applies to marked-down lines. No blocking, no error, the code just doesn’t touch those items.

The same guard has a softer setting called Sale or code. The code still works on sale items, but the sale’s markdown counts toward it, so the customer gets whichever saves more and never both. A 20% code on a $60 item already marked down to $40 gives nothing extra; a 50% code would take it to $30. Useful when “20% off” is a promise you want to keep to the letter, including on sale items, without ever paying out on top of a markdown. There’s a full post on it.

If you only ever ran PromoLock-created discounts, this alone would close the leak. The Controller lock exists for everything else: your old native codes, the referral app minting unique codes, whatever’s still floating around inboxes from 2024.

Or don’t block at all

There’s a third option that deserves its own post, because for some stores it converts better: let codes work on sale items, at a lower rate you chose. Full-price items get 20%, sale items get 5%, one code, nobody’s checkout errors. If blocking feels too aggressive for your brand, read how to control discounts on sale items before deciding.

Check what it was costing you

PromoLock’s analytics has a report for exactly this, sale-item loss computed from your order history. Most merchants who look are surprised. Turn the lock on, watch that line flatten over the next month, and you’ll know precisely what the hoodie math was doing to your margin.

Loss calculator

Estimate your unintended loss.

Four quick questions. Planned promotions never count.

?$3.5M
Which of these are true for you?
?
?
?
?