HomeShopify & E-commerceHow to Build a Shopify Repeat…

How to Build a Shopify Repeat Customer Reward Email With n8n

How to Build a Shopify Repeat Customer Reward Email With n8n










This guide builds a shopify repeat customer reward email n8n workflow that watches every new order, spots the moment a shopper places their third order, generates a unique Shopify discount code through the Admin API, and sends a personal thank-you email with Gmail. No loyalty-app subscription and no manual list-pulling. It takes about 35 minutes to wire up and runs free on self-hosted n8n.

Prefer to skip the setup? Grab the ready-made template below and have it live in under 10 minutes.

What it does

Your repeat buyers are the cheapest revenue you will ever earn, yet most stores only thank a customer once, in the order-confirmation receipt. After that, a shopper can place a second and third order and hear nothing. This workflow fixes that quietly in the background.

Every time an order is created in your Shopify store, n8n receives it, reads how many orders that customer has now placed, and waits for the one that turns them into a three-time buyer. At that point it mints a brand-new discount code just for them and emails it as a thank-you. The shopper feels recognized at the exact moment loyalty is forming, and you never touch a spreadsheet.

It is one piece of a larger toolkit. If you are mapping out your whole store, start with the pillar guide on n8n Shopify automation and slot this reward email in alongside your welcome and post-purchase flows.

Why it beats the default

Shopify Flow can tag a repeat customer, but it cannot generate a personal discount code and write a warm email in the same run without bolting on a third-party app. Dedicated loyalty apps do all of this, but they start around 30 to 50 dollars a month and grow with your order volume, and they own the customer relationship instead of you.

Doing it in n8n keeps three things in your hands:

  • The trigger logic. Reward on the third order, the fifth, or a spend threshold. It is one field, not a pricing tier.
  • The email. It sends from your own Gmail address, so it lands in the primary inbox and reads like a note from a shop owner, not a marketing blast.
  • The cost. One n8n instance runs this and dozens of other store workflows for the price of nothing extra.

What you need

  • An n8n instance, cloud or self-hosted (the workflow is identical on both).
  • A Shopify custom app access token with read_orders, write_price_rules, and write_discounts scopes.
  • One price rule created in Shopify admin ahead of time, for example “Repeat customer 15% off”. You will copy its numeric ID.
  • A Gmail account connected to n8n for sending the reward email.

Estimated build time: about 35 minutes from scratch, or under 10 minutes with the template.

Node-by-node list

Five nodes, in a straight line with one branch:

┌──────────────────────────────────────────────────────────────┐
│  SHOPIFY REPEAT CUSTOMER REWARD EMAIL                         │
│                                                              │
│  [Shopify Trigger] → [Edit Fields] → [IF orders = 3]         │
│                                          │ true              │
│                                          ▼                   │
│                              [HTTP: create discount code]    │
│                                          │                   │
│                                          ▼                   │
│                                   [Gmail: send reward]       │
└──────────────────────────────────────────────────────────────┘
  
  1. Shopify Trigger (n8n-nodes-base.shopifyTrigger) on the orders/create topic.
  2. Edit Fields (n8n-nodes-base.set, v3.4) to extract the customer details.
  3. IF (n8n-nodes-base.if, v2.2) to continue only on the third order.
  4. HTTP Request (n8n-nodes-base.httpRequest, v4.2) to create the discount code.
  5. Gmail (n8n-nodes-base.gmail, v2.1) to send the thank-you email.

Step-by-step build

1 Shopify Trigger

Add a Shopify Trigger node and connect your Shopify credential. Set the topic to orders/create. n8n registers the webhook in your store automatically, so a new order now fires the workflow within seconds. The node hands the full order object to the next step. The slice you care about lives under customer:

{
  "order_number": 1042,
  "customer": {
    "id": 6072830012345,
    "first_name": "Emily",
    "email": "emily.rodriguez@gmail.com",
    "orders_count": 3,
    "total_spent": "284.00"
  }
}
💡

Tip: orders_count already includes the order that just triggered the webhook, so a shopper’s third purchase reads as 3. That is the number the IF node checks.

2 Edit Fields

Add an Edit Fields node (the Set node, version 3.4) to pull the four values you need into clean, predictable names. Add these assignments:

Name Type Value
customerEmail String ={{ $json.customer.email }}
firstName String ={{ $json.customer.first_name }}
ordersCount Number ={{ $json.customer.orders_count }}
orderNumber Number ={{ $json.order_number }}

After this node, every downstream step reads $json.customerEmail instead of digging back into the raw payload.

3 IF — is this the third order?

Add an IF node. Create one condition comparing numbers:

  • Left value: ={{ $json.ordersCount }}
  • Operator: Number → Equals
  • Right value: 3

Wire only the true output forward. Every order still flows in, but only the one that makes someone a three-time buyer continues. The false branch is left empty, which silently ignores first orders, second orders, and everything past the third.

📌

Using Equals 3 rather than greater than or equal to 3 is deliberate. Equals fires the reward exactly once. A greater-or-equal check would re-send a code on the fourth, fifth, and every later order.

4 HTTP Request — create the discount code

Add an HTTP Request node (version 4.2). This is where the reward becomes real. You create a unique code under the price rule you set up earlier.

  1. Method: POST
  2. URL: https://YOUR_STORE.myshopify.com/admin/api/2026-04/price_rules/YOUR_PRICE_RULE_ID/discount_codes.json
  3. Authentication: Predefined Credential Type → Shopify API, using the same credential as the trigger.
  4. Body: set Body Content Type to JSON and paste the JSON body below.
{
  "discount_code": {
    "code": "LOYAL15-{{ $json.orderNumber }}"
  }
}

Because the code is built from the order number, every reward is unique and easy to trace back to the order that earned it. Shopify returns the created code:

{
  "discount_code": {
    "id": 13294857263,
    "price_rule_id": 9876543210,
    "code": "LOYAL15-1042"
  }
}
💡

Tip: The price rule decides the actual discount (percentage, usage limits, expiry). Build it once in Discounts → no, use the price rule via the API or the admin, set “Limit to one use per customer”, and the workflow simply attaches fresh codes to it.

5 Gmail — send the reward email

Add a Gmail node (version 2.1), operation Send. Connect your Gmail credential and fill in:

  • To: ={{ $('Edit Fields').item.json.customerEmail }}
  • Subject: A thank-you gift for your third order
  • Email type: HTML
  • Message:
Hi {{ $('Edit Fields').item.json.firstName }},

Three orders in. That means a lot to a small shop, so here is
15% off your next one, just for you:

  {{ $json.discount_code.code }}

Apply it at checkout. Thanks for keeping us in your corner.

Save the workflow and toggle it active. The next customer to reach their third order gets a personal code in their inbox minutes later.

Common mistakes

  • Using greater-or-equal in the IF. It re-rewards the same shopper on every order past the third. Use exact Equals, or a modulo expression like ={{ $json.ordersCount % 5 === 0 }} for an every-fifth-order reward.
  • Missing the write scopes. A token with only read_orders returns a 403 at the HTTP node. Add write_price_rules and write_discounts to the custom app.
  • Sending a plain text body as HTML. If you choose HTML email type, wrap the message in real markup so line breaks render. Or switch the type to Text for the simple version above.
  • Forgetting the price rule limit. Without “one use per customer” on the price rule, a forwarded code can be redeemed by anyone. Set the usage limit on the rule, not the code.
  • Testing with an account that has imported history. If you migrated orders, orders_count may not start at 1. Place a test order and read the real value before trusting the number 3.

Cost at realistic volume

Take a store doing 600 orders a month. Repeat-buyer rates vary, but suppose 40 customers cross into their third order in a given month. That is 40 discount-code API calls and 40 Gmail sends.

Component Usage at this volume Cost
n8n (self-hosted) 600 trigger runs, 40 full runs $0
Shopify Admin API 40 discount-code calls $0 (within rate limits)
Gmail 40 emails (limit ~500/day) $0

The whole thing runs for nothing beyond the server you already pay for. Compare that to a loyalty app at 39 dollars a month and the workflow pays for itself the day you turn it on. On n8n Cloud, these executions sit comfortably inside the entry plan.

🚀 Get the Repeat Customer Reward Email template

The guide above is free to follow. If you would rather skip the build, download the ready-to-import workflow, then just add your credentials. Prefer it installed and tuned for you? See our done-for-you services.

Download the template ($14) →

Instant download · Works on n8n Cloud and self-hosted

FAQ

Does this send a reward on every future order?

No. The IF node checks for an exact orders count of 3, so the reward fires once when the customer becomes a three-time buyer. Change the number, or use a modulo expression, if you want a reward on every fifth order instead.

Do I need a paid loyalty app for this?

No. The workflow uses the native Shopify Admin API to mint discount codes and Gmail to deliver them, so there is no monthly loyalty-app fee. You only need an n8n instance, which runs free when self-hosted and cheaply on Cloud.

Where does the discount code come from?

You create one reusable price rule in Shopify admin, for example fifteen percent off. The workflow then generates a fresh, single-customer code under that price rule on each qualifying order, so every reward code is unique and trackable.

Will the customer count be off by one?

The orders_count on the customer object includes the order that just triggered the webhook, so a third purchase reads as 3. If your store imported historical orders, test with a real account first and adjust the IF value to match what you actually see.

Can I reward by total spend instead of order count?

Yes. The customer object also carries total_spent. Map that field in the Edit Fields node and change the IF condition to a spend threshold, such as greater than 300 dollars, to reward your highest-value buyers instead of counting orders.

Related guides

n8n
Shopify
Gmail
loyalty
automation