Discounting is the most overused growth lever in Shopify. Sitewide 15% off, free shipping over $50, BOGO on selected lines, abandoned cart 10% off, BFCM 30% off everything, post-purchase upsell at 20%, loyalty member exclusive 25%, the list keeps going. Some of these are necessary. Most are not. And almost all of them quietly destroy gross margin without anyone in the business seeing the actual cost.
The reason this is so easy to miss is that Shopify reports show you discount as a line item on revenue. You see "discount: $48,200" for the month and think you understand the cost. You do not. The actual hit lands in gross margin, and the gap between "what we discounted" and "what it cost us" is significantly bigger than most operators realise.
This post walks through how discounting actually shows up in your numbers, why standard reports understate the damage, and how to track real margin erosion across a multi-store Shopify operation.
The simple version
Imagine you sell a product at $100 with 40% COGS. Normal gross margin is $60.
Now you discount it 20%. The customer pays $80. Your COGS is still $40. Gross margin is now $40. You did not lose 20% of revenue. You lost 33% of gross margin.
Every percentage point of discount comes off the top of revenue but the bottom of gross margin. A 20% discount on a 40%-margin product wipes out a third of your margin on that order. A 30% discount wipes out half. A 40% discount makes the order a loss.
This is the simple version, and most Shopify reports do show this if you click into the right view. The harder problem is what happens at scale, across multiple stores, where the discount stacking is invisible.
Where discounting actually hides
The visible discount is the one you set in Shopify. The customer entered code WELCOME10 and got 10% off. That shows up. The invisible costs that come with most discounting strategies are the ones that quietly compound:
Stacking
A customer applies a welcome 10% off, hits free shipping, gets the bundled discount, and accepts the post-purchase upsell at 20%. None of these on their own look bad. Stacked, they pull the order from a 45% gross margin to 18%. Most Shopify accounts allow some level of stacking by default unless rules are set explicitly.
Free shipping absorption
"Free shipping over $50" sounds free to the customer because you absorb it. But shipping is real money, somewhere between 6% and 12% of order value depending on weight and zone. Most Shopify accounts do not track shipping cost back to the specific order or campaign it was applied to, so the cost just shows up as a P&L line nobody attributes to discounting.
Auto-applied loyalty discounts
Many brands run loyalty programs that take 5-10% off automatically for repeat customers. The customer never sees a code, the team never tracks it as a "discount", and Shopify reports it as a price adjustment or a tag-driven discount. It still costs you the same money.
Landing page discounts baked into the URL
"Shop the sale" landing pages with prices already 20% off relative to retail. The discount is baked into the variant price, not the cart. Shopify shows the lower price as the regular price for that landing flow. There is no discount line at all.
Order-edit discounts from customer service
Customer service applies a discount to fix a complaint or chase a delivery delay. The order shows up at the lower amount. Reports show a small one-off adjustment with no pattern. Add up a year of these and it is a real number.
Total these up and the real "discounted percentage of revenue" on most multi-store brands sits somewhere between 12% and 25%, while their official Shopify discount line says 4% to 7%.
The multi-store version
Multi-store brands run different discount strategies on different stores, often with different teams. Store 1 holds a "premium, no discounting" position. Store 2 has a permanent sale section. Store 3 stacks welcome offers, loyalty, and cart-level promos.
The blended number you see at the brand level (one P&L summing across stores) hides where the margin is actually leaking. The brand-level gross margin might look fine at 42% because Store 1 holds it up at 50% while Store 3 has slipped to 31% from heavy stacking.
Without per-store, per-discount-type tracking, you do not see this. By the time the year-end accounts come in, the team has been running a 31%-margin business on Store 3 for nine months and never knew.
What real discount tracking looks like
The version that catches the leak is per-store, per-product, per-discount-source. The rough structure:
| Store | Order count | Gross discount % | Stacked impact % | Free shipping cost % | Net margin impact % |
|---|---|---|---|---|---|
| Store 1 (premium) | 2,400 | 4% | 4% | 1.1% | 5.1% |
| Store 2 (everyday) | 3,800 | 11% | 14% | 2.4% | 16.4% |
| Store 3 (sale-driven) | 1,900 | 9% | 18% | 3.0% | 21.0% |
Gross discount is the headline number from Shopify. Stacked impact adds in the order-level effect of multiple promos hitting the same order. Free shipping cost is the absorbed shipping the customer would otherwise have paid. Net margin impact is the total hit to gross margin.
The pattern most brands find when they first build this view: real discount cost is roughly 1.5 to 2.5 times what their Shopify-level discount line says. Store 3 in the table above shows 9% gross discount but a 21% net margin impact, more than double.
How this compounds across multiple stores
Multi-store operators run into a second issue: the same customer buys across stores. They pick up a 10% welcome discount on Store 1, a 15% loyalty discount on Store 2, and a free shipping offer on Store 3. Across the brand, that customer's net margin contribution is much lower than any single store sees.
The way to track this is dedupe customers across stores (by email or shared loyalty ID) and compute customer-level discount load. A customer who bought $400 across three stores at a blended 22% discount cost the brand $88 in margin. The individual stores each saw "small" discount lines.
Without this view, you never see the customer-level erosion. With it, you spot the customers whose total margin contribution sits below break-even across the entire brand.
Three operational moves, in priority order
Track stacked margin impact, not just discount line items
The first job is to see real discount cost as a percentage of net margin per store, not as a percentage of revenue. The reports will be uglier. They will also be honest. This usually means joining Shopify discount data with order-level shipping cost from your 3PL and any auto-applied loyalty discounts from your loyalty platform.
Cap stacking
Most brands have no rule preventing customers stacking five promos. Shopify's default behaviour allows it for many discount types unless explicitly blocked. The simplest fix is to pick the top three discount types per store and disable stacking among them. Customer gets the best one, not all of them. This usually adds 2-4 points of gross margin overnight, with no measurable impact on conversion rate.
Per-channel discount attribution
Different acquisition channels have different discount loads. Meta ads land cold customers who get welcome 10% plus free shipping. Google branded keywords land repeat customers who already get loyalty 15%. The blended discount rate hides this. Per-channel tracking shows you that paid social customers cost 18% more in discounting than organic search, which changes how you think about CAC.
Worked example: the gap between "reported" and "real"
A multi-store brand books $400,000 in revenue across three stores in a month. Shopify's discount line shows $32,000, or 8%. The team reports gross margin of 41%.
Real discount load, after reconciling stacked discounts, free shipping absorption, auto-applied loyalty, and customer service adjustments:
| Discount source | Cost | % of revenue |
|---|---|---|
| Shopify-reported discounts | $32,000 | 8.0% |
| Order-level stacking adjustment | $11,200 | 2.8% |
| Free shipping absorption | $8,400 | 2.1% |
| Auto-applied loyalty | $6,800 | 1.7% |
| CS-applied order adjustments | $2,400 | 0.6% |
| Total real discount load | $60,800 | 15.2% |
Reported 8% versus real 15.2%. Real gross margin is not 41%, it is closer to 34%. Across a year that gap is over $300,000 in margin the team thought they had. It does not mean the discounting is wrong, it means the team has been making decisions on a number that understates real cost by half.
The data problem
Doing any of this requires data that lives in Shopify (per-discount-type usage), in your 3PL (shipping cost back to the order), in your loyalty platform (auto-applied loyalty), and in your customer service tool (manual order-level discounts). Pulling it together to see real net margin impact per store, per product, per channel, is the kind of work that takes a finance person days and is stale by the time it is done.
At Perch we build discount margin tracking directly into every dashboard. Discount type, stacking, shipping absorption, and the customer-level cross-store view are all surfaced live by store. Operators see the real margin hit per discount campaign, not the revenue-line version Shopify shows.
Bottom line
Discounting hits gross margin harder than it hits revenue. A 20% discount on a 40%-margin product takes 33% of the margin. A 30% discount takes half. Stacking, free shipping absorption, loyalty programs, landing-page price changes, and customer service adjustments all pile on top of the visible discount line, and the real margin cost is usually 1.5 to 2.5 times the Shopify-reported number.
Multi-store brands have it worse because customers cross stores and stack different promos at different brands. Without per-customer cross-store tracking, the leak is invisible.
The fix is honest tracking: per-store, per-product, per-discount-source net margin impact. The numbers will be worse than what your current reports show. They will also be the truth, which is what you actually need to make decisions on.
See your real discount cost per store, in one view.
Every Perch dashboard surfaces stacked discount impact, free shipping absorption, and auto-applied loyalty cost as a single net margin number per store. Tell us about your stack and we'll email your quote.
Get your quote →