HomeShopify & E-commerceShopify abandoned checkout email sequence with…

Shopify abandoned checkout email sequence with n8n and Gmail

Shopify abandoned checkout email sequence with n8n and Gmail

New to n8n? Start with our step-by-step setup guide, then come back to build this workflow.










TL;DR: This guide builds a Shopify abandoned checkout email sequence in n8n using Gmail and Google Sheets. A schedule trigger pulls open checkouts from the Shopify Admin API every hour, works out how long each one has been sitting, and sends a timed three-email recovery sequence: a gentle nudge, then a discount, then a last call. Every send is logged to a sheet so nobody gets the same email twice. No paid recovery app, no per-message fees.

Roughly seven in ten shoppers who reach checkout never finish. They get distracted, the shipping number surprises them, or they meant to come back and forgot. Shopify’s built-in recovery email helps a little, but it is one message you barely control. A proper sequence does better, and you do not need a $40-a-month app to run one. If you already self-host n8n, you can build this in an afternoon and own the whole thing.

Prefer to skip the setup? Grab the ready-made template and be recovering carts in under 15 minutes.

This is part of our n8n Shopify automation series, and it pairs well with the welcome email and daily sales report flows linked at the end.

What it does

The workflow watches your store for abandoned checkouts and emails the shopper on a schedule until they either buy or run out of the sequence. Here is what a shopper experiences:

  1. About an hour after they leave, they get a short reminder that their items are still waiting, with a one-click link back to their cart.
  2. If they still have not bought after a day, a second email arrives with a small discount code to tip them over.
  3. Three days in, a final email tells them the offer is about to expire. After that, the workflow leaves them alone.

Behind the scenes, n8n keeps a simple Google Sheet that records which stage each checkout has received. That sheet is the memory of the system. It stops repeat sends and gives you a plain record of who was contacted and when.

Why it beats the default

Shopify’s native abandoned checkout email is fine as a starting point, but it has real limits. You get one email, sent at a fixed delay, with templating that fights you the moment you want anything custom. There is no second touch and no easy way to add an escalating offer.

The marketplace answer is to install a recovery app. Those work, but they bill monthly and often charge again per message or per recovered order. For a store doing modest volume, that is money leaving every month for something you can run yourself.

Building it in n8n flips the trade. You write every line of every email, you decide the exact timing, and you control when and how big the discount gets. The cost is your n8n instance, which you are likely already paying for, plus a Gmail account you already have. Your customer data stays on your own server and in your own sheet rather than inside a third party tool.

What you’ll need

  • A running n8n instance, cloud or self-hosted, on version 1.0 or later.
  • A Shopify store on any paid plan, plus a custom app with read access to checkouts.
  • A Gmail or Google Workspace account to send the recovery emails from.
  • A Google Sheet to log sends, with one tab and a header row.
  • Optional: a Shopify discount code you create once and reference in stages 2 and 3.

Build time is around 45 minutes from scratch, or under 15 minutes if you import the template and just plug in your credentials.

How the workflow is built, node by node

The whole thing is one linear workflow with a short branch for the email stage. Here is the shape of it before we go through each node.

┌───────────────────────────────────────────────────────────────┐
│  SHOPIFY ABANDONED CHECKOUT RECOVERY                          │
│                                                              │
│  [Schedule]→[Get Checkouts]→[Decide Stage]→[Read Log]        │
│                                    ↓                         │
│                            [Select Who To Email]            │
│                                    ↓                         │
│                              [Build Email]                  │
│                                    ↓                         │
│                          [Send Gmail]→[Log To Sheet]        │
└──────────────────────────────────────────────────────────────┘
  

The nodes, in order, are a schedule trigger, an HTTP request to Shopify, a code node that decides the stage, a Google Sheets read, a filter that picks who is due, a set node that writes the email, the Gmail send, and a final Google Sheets append. Eight nodes, no loops to manage by hand.

Step-by-step build

1 Schedule trigger

Add a Schedule Trigger and set it to run every hour. Hourly is a good balance: it catches new abandonments quickly without hammering the Shopify API. If your store is quiet overnight you can narrow the active hours later.

2 Get abandoned checkouts (HTTP request)

Use an HTTP Request node to call the Shopify abandoned checkouts endpoint. Set the method to GET and the URL to your store’s admin API, authenticated with your custom app token.

GET https://YOUR-STORE.myshopify.com/admin/api/2024-01/checkouts.json?limit=100
Header: X-Shopify-Access-Token: YOUR_SHOPIFY_ACCESS_TOKEN

This returns open checkouts that were never turned into orders. Each item carries the shopper’s email, line items, total, and the abandoned_checkout_url that links them straight back to their cart.

💡

Tip: the abandoned_checkout_url is the magic field. It rebuilds the exact cart in one click, so always use it as your button link instead of sending people to a generic store page.

3 Decide the stage (code node)

Add a Code node that loops over the checkouts and works out how many hours have passed since created_at. Map that age to a stage: stage 1 at roughly one hour, stage 2 at about 24 hours, stage 3 at about 72 hours. Anything older than the last stage gets dropped.

const now = Date.now();
return items
  .map(i => {
    const c = i.json;
    const hours = (now - new Date(c.created_at).getTime()) / 3600000;
    let stage = 0;
    if (hours >= 72) stage = 3;
    else if (hours >= 24) stage = 2;
    else if (hours >= 1) stage = 1;
    return { json: { id: c.id, email: c.email, total: c.total_price,
      url: c.abandoned_checkout_url, hours: Math.round(hours), stage } };
  })
  .filter(i => i.json.stage > 0 && i.json.email);

4 Read the sent log (Google Sheets)

Add a Google Sheets node set to read your log tab. Pull back the existing rows so the next node can check what has already gone out. Each row holds a checkout ID and the highest stage that checkout has received.

5 Select who to email (filter)

Add a Code or Filter node that compares each due checkout against the log. Keep a checkout only if its due stage is higher than the last stage logged for that ID. This is what guarantees a shopper moves 1 to 2 to 3 and never gets the same message twice, even though the workflow runs every hour.

6 Build the email (set node)

Add a Set node that writes three fields based on the stage: a subject, an HTML body, and a discount line. Stage 1 is a plain reminder with no discount. Stage 2 adds a code like COMEBACK10. Stage 3 reuses the code and adds urgency about it expiring. Reference the cart link with an expression so every email points to the right checkout.

📌

Note: create the discount code once inside Shopify under Discounts, then just reference its name in the email text. The workflow does not need to create codes on the fly.

7 Send through Gmail

Add a Gmail node, set the operation to send a message, and map the recipient to the checkout email, the subject and body to the fields from the previous node. Send from your store inbox so replies land somewhere you read.

8 Log to Google Sheets

Finish with a Google Sheets append node that writes the checkout ID, the stage just sent, the shopper email and a timestamp. This closes the loop: the next hourly run reads this row and knows not to repeat the stage.

The data the log stores

The Google Sheet is deliberately small. One row per send, with these columns.

Column Type Example Description
checkout_id Number 29384756 Shopify checkout ID, used to match against new runs
email Text emily.rodriguez@gmail.com Shopper email the message was sent to
stage Number 2 Highest stage sent for this checkout (1, 2 or 3)
total Text $148.00 Cart value, handy for spotting high-value recoveries
sent_at Text March 14, 2026 14:30 Timestamp of the send

Common mistakes

The first one is sending too fast or too often. If your schedule runs every five minutes and your stage logic is loose, a shopper can get two emails in a row. Keep the trigger hourly and let the log node do its job.

The second is skipping the dedupe check. Without reading the sent log before you email, every run that finds the same checkout will email it again. The log read in step 4 and the filter in step 5 are not optional, they are the safety mechanism.

The third is using the wrong link. People paste a link to the homepage or a collection, which forces the shopper to rebuild their cart by hand. Always use abandoned_checkout_url so they land back exactly where they left off.

The last one is forgetting the API version. Shopify retires old API versions on a schedule, so a URL that works today can return errors next year. Use a current version like 2024-01 and update it once a year when you review the workflow.

What it costs at realistic volume

Say your store gets 60 abandoned checkouts a week. Most get one or two emails, a few get all three, so call it about 130 emails a week, or roughly 560 a month.

Setup Monthly cost Notes
n8n + Gmail (this workflow) $0 extra Runs on your existing n8n and a normal Gmail account, well under the daily send limit
Typical cart recovery app $20 to $50 Flat monthly fee, sometimes plus a cut of recovered revenue
Email platform with automation $15 to $30 Priced by contact count, climbs as your list grows

At 560 emails a month you are comfortably inside Gmail’s free sending limits, so the running cost of this approach is whatever you already pay for n8n. If you grow past a few thousand emails a month, swap the Gmail node for an SMTP provider and keep the rest of the workflow as is.

Get the abandoned checkout recovery template

You now know how the sequence works. If you would rather not wire up eight nodes by hand, the ready-made template imports in minutes and ships with the Google Sheet layout, all three email drafts, and a setup guide for the Shopify and Gmail credentials.

Get the template

Instant download. Works on n8n Cloud and self-hosted. Want it installed for you? See our done-for-you n8n setup service.

Frequently asked questions

Does this work on Shopify Basic and the free trial plan?

Yes. The abandoned checkouts endpoint is available on every paid Shopify plan, including Basic. You only need a custom app with read access to checkouts. The free trial works for testing, but you need a live paid plan to keep the API running once the trial ends.

Will Gmail block me for sending recovery emails?

A standard Gmail account sends up to 500 messages a day, and Google Workspace allows 2,000. Most small stores stay well under that. Send from your own store address, keep the volume reasonable, and you will be fine. High-volume stores should move to a dedicated SMTP provider.

How is this different from Shopify’s built-in abandoned checkout email?

Shopify sends one fixed email and gives you little control. This workflow sends a timed three-email sequence, lets you write every word, adds escalating discount codes, and logs results to a sheet you own. You also avoid paying a recovery app every month.

Can I add another reminder channel later?

This template is email only by design, using Gmail. If you want a second channel you can add Telegram for internal alerts to your own team, for example a ping when a high-value cart is abandoned. The customer-facing recovery stays on email.

What happens if the shopper completes the order after email one?

The abandoned checkouts endpoint only returns checkouts that were never converted to an order. Once the shopper pays, that checkout drops off the list, so the next run will not send stages 2 or 3. No extra logic is needed to stop chasing a paid customer.

Related guides

n8n
Shopify
Gmail
Google Sheets
cart recovery
automation