# Post-Purchase Follow-Up Automation in AcelleMail — Thank, Review, Cross-Sell

> A confirmation email is just the start. Layer in a delivery-day check-in, a 7-day review request, a 30-day cross-sell, a 60-day "we miss you". This guide builds the full post-purchase flow in AcelleMail's automation builder using tags or custom events fired from your ecommerce backend.

- Canonical URL: https://acellesend.com/kb/articles/post-purchase-follow-up-automation
- Author: Sofia Lindqvist, Email Marketing Editor
- Category: Automation — Triggers, workflows, welcome series, drip campaigns, behavioral flows
- Content type: tutorial · Difficulty: intermediate
- Tags: Acellemail
- Published: 2026-05-13 · Last updated: 2026-08-15
- Reading time: 8 min
- Publisher: AcelleMail Knowledge Base, https://acellesend.com/kb

---

## What "post-purchase" actually means

A post-purchase flow is a sequence of emails that fires AFTER someone buys — automatically, without you scheduling each send. The right flow varies by what you sell, but every successful one shares the same skeleton:

| Stage | Timing | Goal |
|---|---|---|
| Confirmation | Immediately | Reassure: order received, here's what happens next |
| Shipping notification | When tracking is available | Set expectation for arrival |
| Delivery check-in | 1-2 days after delivery | Confirm satisfaction, surface issues early |
| Review request | 7 days after delivery | Capture social proof while memory is fresh |
| Cross-sell / replenishment | 30 days after purchase | Right-time the next-purchase nudge |
| Win-back | 60-90 days if no return purchase | Re-engage before they forget |

AcelleMail's automation builder handles all of this with three trigger types: **Tag added**, **Custom event**, and **Date relative** (post-tag).

## Setup: two paths depending on your ecommerce stack

### Path A: Tag-driven (simpler, manual or webhook-pushed)

When a purchase happens, your ecommerce system tags the subscriber in AcelleMail with a tag like `purchased-2026-05-19` or just `recent-purchaser`. The automation triggers on tag add.

### Path B: Custom-event-driven (richer, more flexible)

Your ecommerce system fires a custom event with payload like `{"event": "purchase_completed", "order_total": 87.50, "products": ["sku-001", "sku-007"]}`. The automation triggers on the event + uses payload data in subsequent steps.

For most senders Path A is enough to start. Switch to Path B when you need conditional flows ("if order over $100 → premium review request track; else standard track").

## Build the flow (Path A — tag-driven)

### Open the visual automation builder

In AcelleMail's left sidebar, click **Automation** → **Automations**. The index lists every automation in this account with its current state:

![Automations index](https://acellesend.com/plugins/acelle/landing/images/help/kb/welcome-automation/01-automations-index.png)

Click **New automation** in the top-right toolbar. The trigger picker opens:

![Trigger picker — pick what starts the automation](https://acellesend.com/plugins/acelle/landing/images/help/kb/welcome-automation/02-create-trigger-picker.png)


For the confirmation email step:

1. **Trigger**: **Tag added**
2. **Tag**: `recent-purchaser`
3. **Action**: send the **Confirmation** email immediately

Drop in the email step, write your confirmation copy. Save. The trigger now fires the email whenever `recent-purchaser` tag is added to anyone.

Add downstream steps inside the same automation:

```
[Trigger: tag added 'recent-purchaser']
  →
[Email: Order Confirmation]
  Wait: 3 days
[Email: How's it going? (delivery check-in)]
  Wait: 4 days  (=7 days from purchase)
[Email: Leave a review]
  Wait: 23 days  (=30 days from purchase)
[Email: You might also like...]
  Wait: 30 days  (=60 days from purchase)
[Condition: did NOT purchase again]
  →
[Email: We miss you — here's 10% off]
```

The visual builder:

![Multi-step automation flow](https://acellesend.com/plugins/acelle/landing/images/help/kb/welcome-automation/03-flow-builder.png)

Each "Wait" step is delay-based — AcelleMail queues the next step's send time per-subscriber individually.

## Tag-source patterns

The tag `recent-purchaser` arrives in AcelleMail one of three ways:

### Webhook from ecommerce platform

Shopify / WooCommerce / Magento / BigCommerce all send order webhooks. Configure a bridge service (Cloudflare Worker, Zapier, n8n, custom backend) to translate the webhook into an AcelleMail API call:

```
[Shopify webhook: order/created]
  → bridge service receives
  → POST to https://acellemail.com/api/v1/subscribers/{uid}/tags
    body: { "tags": ["recent-purchaser"] }
```

The subscriber must already exist in your AcelleMail list (or use the upsert API to create-if-not-exists).

### Manual tag-add from the subscriber detail view

For small senders, the easiest path is manual: open the subscriber, **Tags** section, click **Add tag** → `recent-purchaser`:

![Subscriber tags UI](https://acellesend.com/plugins/acelle/landing/images/help/kb/preferences/03-subscriber-tags.png)

Workable for low-volume; not scalable.

### CSV import / bulk re-tag

Export today's orders → CSV with `email` + `tags` columns → import into AcelleMail via **Audience → [list] → Import** with the duplicate-handling set to **Update**. Existing subscribers get the new tag, the automation fires.

## Common UI signals + fixes

| Symptom | Likely cause | UI fix |
|---|---|---|
| Confirmation email doesn't send when order placed | Webhook from ecommerce isn't reaching AcelleMail | Test the webhook destination URL directly with curl; verify auth header |
| Subscriber gets confirmation but no follow-ups | Wait step not advancing | Open automation → check run-log for blocked subscribers (waiting on Wait timer; OR exited automation due to unsubscribe) |
| Same subscriber gets 3 confirmation emails | Tag added 3 times (re-imported 3 times) | Switch to "Tag changed to" not "Tag added" — fires only once per state change |
| Review request fires before delivery | "7 days from tag add" but tag was added at order time, before shipping | Have ecommerce add a separate "order-delivered" tag when tracking shows delivered; trigger review on that tag instead |
| Cross-sell email recommends item already purchased | Email body hard-codes product list, ignores purchase history | Use merge tags from custom fields populated at purchase time, OR fall back to popular-items |

## Path B — Custom event triggers

Switch to events when the flow needs to react to *what* was purchased, not just *that* a purchase happened.

Fire the event from your ecommerce backend:

```bash
curl -X POST "https://acellemail.com/api/v1/events" \
  -H "Authorization: Bearer $ACELLE_TOKEN" \
  -d '{
    "subscriber_email": "buyer@example.com",
    "event": "purchase_completed",
    "data": {
      "order_total": 87.50,
      "currency": "USD",
      "products": ["yoga-mat-blue", "yoga-block-pair"],
      "category": "fitness"
    }
  }'
```

In AcelleMail, build the automation:

1. **Trigger**: **Custom event**, event name = `purchase_completed`
2. **Conditional step**: branch on `data.order_total > 100`
3. **Branch A** (high-value): premium review request track
4. **Branch B** (standard): standard review request track

Custom-event triggers let the automation read the event's payload — `{{ event.data.order_total }}` works in email body, `{{ event.data.products[0] }}` for the product name in subject, etc.

<details>
<summary><strong>Advanced: ecommerce webhook setups for Shopify, WooCommerce, Stripe</strong></summary>

The bridge between your store and AcelleMail is where most "post-purchase doesn't fire" bugs hide. Here are concrete patterns for the three most common platforms.

**Shopify → AcelleMail:**

```bash
# 1. In Shopify admin: Settings → Notifications → Webhooks → Create webhook
#    Event: Order creation
#    Format: JSON
#    URL: https://your-bridge.example.com/shopify-to-acelle

# 2. Your bridge service (Cloudflare Worker example):
addEventListener('fetch', event => {
  event.respondWith(handle(event.request))
})

async function handle(req) {
  if (req.method !== 'POST') return new Response('', { status: 405 })

  // Verify Shopify HMAC signature
  const body = await req.text()
  const sig = req.headers.get('x-shopify-hmac-sha256')
  const expected = await hmacSha256(body, env.SHOPIFY_WEBHOOK_SECRET)
  if (sig !== expected) return new Response('Bad signature', { status: 401 })

  const order = JSON.parse(body)

  // Push to AcelleMail
  await fetch('https://acellemail.com/api/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + env.ACELLE_TOKEN,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscriber_email: order.email,
      event: 'purchase_completed',
      data: {
        order_total: order.total_price,
        currency: order.currency,
        products: order.line_items.map(l => l.sku),
      }
    })
  })

  return new Response('ok')
}
```

The `verify HMAC` step is critical — without it anyone can spoof a Shopify webhook and trigger your automation.

**WooCommerce → AcelleMail (via WordPress action hook):**

```php
add_action('woocommerce_order_status_completed', function($order_id) {
    $order = wc_get_order($order_id);
    $email = $order->get_billing_email();
    $total = $order->get_total();

    wp_remote_post('https://acellemail.com/api/v1/events', [
        'headers' => [
            'Authorization' => 'Bearer ' . ACELLE_TOKEN,
            'Content-Type' => 'application/json',
        ],
        'body' => json_encode([
            'subscriber_email' => $email,
            'event' => 'purchase_completed',
            'data' => [
                'order_total' => $total,
                'products' => array_map(fn($i) => $i->get_product()->get_sku(), $order->get_items()),
            ]
        ]),
    ]);
});
```

Add to your theme's `functions.php` or a custom plugin.

**Stripe Subscriptions → AcelleMail:**

```bash
# Stripe sends 'customer.subscription.created' / 'customer.subscription.updated' / 'invoice.paid'
# Forward via Stripe webhook → your endpoint:

# Express.js example
app.post('/stripe-to-acelle', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, STRIPE_WEBHOOK_SECRET);
  } catch (err) { return res.status(400).send('webhook error'); }

  if (event.type === 'invoice.paid') {
    const invoice = event.data.object;
    await fetch('https://acellemail.com/api/v1/events', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer ' + ACELLE_TOKEN,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        subscriber_email: invoice.customer_email,
        event: 'subscription_renewed',
        data: { amount: invoice.amount_paid / 100, currency: invoice.currency },
      }),
    });
  }

  res.json({received: true});
});
```

**Reverse-direction sync** (AcelleMail → CRM):

When the post-purchase flow's "review request" comes back with a 1-star NPS, you want a sales / customer-success ticket to open in your CRM. Use AcelleMail's automation **Send webhook** action:

```
[Form submission: NPS feedback]
  Condition: score <= 6
    [Send webhook: POST https://your-crm.example.com/tickets
       body: { customer_email: '{{ subscriber.email }}', issue: 'low_nps', score: '{{ form.nps_score }}' }]
```

Your CRM receives, opens a ticket, assigns to a CSM. The whole loop closes without anyone manually copy-pasting.

**Replenishment timing — when to nudge the next purchase:**

Most products have a "natural reorder cycle" — coffee at 4 weeks, supplements at 30 days, razors at 6 weeks. Set the cross-sell Wait step to ~80% of the typical cycle so the email arrives *before* they think about reordering, not after they've already gone to a competitor. For unknown products, default to 30 days and measure CTR by Wait-duration A/B test (split the audience: 21d vs 30d vs 45d, compare conversion).

**Test the full flow before launching:**

In AcelleMail, the automation **Test** button (or **Preview run**) lets you simulate a subscriber going through the entire flow with shortened wait times — useful before launching for real.

```bash
# Manual test from API:
curl -X POST "https://acellemail.com/api/v1/events" \
  -H "Authorization: Bearer $ACELLE_TEST_TOKEN" \
  -d '{
    "subscriber_email": "your-test-email@example.com",
    "event": "purchase_completed",
    "data": {"order_total": 87.50}
  }'
```

Then watch the automation logs to verify each step ran + when.

</details>

## Related articles

- [Building a welcome email series in AcelleMail](https://acellesend.com/kb/articles/building-a-welcome-email-series-in-acellemail)
- [Advanced automation triggers and conditions](https://acellesend.com/kb/articles/advanced-automation-triggers-and-conditions)
- [Using API triggers for custom automation workflows](https://acellesend.com/kb/articles/using-api-triggers-for-custom-automation-workflows)
- [Lead scoring with email automation](https://acellesend.com/kb/articles/lead-scoring-with-email-automation)
- [Birthday and anniversary email automations](https://acellesend.com/kb/articles/birthday-and-anniversary-email-automations)

---

## Related articles

- [Build a Welcome Email Series in AcelleMail (Visual Flow Builder)](https://acellesend.com/kb/articles/building-a-welcome-email-series-in-acellemail): AcelleMail's automation builder ships with 12 triggers. "Welcome new subscribers" + 5 email nodes + a WAIT + a YES/NO CONDITION gives you a working welcome series in 30 minutes. Walkthrough with the actual flow canvas.
- [Automation Triggers + Conditions: Full Reference](https://acellesend.com/kb/articles/advanced-automation-triggers-and-conditions): Complete reference for AcelleMail's 12 built-in triggers, the CONDITION node operators, and the OPERATION actions. Plus the multi-branch patterns power users actually deploy.
- [Lead Scoring with AcelleMail Automation — Score, Tag, and Route](https://acellesend.com/kb/articles/lead-scoring-with-email-automation): Add points when a subscriber opens a campaign, clicks a key link, or fills a form. Route high-score subscribers to a sales-handoff tag automatically. This guide walks the AcelleMail automation builder + custom-field scoring, with API-driven scoring patterns for ecommerce + CRM integrations in the collapsible section.
- [Birthday & Anniversary Automations in AcelleMail — Date-Triggered Sends](https://acellesend.com/kb/articles/birthday-and-anniversary-email-automations): Send a happy-birthday discount on the day, a year-since-signup gift on the anniversary, a renewal reminder 30 days before expiry. AcelleMail's date-relative automation trigger handles all of these — this guide walks the setup with screenshots.
- [API Triggers for Custom Automations — Wiring AcelleMail to Anything](https://acellesend.com/kb/articles/using-api-triggers-for-custom-automation-workflows): Your CRM, app, or backend can fire AcelleMail automations directly — no Zapier, no manual tagging. This guide walks the UI setup (custom-event triggers + API token generation) plus a complete payload + signing reference in the collapsible developer section.
