Back to Playbooks

A Gentle Add‑to‑Cart Recovery Flow Your Shoppers Actually Appreciate

Free

A detailed Spreeflo journey for recovering add-to-cart abandoners with gentle, behavior-based messaging. It shows how to trigger on meaningful events, pace delays, gate against checkout flows, and reserve discounts for high-value carts you can measure.

Industry

Niche

Pattern

Loading sequence...

The CartWizard team knew their merchants had a cart problem. The Shopify dashboards looked healthy, the checkout-abandonment flows were tuned, yet one number kept nagging: thousands of “Add to cart” events a week that never even reached checkout.

No payment intent to recover. No abandoned checkout URL to key off. Just shoppers casually adding items, getting distracted, and disappearing.

If you build e‑commerce apps, you’ve seen the same shape in your own analytics: install rates look good, merchants are happy with your core feature set, but there’s obvious money left on the table between “added to cart” and “started checkout.”

The sequence at the top of this page is the whole journey, end to end. It’s a Spreeflo journey built specifically for that gap: a light‑touch, add‑to‑cart abandonment flow you can run for your own storefront or bake into your app’s offering. It treats add‑to‑cart as its own behaviour, not just a weak version of checkout abandonment.

This article walks through that journey step by step: why each node is where it is, how to keep messaging gentle, and how to measure whether the flow is actually worth the discounts you hand out.

Why “added to cart” deserves its own journey

Most merchants (and a lot of apps that serve them) conflate two very different behaviours:

  • Shoppers who add an item to cart and wander off

  • Shoppers who start checkout and then bail

Those are not the same people.

“Added to cart” is a softer signal. It includes:

  • People idly building wishlists

  • Shoppers comparing prices with another tab

  • Mobile users testing shipping or tax estimates

If you drop your full checkout‑abandonment sequence on everyone who casually added something, you over‑message, over‑discount, and train otherwise happy buyers to wait for coupons.

That’s the lifetime‑value leak pattern here:

  • No follow‑up: you leave easy revenue on the floor.

  • Aggressive follow‑up: you get revenue, but margin erodes and engagement suffers.

The point of this journey is to thread the middle: capture enough detail on each shopper to talk to them like a person, then send one or two thoughtful nudges instead of a hard‑sell series.

What this journey is designed to do

In Spreeflo, this is a behaviour‑driven journey, not a one‑off campaign. It runs continuously in the background, firing whenever your app or storefront sends an add_to_cart event.

At a high level, the journey does six things:

  1. Listens for a meaningful add_to_cart event from your app.

  2. Waits a few hours so natural checkouts can happen on their own.

  3. Checks whether the shopper has already started checkout or purchased.

  4. Sends a single, personalised reminder email if they haven’t.

  5. Optionally sends a second, incentive‑based email for high‑value carts only.

  6. Tags and updates contacts so you can measure recovery vs. discount cost later.

You build and edit that visually with the campaigns and journeys builder. Let’s go node by node.

Step 1: Trigger on every meaningful add_to_cart event

The journey starts with a Custom Event trigger configured for your add_to_cart event.

Behind the scenes, your app or storefront calls Spreeflo.track('add_to_cart', eventData, attributes) either via the JavaScript SDK or the Spreeflo API. The important bit is the payload:

  • The event name: add_to_cart

  • Key properties: things like cart_value, currency, product_id, category

  • Optional contact attributes: last_cart_value, last_cart_product_name, etc. (set via Spreeflo.identify so they’re stored on the contact record)

In the trigger:

  • Event name: add_to_cart

  • Property conditions: only fire when it’s worth bothering the shopper. Two common examples:

  • cart_value greater than or equal to a threshold (say, $20)

  • currency is one you actually ship to

You also want Re-enrollment set to true. Add‑to‑cart is a repeat behaviour; if a shopper abandons a cart in March and again in May, they should be eligible both times. Spreeflo’s mid‑journey lock prevents duplicates while they’re already inside the journey, so you don’t need to worry about parallel runs.

Why this matters for your app business:

  • You’re capturing specific behaviour, not vague intent.

  • You’re building a richer contact profile every time this fires, so later emails can speak to this shopper’s history, not some generic persona.

That’s brand message 1 in practice: you’re literally accumulating the details you’ll use to talk to each contact uniquely.

Step 2: Give shoppers a few hours to act

Right after the trigger, the journey hits a Time Delay node:

  • Delay: 4 hours

  • Unit: Hours

That four‑hour buffer does a few quiet but important things:

  • Gives impulsive buyers time to check out on their own.

  • Avoids the creepy “you added this 90 seconds ago” feeling.

  • Lets your separate checkout‑abandonment journey (triggered on checkout_started) take over if intent intensifies.

You could make this delay 2 hours or 8 hours depending on your product, but resist the urge to go shorter. Add‑to‑cart is lightweight behaviour; this flow only earns its place if it feels respectful, not reactive.

Step 3: Exclude people who bought or started checkout

After the delay, the sequence reaches an If/Else node. This is the guardrail that keeps your add‑to‑cart journey from colliding with your heavier checkout recovery or post‑purchase flows.

The condition uses Spreeflo’s segment builder:

Group operator: AND

  • Rule 1: Custom event checkout_started with operator HAS_NOT_TRIGGERED in the last 1 day

  • Rule 2: Custom event purchase with operator HAS_NOT_TRIGGERED in the last 1 day

Interpretation:

  • “Send down the ‘Yes’ branch only if this contact has not started checkout and not completed a purchase in the last day.”

Branches:

  • Then (still pre‑checkout, not purchased): continue the recovery sequence.

  • Else (already in checkout or has purchased): skip all shopper‑facing messages and go straight to clean‑up (for example, remove temporary tags, then exit).

This is where many merchants leak goodwill. Without this gate, a shopper could:

  • Start checkout, trigger your main abandonment flow.

  • Also be in this add‑to‑cart sequence from earlier.

  • Receive two different “You left something behind” emails, often with different discounts.

For a small app team, that’s a support headache and a churn trigger. One clean If/Else condition solves it.

Step 4: Send a single, specific reminder email

Contacts who pass the guardrail hit the first Send Email node.

Configuration basics:

  • Send only once: On. A shopper should never receive this exact email twice, even if they re‑enter the journey months later.

  • Content: built in the visual email builder or from a saved template.

What goes in this email:

  • A short subject that assumes curiosity, not urgency.

  • A reminder of what’s in the cart, using the attributes you set on the contact when the event fired (for example, last_cart_product_name).

  • Light social proof or a quick “this is why people buy this” paragraph.

  • A single, obvious call‑to‑action back to the cart.

What does not go in this email:

  • A discount by default.

  • A long story.

  • Threatening urgency (“This is your last chance!”) when they only added something once.

You can use Spreeflo’s AI‑powered copy tools and personalize with AI variables to generate variants that reference those contact attributes:

  • New vs. returning buyers.

  • Category of the product they added.

  • Geography‑specific language or shipping reassurance.

The point is to prove you actually saw what they were doing, without jumping straight to a coupon.

Step 5: Wait a day, then decide who deserves a second nudge

From the first email, the journey goes to another Time Delay:

  • Delay: 1 day

That keeps your pacing sane. Even if the shopper ignores the first email, a one‑day gap respects their inbox.

After that delay, we use a second If/Else node to make a simple judgment call: is this cart valuable enough, and still unpurchased, to justify another touch?

Condition (again using the segment builder):

Group operator: AND

  • Rule 1: Custom event purchase with operator HAS_NOT_TRIGGERED in the last 3 days

  • Rule 2: Custom event add_to_cart with:

  • frequency operator AT_LEAST 1 time in the last 3 days

  • property filter where cart_value is greater than a threshold (say, $100)

You might expand this with extra rules:

  • Exclude contacts with a “discount‑sensitive” tag if you don’t want to train them.

  • Include only certain product categories where margin supports incentives.

Branches:

  • Then (high‑value, still unpurchased): eligible for a second, incentive‑based email.

  • Else: go to clean‑up and exit quietly.

This is where you protect your discount cost ratio. You’re reserving discounts for the subset of shoppers whose potential order value justifies the margin hit.

From your app’s perspective, this is also where you turn analytics into a product decision:

  • If most carts are low value, you might skip this second branch entirely.

  • If merchants often see very high cart values, you could expose this threshold as a setting in your UI and call Spreeflo’s API behind the scenes.

Step 6: Send a restrained incentive (for high‑value carts only)

Contacts who pass the second If/Else hit the final Send Email node.

Configuration:

  • Send only once: On.

  • Content: a second template, often with a slightly stronger subject line.

What changes in this email:

  • You introduce a modest incentive:

  • Free shipping

  • A small fixed discount

  • A bonus add‑on instead of pure price‑cut

  • You frame it as help, not desperation:

  • “If shipping was the blocker, here’s free shipping for the next 24 hours.”

The mechanics around the incentive are up to your stack:

  • Your app or store backend can generate a discount code and sync it to a last_cart_discount_code attribute on the contact via the API.

  • The email template simply merges that attribute into the call‑to‑action button.

Immediately after this second email, the high‑value branch usually adds:

  • An Add Tag node, tagging contacts as received_add_to_cart_discount. This lets you:

  • Avoid including them in similar flows again too soon.

  • Build segments later to compare behaviour of discount‑exposed vs. non‑exposed shoppers.

  • From here, both branches (those who got the second email and those who didn’t) feed into a Merge node that leads to a shared clean‑up step.

Step 7: Clean up state so future journeys stay clean

The last action node in the journey handles clean‑up:

  • Remove Tag: clear any temporary intent tags like in_add_to_cart_flow.

  • Optional Add Tag: completed_add_to_cart_sequence.

Those tags may feel like bookkeeping, but they give you important control later:

  • You can exclude completed_add_to_cart_sequence from future aggressive win‑back flows.

  • You can create a reusable “was ever in this flow” condition without re‑creating event logic each time.

This is the quiet systems work that helps founder‑led teams win on leverage. You build the graph once; the tags and attributes keep it behaving predictably as volumes grow.

Re-enrollment: how often should the same person see this?

Back at the trigger, we turned Re-enrollment on for the add_to_cart event. That’s deliberate.

Spreeflo’s rule is journey‑scoped:

  • If re‑enrollment is off, a contact who has completed the journey once will never enter again via this or any other trigger in the same journey.

  • If it’s on, they can re‑enter every time the condition is met, as long as they’re not currently mid‑journey.

For add‑to‑cart, re‑enrollment should be on. People shop multiple times. You want the same polite treatment each time they build up a meaningful cart and wander away.

If you’re worried about over‑messaging true super‑fans, there are two extra safety valves you can add with If/Else conditions right after the trigger:

  • Skip the journey if a contact has the tag received_add_to_cart_discount.

  • Skip if a last_cart_discount_sent_at timestamp attribute is within the last 14 or 30 days (that attribute gets updated by an Update Contact Attribute node when you send the second email).

That way, even though re‑enrollment is on, heavy incentive offers stay rare for each person.

How to measure whether this flow earns its keep

The three metrics to watch are:

  1. Add‑to‑cart recovery rate

    At a simple level:

    Segment A: contacts who triggered add_to_cart at least once in the last 7 days.
    Segment B: contacts who are members of Segment A and triggered purchase at least once in the last 7 days.

    Recovery rate = |B| ÷ |A|.

    If you want to isolate the impact of this journey, filter Segment B to contacts who also have the tag completed_add_to_cart_sequence.

  2. Order rate from this flow

    Using the same tags, you can create a segment:

    “Completed this add‑to‑cart journey AND purchased in the last 7 days.”

    Compare its size over time to the total number of contacts who entered the journey in that window. You’ll see whether tweaks to copy, timing, or thresholds move the needle.

  3. Discount cost ratio

    For the second email, you care about:

    How many people received a discount (received_add_to_cart_discount tag).
    How many of those placed an order afterwards (custom event purchase with a filter for discount_applied true, if you track that in event properties).

    From there, it’s spreadsheet work: total discount dollars granted vs. incremental revenue from recovered orders. Because Spreeflo makes both events and tags first‑class in the web tracking and analytics tools, the data you need is already in your account.

The big strategic point: you’re no longer guessing. You can tune delay times, thresholds, and incentive levels with actual numbers instead of gut feel.

Why this pattern belongs in every e‑commerce app’s toolkit

As an app developer, your leverage isn’t another setting in your UI. It’s the outcomes your product quietly delivers for every merchant who installs it.

A thoughtful add‑to‑cart abandonment journey is one of those outcomes:

  • It catches a leak most merchants ignore.

  • It respects shoppers’ intent instead of blasting everyone with coupon spam.

  • It uses rich behavioural data to talk to each person like a human.

Spreeflo exists for exactly this class of problem. You use the segment builder to define who should hear from you, the email builder to say something worth hearing, and the journeys editor to glue it together once so it runs forever.

Build this add‑to‑cart sequence, wire your add_to_cart and purchase events into it, and let it run for a month. If you’re anything like CartWizard’s merchants, you’ll see a meaningful uptick in recovered orders with only two carefully chosen emails.

That’s what “capture detail on every customer so you can speak to each uniquely” looks like when it’s wired into revenue, not just into a dashboard.