Win Back Past Buyers with Purchase-History Segments & Discount Codes

"People who bought X between date A and B" isn't a rollup number, it's real order line items — and once a Shopify or WooCommerce store is connected, MailInApp can filter on exactly that. Build the segment, turn on a discount offer, and every matched recipient gets their own single-use code minted on your store the moment their email sends — redeemed at your own checkout, not a second one.

"People who bought X between date A and B" isn't a lifetime-spend rollup — it's real order line items. Once a Shopify or WooCommerce store is connected, MailInApp can filter on exactly that, and hand each match a real, single-use discount code redeemed on your own store.

Most win-back emails either go to everyone who hasn't bought recently, or to nobody, because building "bought this specific product in this specific window" by hand means exporting orders into a spreadsheet first. This walks through doing it inside MailInApp instead — segment, discount, send.

Step 1 — Connect your store and backfill order history

From Settings → Integrations, connect Shopify or WooCommerce if you haven't already. Either one syncs customers into a contacts list and keeps line-item order data current from then on through its own webhooks. An older connection, or a store with years of history, needs a one-time Backfill order history pull from the same Integrations panel first — ongoing orders sync automatically after that. Shopify backfills reach roughly the last 60 days unless Shopify has separately approved the app for full order history on your store; WooCommerce has no such cap.

Step 2 — Build a Purchase history audience filter

On a project's Send page, open the Audience filter and add a condition under the new Purchase history group — distinct from the plain "purchased" and "total revenue" conditions, which only look at a lifetime rollup. Pick a product (or leave it open to match any), a date range, whether to sum by amount or quantity, and the threshold:

  • Bought 2+ units of a specific product in the last 90 days.
  • Spent over $50 storewide between two specific dates — a seasonal win-back list.

Combine it with ordinary field conditions using the same AND/OR groups you already use for a block's visibility rules in the studio.

Step 3 — Turn on a discount offer

The same project's Discount offer section is where the actual incentive lives. Turn it on, pick a percentage or fixed amount off, how many days a minted code stays valid, and — optionally — scope it to one product instead of the whole store. Set Don't re-offer within N days too if more than one campaign might target this list, so a contact who already got a code from an unrelated send recently doesn't get a second one right away.

Step 4 — Write the email once

Drop {{discount_code}} into a heading and {{discount_url}} into a Button block's link — both are built-in merge tags, resolved per recipient the same way {{first_name}} is. Nothing about the email needs a per-person template; every recipient's copy just carries their own real values once it sends.

Step 5 — Send, and let redemption happen on your own store

Right before each matched recipient's email renders, MailInApp mints a real discount code on your connected store (a Shopify discount code or a WooCommerce coupon), restricted to that one customer's email and usable exactly once. {{discount_url}} links straight to checkout with it already applied, so there's nothing to copy-paste. If minting fails for a particular recipient — a token needs reconnecting, a live API hiccup — that recipient's email still sends anyway, just without a code that time; it's never a blocked send.

Why redemption happens on your own store

This is deliberate, not a limitation. The audience you're targeting is already shopping on your store, so the discount reuses that store's existing inventory, tax, and pricing rules instead of standing up a second point of sale for products that already have one. MailInApp's own Product block + Stripe checkout solves a different problem — selling something with no storefront behind it at all.

Reading the results

A redeemed order attributes back to the campaign that sent the code exactly the way any other store click already does — see tracking Shopify orders, checkouts & revenue for how that attribution actually works end to end.

Getting started

Connect your store, backfill order history if it's an older connection, build one Purchase history segment against a product you actually want to move, and turn on a modest discount offer before sending to that small matched list first. See Behavioral segments, Sending to your contacts, and Data sources & merge tags for the full reference.

A typical build-and-send sequence

  1. 1

    Connect your store and backfill order history

    From Settings → Integrations, connect Shopify or WooCommerce if you haven't already. A store connected before purchase-history segments existed, or with older history, needs a one-time Backfill order history pull so past orders are queryable — ongoing orders sync automatically from there.

  2. 2

    Build a Purchase history audience filter

    On the Send page's audience filter, add a Purchase history condition: pick a product (or leave it open to any product), a date range, amount or quantity, and the threshold — for example, bought 2+ units of a specific item in the last 90 days.

  3. 3

    Turn on a discount offer

    In the same project's Discount offer section, set a percentage or fixed amount off, how many days the code stays valid, and an optional cooldown so an unrelated campaign doesn't re-offer the same contact too soon.

  4. 4

    Write the email once

    Drop {{discount_code}} and {{discount_url}} into a heading and a Button block. Every recipient's copy of the email carries their own real, working code and link — nothing to template per person by hand.

  5. 5

    Send, and let redemption happen on your own store

    Each matched recipient gets a single-use code minted right before their email renders. They redeem it on your store's own checkout — the same inventory, tax, and pricing rules that already run there — and the resulting order attributes back to this campaign the same way any other store click does.

Frequently asked questions

Why does redemption happen on my own store instead of MailInApp's own checkout?

Because the audience you're targeting is already shopping on your store — this feature reuses that store's own inventory, tax, and pricing rules through a real Shopify discount code or WooCommerce coupon, rather than standing up a second point of sale inside MailInApp for products that already have one. MailInApp's own Product block + Stripe checkout is a separate feature for a different case: selling something with no existing storefront behind it.

Is the discount code reusable, or can it leak if someone forwards the email?

Each code is minted single-use and restricted to that one recipient's own email address on your store, so forwarding the email doesn't hand a stranger a usable code — only the original recipient's own account or checkout email can redeem it.

How far back does purchase history actually go?

As far back as your store has synced. Ongoing orders sync live from your store's own webhooks going forward; a store connected before this existed, or with years of history, needs a one-time Backfill order history pull — Shopify backfills reach roughly the last 60 days unless Shopify has separately approved the app for full history on your store, while WooCommerce has no such cap.

What happens if a recipient's code fails to mint?

Their email still sends — just without a code that send. A misconfigured or disconnected store can't block the whole campaign; only that recipient's discount content is missing, and it's visible in server logs rather than silently claimed as a success.

Can I stop the same contact from getting couponed by two different campaigns too close together?

Yes — the Discount offer section's "Don't re-offer within N days" setting checks the contact's own last-offered date before minting a new code, regardless of which project or schedule is sending. Leave it blank and it defaults to the code's own expiry, so a replacement is never handed out while an earlier one might still be valid.

Does this work the same way with WooCommerce as Shopify?

Yes — WooCommerce mints a restricted, single-use coupon through its own REST API instead of Shopify's discount-code API, but the segment builder, the Discount offer settings, the merge tags, and the attribution all work identically once a store is connected.

Build this in the studio

Start on the free plan — every interactive block and the full fallback engine are included on every tier.