Daily
Check whether discounts and refunds ate your sales
Each morning you're alerted if discounts and refunds took too big a share of yesterday's sales, with the worst orders listed.
- Runs
- Daily
- Apps
- Shopify
- AI
- Not needed
- Access
- read_orders
Send this to your assistant
Create a ClickRuntime automation: each morning at 8am, check yesterday's Shopify orders and Slack me if discounts plus refunds were over 15% of gross sales, listing the 5 worst orders.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A Shopify store running promotions can feel busy and profitable while the margin quietly disappears. A stacked discount code, a generous automatic discount and a spike in refunds can together remove 30 percent of a day's revenue. The owner looks at gross sales in the admin, sees a healthy number, and does not realize that the net is much lower until the end of the month. A mispriced promotion can drain money for weeks before it is noticed.
Every morning the automation queries yesterday's orders with their discounts and refunds, works out what share of revenue they represent, and sends you an alert if that ratio is above the threshold you set. On normal days it stays quiet. Store owners and finance people use it as a guard on margin during sales and campaigns.
What you get out of it
A bad promotion is stopped quickly
If a discount code is applied far more than expected, the alert shows it the next morning. Ending it after one day costs little, while discovering it after a week can cost thousands.
Discount stacking errors are noticed
Combinations of codes and automatic discounts sometimes give away far more than intended. A high discount ratio is the clearest sign, and an owner can inspect the orders affected. A code stacked on an automatic discount can give away 40 percent, which a gross sales figure hides.
Refund spikes get attention
A sudden rise in refunds can indicate a defective batch or a shipping problem. Seeing the refund share the next day lets you investigate while the cause is still fresh.
Margin is protected during sales
Black Friday and other campaigns produce high volume and high risk. A daily check gives you the chance to adjust offers during the sale, rather than analyzing losses afterward. During a Black Friday weekend, a one-day delay in noticing an over-generous offer can be expensive.
Quiet when things are healthy
Alerts only appear above the threshold, so the owner is not given another daily report to ignore. A message therefore means something to look at. A day with no alert means discounts and refunds stayed under your line, so there is nothing to read.
How it works
What happens, step by step
Every morning, the automation collects yesterday's Shopify orders with their discounts and refunds.
It works out what share of gross sales was lost to discounts and refunds.
If that share is above your limit, it posts an alert to your Slack channel with the worst orders listed.
Before it runs live
- Connect Shopify
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Run it at a different time, more or less often, or only on weekdays
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Slack
- Combine it with other Shopify steps into one automation
Under the hood
The code that runs this automation
from datetime import date, timedelta
from clickruntime import on_trigger, credentials, http, notify
STORE = "your-store.myshopify.com"
def gql(query, variables=None):
resp = http.post(f"https://{STORE}/admin/api/2025-07/graphql.json",
headers={"X-Shopify-Access-Token": credentials.connection("shopify", "store")},
json={"query": query, "variables": variables or {}})
resp.raise_for_status()
return resp.json()["data"]
THRESHOLD = 0.15
QUERY = """query($q: String!) { orders(first: 250, query: $q) { nodes { name
subtotalPriceSet { shopMoney { amount } } totalDiscountsSet { shopMoney { amount } }
totalRefundedSet { shopMoney { amount } } } } }"""
@on_trigger
def run(event):
day = date.today() - timedelta(days=1)
orders = gql(QUERY, {"q": f"created_at:>={day} created_at:<{date.today()}"})["orders"]["nodes"]
amt = lambda o, k: float(o[k]["shopMoney"]["amount"])
leak = lambda o: amt(o, "totalDiscountsSet") + amt(o, "totalRefundedSet")
gross = sum(amt(o, "subtotalPriceSet") + amt(o, "totalDiscountsSet") for o in orders)
lost = sum(leak(o) for o in orders)
ratio = lost / gross if gross else 0
if ratio <= THRESHOLD:
return {"ratio": round(ratio, 3)}
worst = sorted(orders, key=leak, reverse=True)[:5]
notify.slack(f"Discounts + refunds were {ratio:.0%} of gross sales on {day} ({lost:,.2f} of {gross:,.2f})\n" +
"\n".join(f"• {o['name']}: {leak(o):,.2f}" for o in worst), channel="#store")
return {"ratio": round(ratio, 3)}FAQ
Common questions
How is the discount ratio calculated?
What threshold should I choose?
Does it count discounts from every channel?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Get last week's orders as a CSV
Every Monday you get all of last week's orders in one file, with customer, total and status.
See how it worksGet a daily list of abandoned checkouts
Each evening you get today's abandoned checkouts with the customer email, cart value and recovery link, so you can follow up.
See how it worksGet warned when stock runs low
Each morning you see the variants running low, and each one is only flagged once.
See how it worksKeep exploring
Set up “Check whether discounts and refunds ate your sales” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.