Catch leaked, stacked and forgotten discount codes before they eat your margin
Updated · By Ecomsellertool editorial team
To catch discount code leaks, read the codes on every Shopify order and compare each code's redemptions, buyers, referrers and stacked discounts with what the code was meant for. Rules alert when a code is used far above its expected rate, arrives from a coupon site, stacks below your margin floor or runs past its campaign. A person decides whether to deactivate, cap or replace it.
- Shopify discount codes can carry a total usage limit, one use per customer (tracked by email address or phone number), customer eligibility, a minimum purchase and start and end dates (checked November 12, 2026).
- Customers can use up to 5 product or order discount codes and 1 shipping discount code on the same Shopify order.
- Two percentage order discounts on one Shopify order are both calculated on the original subtotal, so 10% and 20% off $100 comes to $70.
- Deactivating a code through the Admin API sets its end date to now; reactivating an expired discount in the admin leaves it Active with no end date.
- In this recipe rules do every count and calculation; a person decides every deactivation, cap and replacement code.
The step map: who runs each step
Trigger: Every new Shopify order that carries a discount code, an hourly count of redemptions per code, the Discount code created event in Shopify Flow, and a weekly audit of every active code.
| Step | What happens | Who runs it |
|---|---|---|
| 1 | When an order is created, rules read its discount codes, the discount applications and total discount, the customer, and the referrer and landing page of the visits before the order. | Rule |
| 2 | Rules match each code to its campaign record: who the code was meant for, the expected redemptions per day, the margin floor and the campaign end date. | Rule |
| 3 | The signal table runs: a redemption spike, a coupon-site referrer, a buyer outside the intended audience, a stack below the margin floor or a code past its campaign end each raises an alert with the evidence. | Rule |
| 4 | Rules work out the margin at risk for the alert: unexpected redemptions times the average discount, and the contribution left on an order after all its discounts. | Rule |
| 5 | A weekly audit reads every active code's settings and flags codes with no usage limit, no end date, combinations the campaign did not ask for, or a new code created outside the plan. | Rule |
| 6 | A person reviews each alert and decides: deactivate the code, cap it, narrow who can use it, replace it with unique codes, or leave it running. | Person |
| 7 | Rules carry out the decision through the Admin API, log who decided and why, and add the code to the next weekly summary. | Rule |
6 rule steps · 0 AI model steps · 1 person step. A rule follows fixed logic you approve; an AI model handles messy input and its output is checked by rules; a person makes the calls listed below.
What stays with a person
- Deactivating, capping or replacing any code, since real customers may be at checkout with it
- Whether a spike is a leak or a campaign that simply worked
- What to tell a customer whose leaked code stopped working
- The campaign record itself: audience, expected rate, margin floor and end date for each code
- Which discounts may combine, set per campaign
Which tools can run it
- Shopify Flow: the Discount code created trigger and the Get discount data action for a weekly summary of active codes
- Shopify Flow or Shopify webhooks plus Zapier, Make or n8n, to count redemptions per code, check referrers and post alerts to Slack
- Custom code on your accounts, for margin per order after every discount, campaign records, unique code sets and deactivation from the alert
Systems it connects
- Shopify orders and discounts
- Shopify Flow
- Product cost per item
- Email or SMS platform that sends the codes
- Influencer or affiliate list
- Slack or email for alerts
Build size: Medium
Shopify holds the codes and the order data; the work is the campaign record per code, the margin math after stacking and a clean alert a person can act on.
A discount code is a promise to a group of people: new subscribers, a creator's followers, last year's wholesale buyers. The trouble starts when the code leaves that group. It lands on a coupon site, gets shared in a forum, stacks with a sitewide sale, or keeps running for months after the campaign ended. Nobody notices, because the orders look like good orders. This recipe gives every code a written purpose, watches the orders against it, and puts a person in charge of what happens next. It is one page of our automation library.
Which signals show a code has leaked, and who decides?
Start with a table, because "leaked" means different things for a welcome code and a creator code. Each row names a signal, where the workflow reads it, what the rule does on its own and what stays with a person. The data comes from the order: Shopify's Order object carries the discount codes used, noting that "multiple codes can be applied to a single order", plus the discount applications and the total discounted (checked November 12, 2026). The thresholds are illustrative. Copy the table and set your own.
| Signal | Where it is read | What the rule does | What a person decides |
|---|---|---|---|
| Redemptions far above the expected rate, for example 3 times the code's 7-day average | The discount codes on each new order, counted per code per hour | Alert with the count, the expected rate and the first orders in the spike | Leak or a campaign that worked: deactivate, cap or leave it |
| Orders arriving from a coupon or deal site | The visits before the order: Shopify's CustomerVisit has the referrer URL, landing page and UTM parameters | Match the referrer against a list of coupon sites your team maintains; alert on the first match per code | Confirm the leak; replace the code with unique codes for the intended group |
| A buyer outside the intended audience | The customer on the order, against the campaign record (subscriber tag, creator list, wholesale tag) | Flag the order; alert when the share of outside buyers passes your limit | Narrow the code to a customer segment or specific customers, or accept it |
| The same person using a code again | Orders per customer per code | Flag repeat use when the code allows more than one use | Turn on one use per customer, or switch to unique codes |
| Stacking that breaks the margin floor | Every discount on the order, the total discounted and the product cost per item | Work out contribution after all discounts; alert when an order falls below the floor | Change which discounts the code combines with |
| A code still active after its campaign ended | The code's status and end date, against the campaign end date | Alert the day after the campaign ends, then daily | Set an end date or deactivate it |
| A code with no usage limit, no end date or combinations the campaign did not ask for | The code's own settings, in the weekly audit | List it in the audit with the missing setting | Add the cap, the end date or the combination rule |
| A new code created outside the plan, by staff or an app | The Discount code created event | Check it against the rules for caps, end dates and combinations | Approve it, fix it or remove it |
| A capped code close to its limit, for example 90% used | Redemptions against the code's usage limit | Alert once | Raise the cap or let it close as planned |
Two rules keep the table honest. A single signal that is common among real customers, such as one repeat buyer, only flags; an alert needs the signal to pass a threshold or meet a second signal. And every alert carries its evidence: the code, the campaign it belongs to, the orders that triggered it and the margin at risk, so the person reading it can decide in a minute.
How much margin is a leaked code costing you?
Two numbers tell you how urgent an alert is. The first is the discount you are giving to people the code was not meant for. The second is what is left on each order after every discount. Our glossary entry on contribution margin explains the base.
Margin at risk per week = (redemptions per week − expected redemptions per week) × average discount per order
Contribution per order after discounts = order subtotal − all discounts − product cost − fees and shipping
The first number is an upper bound. Some people who found your code on a coupon site would have bought at full price, so not every dollar is lost; some would not have bought at all. The second number has no such doubt: if it is below zero, every order with that stack loses money.
A worked example
Every number here is illustrative, not from any store or client. Picture a $60 average order subtotal, product cost of $21 and $12 of fees and shipping, so $27 of contribution before any discount. The welcome code is 15% off the order, meant for about 40 new email subscribers a week.
| Situation (illustrative) | Code uses per week | Expected | Discount per order | Margin at risk per week | Contribution per order after discounts |
|---|---|---|---|---|---|
| Welcome code working as planned | 40 | 40 | $9.00 | $0 | $18.00 |
| Welcome code posted on a coupon site | 240 | 40 | $9.00 | $1,800 | $18.00 |
| Leaked and stacked with a 10% order code | 240 | 40 | $15.00 | $3,000 | $12.00 |
| Old 30% campaign code still running after it ended | 60 | 0 | $18.00 | $1,080 | $9.00 |
| Creator code at 40%, leaked and stacked with the 10% code | 150 | 50 | $30.00 | $3,000 | −$3.00 |
The stacked rows use Shopify's own math. Its combining discounts page says that when two or more percentage order discounts apply, both are calculated on the original subtotal, so 15% and 10% off $60 is $15 off (checked November 12, 2026). Product discounts apply first, then order discounts on the revised subtotal, then shipping discounts. The last row is the one to act on today: each order loses $3, so a person deactivates the code and sends the creator a fresh one.
What can Shopify's own settings prevent?
Most leaks get worse because a setting was left open. Shopify's discount codes page lists what each code can carry: the number of times it can be used, a minimum order amount, whether it combines with other discount classes and the dates it is valid, in your store's time zone (checked November 12, 2026). Its amount off discounts page adds eligibility for all customers, customer segments or specific customers, and a one-use-per-customer limit "by tracking a customer's email address or phone number". It also says a code with no end date does not expire.
| Setting | What it stops | What it does not stop |
|---|---|---|
| Total usage limit | A public code running without end | Every use until the cap is reached, by anyone |
| One use per customer | The same email address or phone number using it twice | A second email address |
| Customer segments or specific customers | Strangers using a code meant for a known group; a code can name up to 100 specific customers, products and variants | Sharing inside the group |
| End date | A campaign code running for months | Anything before the end date |
| Combination settings | Stacking you did not plan | A single deep code |
| Unique codes per person | One leak spreading to everyone | Nothing, if each code is single-use; Shopify allows up to 20,000,000 unique codes per store |
The limits on stacking are wide. The combining page says customers can use up to 5 product or order discount codes and 1 shipping discount code on one order, a store can have up to 25 active automatic discounts, and when codes and automatic discounts both apply, the best discount or combination applies on its own. Stacking product discounts on the same line item is for Shopify Plus stores only. So the combination setting on each code matters more than any one percentage.
What should a person do with an alert?
Pick the smallest fix that stops the loss. Shopify's managing discounts page says you can temporarily deactivate an unexpired discount, and a customer who then enters it sees "Unable to find a valid discount matching the code entered" (checked November 12, 2026). It also holds a trap: reactivating an expired discount makes it Active with no set end date. Any code you turn back on needs a new end date the same day, which the weekly audit checks.
| Decision | When it fits | What the workflow does |
|---|---|---|
| Leave it running | The spike is a campaign that worked, and contribution stays above the floor | Raises the expected rate on the campaign record |
| Cap it | The code is public but still profitable; you want it to close soon | Sets a usage limit a little above today's count |
| Narrow it | Strangers are using a code meant for a known group | Changes eligibility to the segment or the customer list |
| Stop the stack | Orders fall below the floor only when combined | Changes the code's combination settings |
| Deactivate and replace | Orders lose money, or the code was meant for a small group | Deactivates it and drafts unique codes for the intended group, for a person to send |
Deactivation through the API is the discountCodeDeactivate mutation. It needs the write_discounts scope, keeps the discount's settings, and sets its end date to the current time; a discount scheduled for the future gets both its start and end set to now. A customer who was emailed the old code will hit an error, so plan the message to the intended group before you switch it off.
Can Shopify Flow run this on its own?
Partly. Shopify Flow's Discount code created trigger starts a workflow when a code is created by you or a third-party app, and a separate trigger covers automatic discounts (checked November 12, 2026). The Get discount data action returns up to 100 discounts per run, and Shopify's template "Email weekly summary of active discounts that use a code" runs it on a schedule. Our guide to what Shopify Flow automates covers the basics.
| Job | In Shopify Flow | Where a workflow tool or custom code takes over |
|---|---|---|
| Check a new code's settings | Discount code created trigger, then a condition and an alert | Nothing more needed for a few codes |
| Weekly list of active codes | Get discount data on a schedule, with the weekly summary template | Adding the campaign record and the missing settings to each line |
| Count redemptions per code per hour | Not practical | A counter on each order, compared with the expected rate |
| Coupon-site referrers | Not practical | Reading the visits before each order against your list |
| Margin after every discount | Not practical | Product cost per item, fees and shipping per order |
| Deactivate or cap from the alert | Not covered by the action reference | An Admin API call after a person approves |
Count redemptions from orders, not from the code. Shopify's DiscountCodeBasic object has usageLimit, appliesOncePerCustomer, combinesWith, startsAt, endsAt and totalSales, but its asyncUsageCount "updates asynchronously", and the DiscountRedeemCode page says the count "can be different than the actual usage count" (checked November 12, 2026). For a monthly view, Shopify's Sales by discount codes report groups sales by the discount's name. If you are weighing workflow tools, our Zapier vs Make vs n8n comparison covers how each counts work.
How does it fit with your other margin alerts?
Discounts are one of three things that move margin per order without anyone changing a price. Costs are the second: our supplier cost change alerts recheck margin per SKU when a supplier's price moves, and the margin floor in this recipe should be the same number. Advertised prices are the third, which our MAP price monitoring recipe watches.
Creator codes need their own campaign records. Our creator gifting orders recipe already tags each send with a campaign code; the creator's discount code can share that campaign, so its expected rate and audience sit next to the product you sent. And if your daily sales report shows discounts rising faster than sales, this is the workflow that says which code is behind it. If a code alert and a fraud warning land on the same order, the order goes to our high-risk order review queue first, so one person decides on it with both reasons in view. Amazon and Walmart run their own promotion tools with their own rules, so we check those platform by platform in a project rather than treating them like Shopify codes.
Who builds discount code leak alerts?
Ecomsellertool builds workflow automation on your own Shopify store and the systems around it; we have built software on Amazon's seller APIs since 2017 and shipped 50+ tools for 100+ teams. We write the campaign record and the signal table with you first, then build the order counter, the margin math, the alerts and the approved actions. Decisions stay with your team. Send a project brief or read how our workflow automation service works.
The building blocks are work we have shipped, though neither project was a discount alert build:
- Promotion data next to sales. For Seller-Drive we built a promotion view from Amazon's FBA promotion reports, showing the count of ASINs with promotional data and the sales made after the promotion.
- Promotions inside profit. For Beezboard we built a business performance graph that puts promotions next to COGS, Amazon fees, refund cost, net margin and ROI, with COGS mapped to each product.
The alerts can run on Ecomsellertool Growth OS beside your order and margin data.
Get your discount code alerts built
Send us the codes you worry about
Describe the workflow you want automated. We reply with a written plan: scope, timeline and a fixed price.
Frequently asked questions
How do I know if my Shopify discount code was leaked?
Watch three things per code: redemptions per day against what the campaign should produce, orders whose visits came from a coupon or deal site, and buyers who are not in the audience the code was meant for. One of these alone can be innocent. Two together, such as a spike and a coupon-site referrer, usually mean the code is public.
Should I deactivate a leaked discount code right away?
Not always. A leaked code that still leaves a healthy margin may be cheaper to cap or let expire than to break for real customers who were sent it. Work out the margin at risk first. If orders lose money after the discount, or the code was meant for a small group, deactivate it and send the intended group a new unique code.
Can Shopify limit a discount code to one use per customer?
Yes. When you create a code you can limit it to one use per customer, which Shopify tracks by the customer's email address or phone number, and you can set a total number of uses. A customer with a second email address can still use it again, so unique codes are safer for valuable offers.
How many discount codes can a customer stack on one Shopify order?
Up to 5 product or order discount codes and 1 shipping discount code, if the discounts are set to combine. Shopify also applies the best automatic discount or combination when a customer enters codes. Each discount's combination settings decide what can stack, so check them per code.
What happens when I reactivate an expired discount code?
Shopify's help page says a reactivated expired discount becomes Active with no set end date. That means it runs until someone stops it, so set a new end date at once. The workflow's weekly audit flags any active code without an end date for this reason.
Can Shopify Flow deactivate a discount code on its own?
Flow has a Discount code created trigger and a Get discount data action, which can email a weekly summary of active codes. Deactivating a code is a separate Admin API call, discountCodeDeactivate, which needs write access to discounts. In this recipe a person approves that step.
