Back to Playbooks

When Active Users Go Dark: A 4‑Touch Win‑Back Journey For Your Shopify App

Free

A detailed, node-by-node Spreeflo journey for winning back previously active Shopify app users who stop engaging, using segment-based triggers, conditional logic, and a four-touch email plus internal alert sequence to recover usage and MRR.

Industry

Niche

Pattern

Loading sequence...

The chart looked fine until you switched the view.

Installs were steady. Churn wasn’t spiking. But when Lena, co‑founder of CartWizard (a $98k MRR Shopify app), pulled a cohort of “previously active” stores, the real problem showed up: merchants who had been sending recovery campaigns every week… simply stopped logging in.

No rage‑quit uninstall. No angry support ticket. Just silence.

Those merchants sit in that awkward middle ground: not quite churned, but not getting value either. That’s where most e‑commerce apps leak lifetime value.

The sequence at the top of this page is the whole journey, end to end. It’s the playbook CartWizard now uses to catch those “went quiet” accounts and run a targeted, four‑touch win‑back. In this article, we’ll walk through that journey node by node, why it’s built this way, and how to adapt it to your own Shopify or e‑commerce app.

Why inactive customers deserve their own playbook

Cold leads are one thing. They never really got started, so your message is aspirational: here’s what you could do with our app.

Inactive customers are different. They were active. They saw value. They integrated you into their workflow, then something changed:

  • A new team member joined and didn’t know how to use your app.

  • Their store volume dipped and your app felt “optional.”

  • They hit a confusing edge case and quietly gave up.

Treating them like cold prospects wastes that history. Worse, ignoring them creates a silent churn pipeline: they drift from “active” to “barely using” to “uninstall” without a single intelligent nudge.

This is exactly the kind of lifecycle leak that kills SaaS LTV. The good news: it’s also where a lean, founder‑led team can win. If you can capture enough detail about how each store uses your app, you can speak directly to their version of “went quiet” and automate smart win‑back journeys that run without you hovering over a dashboard.

That’s what this flow is for.

How the win‑back journey works at a glance

Before we zoom into each node, here’s the big picture of the journey you see above:

  • It’s a Journey (not a Campaign) built from the campaigns and journeys view, because it needs to run continuously over time.

  • The primary trigger is a Leave Segment event: when a contact leaves your “Active users” segment, they enter this journey.

  • Immediately, we flag them as at‑risk, route high‑value accounts to an internal alert, then send a four‑touch email series spaced over several weeks.

  • Between each touch we check for reactivation. If they become active again, we tag that outcome, update attributes, and stop sending further win‑back emails.

  • At the end, contacts who never re‑engage are marked as “win‑back exhausted,” so you can treat them differently going forward.

The best channels for this pattern are email plus internal notifications: email to nudge the merchant, internal email so a founder or CSM can decide whether to step in manually for big accounts.

Now let’s build it from the ground up.

Step 1: Define “Active users” like an engineer

Everything hangs off the “Active users” segment. Get this wrong and your win‑back journey either never fires, or fires on the wrong people.

In Spreeflo, you define that segment with the segment builder. For a Shopify or e‑commerce app, a good starting definition might be:

  • Contact is tagged with customer

  • AND Subscription status (a custom attribute you sync in) is active

  • AND Custom event feature_used triggered at least 3 times in the last 30 days
    - with property feature_name is one of your core value features (e.g. recovery_campaign_sent, reports_viewed)

You send those custom events from your app backend or frontend via the Spreeflo API. The more specific you are here, the more accurate your “this person was genuinely active” flag becomes.

Now the key idea for the journey:

  • You do not trigger when someone joins this segment.

  • You trigger when someone leaves it.

That’s the moment they go from “healthy” to “quiet.”

Step 2: Trigger on “Leave Segment: Active users”

The first node in the sequence is a Leave Segment trigger:

  • Trigger type: Leave Segment

  • Segment: Active users (the one you just defined)

  • Re-enrollment: On

With re‑enrollment on, a contact can enter this journey every time they fall out of “Active users,” as long as they’re not already mid‑journey. That matters if a merchant re‑engages today, goes quiet again six months from now, and you still want them in your win‑back logic.

Later, we’ll make sure they don’t get the exact same four emails every single time; Re-enrollment just controls whether the journey is allowed to start again.

This trigger is cheap to maintain. Any time you improve your “Active users” definition in the segment builder, this win‑back logic automatically stays in sync.

Step 3: Flag risk and route high‑value accounts

The moment someone leaves “Active users,” you want two things to happen:

  1. Mark their lifecycle state on the contact record.

  2. Decide whether this account deserves human attention.

You do that with a short sequence right after the trigger.

  1. Update Contact Attribute
    - Attribute: lifecycle_stage (custom TEXT attribute)
    - Update type: Update
    - Value: at-risk

    This writes a static literal to every contact that hits this step. You can reuse lifecycle_stage everywhere: dashboards in your own app, other journeys, or reporting segments.

  2. Add Tag
    - Tags: winback_inactive

    Tagging is your bread‑and‑butter way to create simple audiences and filters. If you haven’t already, it’s worth skimming the guide on getting started with tags to standardize a tag naming scheme early.

  3. If/Else: Is this a high‑value account?
    Here you use the embedded segment builder inside the If/Else node. Example condition:

    - Condition:
    - Custom attribute mrr GREATER THAN 200
    OR tag contains enterprise

    Contacts who match go down the “High value” branch. Everyone else follows the “Standard” branch.

  4. Send Internal Email (High value branch only)
    For those bigger accounts, you drop a Send Internal Email node:

    - Recipient: founders@ or a CSM inbox
    - Content: include the contact’s plan, MRR, last seen date, and a deep link to their store or account in your own admin.

    The goal is not to create a firehose of alerts, just a short list of names worth a personal touch each week.

  5. Merge
    Both branches then connect into a Merge node so the rest of the journey is identical regardless of account size.

By this point every inactive customer is clearly labeled as at‑risk, important accounts surface for potential manual follow‑up, and you’re ready to start the external conversation.

Step 4: Touch 1 – a helpful check‑in, then wait

From the Merge, the first customer‑facing step is a Send Email node.

  • Email 1 theme: “Saw your usage drop, anything we can help with?”

  • Content ideas:
    - Remind them what they were doing when active: “Last month you recovered $X in abandoned carts with CartWizard.”
    - One clear call‑to‑action: “Log back in and restart campaigns” or “Book a 15‑minute walkthrough.”

Build this in the email builder with a couple of dynamic variables, or lean on AI personalization if you’ve already set that up. Leave “Send only once” enabled, so this exact email cannot be sent twice to the same contact, even if they re‑enter the journey a year from now.

To avoid spamming, and to detect early wins, you now insert two nodes:

  1. Wait Condition
    - Condition: contact IS member of segment Active users
    - Timeout: 7 days

    This pauses the journey for up to a week. If the merchant becomes active again (they re‑enter the Active users segment), the condition becomes true and the journey resumes immediately. If they don’t, it resumes after 7 days anyway.

  2. If/Else: Reactivated?
    Same condition as above, but now used for branching:

    - Then branch (reactivated):
    - Add Tag: winback_reactivated
    - (Optional) Update Contact Attribute: reactivation_source = inactive_winback
    - Journey ends here for them.

    - Else branch (still inactive):
    - Continue to Touch 2.

This pattern repeats through the rest of the journey: every email is followed by a delay and a reactivation check, so you never keep nagging merchants who already came back to life.

Step 5: Touches 2 and 3 – value, then offer

On the “still inactive” path from that If/Else, you build out the middle of the sequence.

  1. Send Email – Touch 2: value reminder
    - Angle: “Here’s what you’re missing”
    - Content:
    - Two or three concrete wins from similar stores.
    - A short “best practice” checklist tailored to their use case (e.g. for fashion retailers vs. digital products).

    There’s already a 7‑day Wait Condition between Email 1 and this step, so spacing is healthy.

  2. Time Delay
    - Delay: 5 days

    This ensures at least five days pass before you even think about Email 3.

  3. If/Else: Reactivated?
    - Condition again: contact IS member of segment Active users.

    - Then branch: same reactivation handling as before (tag, attribute update, end).
    - Else branch: proceed.

  4. Send Email – Touch 3: targeted offer
    This is where you introduce an incentive, but still contextual:

    - For trial users: “We’ll restart your trial and add 7 extra days.”
    - For paying subscribers: “Get next month at 50% if you reactivate campaigns this week,” or offer a one‑time strategy session.

    Because reactivation checks gate each step, this offer only hits truly cold accounts, not those who just needed a quick reminder.

Again, there’s a Time Delay between Touch 2 and Touch 3, so you stay well clear of back‑to‑back sends.

Step 6: Touch 4 – graceful exit and expectations

After Email 3, you add one more sequence of spacing and checks:

  1. Time Delay
    - Delay: 7 days

  2. If/Else: Reactivated?
    - Same condition pattern.

    - Then branch: reactivation handling, end.
    - Else branch: final touch.

  3. Send Email – Touch 4: feedback and closure
    The last message should feel like a human closing a loop, not a desperate blast.

    - Acknowledge: “We noticed you haven’t used CartWizard in a while.”
    - Offer options:
    - One‑click link to pause or downgrade.
    - Invitation to reply with one thing that made the app hard to use.

    Explicitly tell them you won’t chase them again about this: you’re either there to help, or you’ll get out of the way.

  4. Add Tagwinback_exhausted
    This gives you a clean way to exclude these contacts from future win‑back waves or aggressive promos. You might still keep them on product‑update announcements, but you probably don’t want another “are you still there?” sequence for a long time.

    Update Contact Attribute
    - Attribute: lifecycle_stage
    - Value: inactive_long_term (or similar)

At this point the journey ends for everyone who didn’t come back. They’re labeled clearly, your team knows where they stand, and no one is stuck looping through the same nudges forever.

Measuring reactivation rate and recovered MRR

A win‑back journey is only as useful as the signal you get out of it. Luckily, each node you’ve added makes measurement straightforward.

Here’s how to tie it together:

  • Reactivation rate
    Build a segment: contacts tagged with winback_inactive AND winback_reactivated. Divide by the total number of winback_inactive minus winback_exhausted. That tells you what share of at‑risk users you successfully rescued.

  • Recovered MRR
    If you store each account’s MRR in a numeric contact attribute (kept up to date via the Spreeflo API or a Webhook from your billing system), you can:
    - Filter for winback_reactivated, then sum that MRR in your own reporting.
    - Or export just that segment for deeper analysis.

  • Time‑to‑reactivate
    Add a timestamp attribute, e.g. first_became_at_risk_at, which you set with an Update Contact Attribute node (type: Set to now) right after the Leave Segment trigger. When someone hits the “reactivated” path, set another timestamp reactivated_at. The difference between those two is your time‑to‑reactivate.

Because all of this uses standard tags and attributes, you can slice it however you like with the segment builder: by plan, by country, by app vertical. That’s the “capture detail on every customer so you can speak to each uniquely” idea in practice, not just a slogan.

What this changes for your app

Most Shopify and e‑commerce apps are already good at acquisition. ASO on the app store, a couple of partner webinars, some content, and installs keep coming.

Where they quietly bleed is right here: customers who were getting value, then went quiet. No drama, no signal, just slow decay.

The journey you’ve just walked through is the antidote. It turns “we should really email inactive users” from a guilt‑trip on a product roadmap into a concrete system:

  • Triggered by actual behavior (leaving “Active users”), not guesswork.

  • Tiered, so big accounts get a human eye while everyone gets a thoughtful email sequence.

  • Safe, because every message is spaced out and stops the moment someone re‑engages.

  • Measurable, down to reactivation rate, recovered MRR, and time‑to‑reactivate.

For a founder‑led team, that’s the kind of automation that earns its keep. You design it once in the journey builder, wire it up with your product events, and then it just runs alongside your app, quietly catching value you’d otherwise lose.

If you already track installs and usage, you have everything you need to build this flow. The sequence at the top of this page shows you the exact wiring; the campaigns and journeys overview and segment builder docs fill in the product details. The rest is just you deciding that inactive customers deserve the same deliberate design as acquisition—and giving them a path back in.