A Shopify discount code performance report built with n8n rolls every paid order up by the promo code it used, then logs the result to a Google Sheet and posts a weekly Slack summary. Shopify tells you a code exists, but not whether it earns its keep. This workflow reads the discount data that already sits on each order, counts redemptions, sums the money you gave away, and sums the revenue those orders brought in, so you can tell a code that drives sales from one that just discounts customers who would have bought anyway.
What it does
Once a week the workflow wakes up on a schedule, asks Shopify for every paid order from the last 30 days, and reads the discount_codes field that Shopify attaches to each order. For every code it builds a single row: how many times the code was redeemed, the total discount given, the total revenue of the orders that used it, and the average order value. It writes those rows to a Discount Report tab in Google Sheets and posts a plain Slack summary with the totals and the top five codes by revenue.
The result is a running scoreboard for your promotions. Instead of a vague sense that “the newsletter code does well”, you get numbers: WELCOME10 redeemed 42 times, gave away $310, and brought in $2,140 of revenue at a $51 average order. Line that up next to FLASH20 and it becomes obvious which promotion to repeat and which to retire.
Take a single order for $60 that used the code SPRING15 for $9 off. The workflow adds one to that code’s redemption count, adds $9 to its discount-given total, and adds $60 to its revenue total. Repeat that across every order in the window and each code ends the run with a clean three-number story: how often, how much given, how much earned.
Why it beats the default
Shopify’s built-in Discounts page shows a redemption count and, on some plans, the total discount amount. What it does not show cleanly is the revenue each code pulled in, side by side, in a place you can sort, chart, and keep month over month. Most owners end up exporting orders to a spreadsheet and rebuilding a pivot table by hand every time they want to compare campaigns.
This approach reads the same order data automatically and keeps a permanent, growing history in a sheet you own. Because the report lands in Google Sheets, you can pivot it, chart redemptions over time, or share it with a marketing partner without giving anyone access to your store admin. And because it runs on your own n8n instance, there is no per-seat analytics subscription and no app skimming your order feed. It is also a natural building block in a wider Shopify automation stack, since the same order pull can later feed margin, refund, or restock flows.
What you need
- An n8n instance, either the free self-hosted community edition or any n8n Cloud plan.
- A Shopify store connected to n8n. If you have not done this yet, follow connect Shopify to n8n with the 2026 Dev Dashboard method first. It takes about ten minutes and is the prerequisite for every step below.
- A Google account with a blank spreadsheet that has a tab named
Discount Report. - A Slack workspace and a channel to post the summary in. Prefer email? Swap the final Slack node for a Gmail node and send the same summary text to yourself.
The Shopify connection needs read access to orders. Everything else here uses standard read and append permissions, so the workflow can never change a product, an order, or a customer.
Node-by-node list
Every Monday 8am (Schedule Trigger)
|
Config and date range (Code: build the 30-day created_at_min)
|
Get paid orders (HTTP Request: Shopify Admin API, orders.json)
|
Aggregate by code (Code: roll orders up by discount code)
|
Append to report (Google Sheets: append one row per code)
|
Build summary (Code: reduce to one Slack message)
|
Post summary to Slack (Slack: post the weekly report)
- Every Monday 8am is a Schedule Trigger set to weekly. It is the only trigger and it fires the run.
- Config and date range is a Code node that computes
created_at_minfrom a singlelookbackDaysvalue, so changing the window is a one-line edit. - Get paid orders is an HTTP Request node calling the Shopify Admin API
orders.jsonendpoint, filtered to paid orders inside the window, returning only the fields the report needs. - Aggregate by code is a Code node that walks every order’s
discount_codesarray and builds one clean row per code. - Append to report is a Google Sheets node that appends those rows to the Discount Report tab.
- Build summary is a Code node that reduces all the code rows into a single plain-text summary.
- Post summary to Slack sends that summary to your chosen channel.
Step-by-step build
- Create a new workflow in n8n and add a Schedule Trigger. Set it to weekly, Monday, hour 8. Rename it
Every Monday 8am. - Add a Code node named
Config and date range. Paste the snippet that setslookbackDays = 30and returnscreatedMinas an ISO date. This is the one place you change the reporting window. - Add an HTTP Request node named
Get paid orders. Method GET, URLhttps://YOUR_STORE.myshopify.com/admin/api/2026-04/orders.json. Set authentication to Predefined Credential Type, choose your Shopify access token credential. Turn on Send Query and add:status=any,financial_status=paid,created_at_min={{ $json.createdMin }},limit=250, andfields=id,name,created_at,total_price,discount_codes. - Add a Code node named
Aggregate by code. Paste the aggregation script from the template. It flattens the orders response, walks each order’sdiscount_codesarray, and outputs one item per code with Uses, Discount Given, Revenue With Code, and Avg Order Value. - Add a Google Sheets node named
Append to report. Operation Append, pick your spreadsheet, and select theDiscount Reporttab. Leave mapping on Auto-map so the column headers match the fields the Code node emits. - Add a Code node named
Build summary. Paste the summary script. It totals redemptions, discount given, and revenue, then lists the top five codes by revenue as one message. - Add a Slack node named
Post summary to Slack. Resource Message, Operation Post, select your channel, and set the text to{{ $json.text }}. Save, then toggle the workflow Active.
Common mistakes
- Reading all orders instead of paid ones. Without
financial_status=paid, unpaid and cancelled orders inflate redemption counts. Keep the filter so the report reflects money that actually changed hands. - Expecting automatic discounts to appear. The
discount_codesarray only lists code-based discounts a customer typed or clicked. Automatic discounts with no code will not show up here, which is by design for a code performance report. - Comparing across different windows. If you switch
lookbackDaysbetween runs, the numbers stop being comparable. Pick a window, keep it stable, and let the Date column separate each run in the sheet. - Wrong API version. Use a current Admin API version such as
2026-04in the URL. An old version can drop or rename fields the aggregation script expects. - Assuming one run covers everything. At more than 250 orders in the window, add pagination on the Get paid orders node or shorten the schedule, otherwise the oldest orders in the window are silently left out.
Cost at realistic volume
Everything here runs on free tiers. n8n community edition is free to self-host, and n8n Cloud counts this as one execution per week. Google Sheets is free with any Google account, and appending a handful of rows sits far inside the daily quotas. Slack posting is free on any workspace. The Shopify Admin API calls are free on every plan.
| Store size | Orders per 30 days | Runs per month | Monthly cost |
|---|---|---|---|
| Small | Up to 250 | 4 | $0 |
| Growing | 250 to 1,000 | Switch to weekly with pagination | $0 |
| High volume | 1,000+ | Weekly, paginated | $0 self-hosted |
Ready-to-import template
The full guide above is free to follow. If you would rather skip the build, the downloadable template is the exact seven-node workflow, validated and ready to import, so you only add your credentials and spreadsheet. Prefer it done for you? See our done-for-you setup service.
Instant download · Works on n8n Cloud and self-hosted
FAQ
Where does the discount data come from?
From the orders themselves. Every paid Shopify order carries a discount_codes array listing the code applied and the amount it took off. The workflow reads that field directly, so there is no separate report to export and no third-party app sitting between you and your own order data.
Does it track revenue or just redemptions?
Both. For each code it counts redemptions, sums the discount given, and sums the total order value those redemptions brought in. That lets you see not only which codes are popular but which ones actually drive revenue versus which quietly erode your margin for little return.
How often does it run?
The template ships with a weekly schedule every Monday at 8am, looking back 30 days. Change the Schedule Trigger to daily or monthly, and adjust the lookbackDays value in the Config node to match. Both are plain fields you can edit without touching any other node.
Will it handle a large order volume?
The template pulls up to 250 orders per run, which covers most monthly windows for small and growing stores. For higher volume, add cursor pagination on the Get paid orders node using the page_info parameter, or shorten the schedule to weekly so each run reads fewer orders.
Do I need a paid n8n plan?
No. It runs on the free self-hosted community edition or any n8n Cloud plan. The only accounts you need are Shopify, a Google account for Sheets, and a Slack workspace for the summary. Swap Slack for a Gmail node if you would rather get the report by email.