Skip to content

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.

Paste it into your assistant. It tells you what it will send or change before it runs live.

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

  1. Every morning, the automation collects yesterday's Shopify orders with their discounts and refunds.

  2. It works out what share of gross sales was lost to discounts and refunds.

  3. 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

RunsDaily
Check whether discounts and refunds ate your salestoday, 9:00Succeeded
Slack · #storeDiscounts + refunds were 21% of gross sales on 2026-10-18 (412.00 of 1,962.00) • #1061: 120.00

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • 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

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
daily_discount_profit_leak_check.pyexample
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?
Total discounts on yesterday's orders divided by gross sales for those orders, with refunds treated the same way. You choose a threshold, such as 25 percent, and whether to combine discounts and refunds or check them separately.
What threshold should I choose?
It depends on your margins. A store with 50 percent gross margin might alert at 20 percent discounts, while one with thin margins might choose 10. Look at a few normal days first, then set the line above them.
Does it count discounts from every channel?
It counts orders recorded in Shopify across the online store, POS and other connected sales channels. Discounts applied in outside tools before the order exists will not appear. Draft orders and wholesale channels are included only when they create normal Shopify orders with discount data.
What permissions does it need?
read_orders. Nothing else in your accounts is used.
Does it need AI?
No. It runs without AI, so it doesn't use your plan's AI allowance.
How many runs does it use?
One run each time it runs (daily). Checks that find nothing to do and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

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.