Featured Article

Build an Abandoned Cart Recovery System That Recovers 20% of Lost Sales

Mike Holownych
#n8n #e-commerce #automation #abandoned-cart #conversion

Quick win: Recover 15-25% of abandoned carts with automated 3-email sequence. Typical store recovers $500-2,000/month.

Here’s the complete system.

The Numbers

Average cart abandonment rate: 69.8% Recovery rate with good sequence: 15-25% Average order value: $100

Monthly calculation (100 carts/month):

100 carts × 69.8% abandoned = 70 abandoned carts
70 × 20% recovered = 14 recovered orders
14 × $100 AOV = $1,400 recovered revenue

Cost to build: $0 (n8n + SendGrid free tiers)


The 3-Email Sequence

Email 1: Reminder (1 hour after abandonment)

Subject: “You left something in your cart”

Content:

  • Remind what they left behind
  • Show product images
  • Single CTA: “Complete Your Purchase”
  • NO discount yet

Conversion rate: 30-40% of recoveries

Email 2: Social Proof + Urgency (24 hours)

Subject: “Still thinking it over? Here’s what others say”

Content:

  • Customer reviews/testimonials
  • Limited stock warning (if true)
  • Free shipping reminder
  • CTA: “Claim Your Items”

Conversion rate: 40-50% of recoveries

Email 3: Discount Offer (72 hours)

Subject: “Here’s 10% off to complete your order”

Content:

  • 10% discount code
  • Expires in 48 hours
  • Highlight value proposition
  • Final CTA

Conversion rate: 20-30% of recoveries

Total sequence recovery: 15-25% of abandoned carts


n8n Workflow Architecture

Schedule (hourly check)
→ Query store API (abandoned carts > 1 hour)
→ Filter (not yet contacted)
→ Branch by time abandoned:
  → 1-2 hours: Send Email 1
  → 24-48 hours: Send Email 2
  → 72-120 hours: Send Email 3
→ Mark as contacted
→ Log to Google Sheets

Step-by-Step Setup

Step 1: Create Google Sheet for Tracking

Columns:

  • Cart ID
  • Customer Email
  • Customer Name
  • Cart Value
  • Abandoned At
  • Email 1 Sent (date)
  • Email 2 Sent (date)
  • Email 3 Sent (date)
  • Recovered (yes/no)
  • Recovery Date
  • Recovery Value

Step 2: Build n8n Workflow

Node 1: Schedule Trigger

Cron: 0 * * * * (every hour)

Node 2: HTTP Request (Get Abandoned Carts)

For Shopify:

Method: GET
URL: https://your-store.myshopify.com/admin/api/2024-01/checkouts.json
Headers:
  - X-Shopify-Access-Token: YOUR_TOKEN
Parameters:
  - status: open
  - created_at_min: (2 hours ago)

For DashNex:

Method: GET  
URL: https://your-dashnex-store.com/api/abandoned-carts
Headers:
  - Authorization: Bearer YOUR_API_KEY

Node 3: Filter Node

Filter carts that haven’t been contacted yet:

const cart = $json;
const hoursSince = (Date.now() - new Date(cart.abandoned_at)) / (1000 * 60 * 60);

// Only process carts 1-120 hours old
return hoursSince >= 1 && hoursSince <= 120;

Node 4: Google Sheets Lookup

Check if cart already in tracking sheet:

Operation: Lookup
Column: Cart ID
Value: \{\{$json.id\}\}

Node 5: Switch Node (Route by Time)

Route 1: 1-2 hours since abandonment
Route 2: 24-26 hours since abandonment
Route 3: 72-74 hours since abandonment
Default: Skip (already contacted)

Node 6a: SendGrid (Email 1)

Template ID: abandoned-cart-reminder
To: \{\{$json.customer_email\}\}
Dynamic Data:
  - customer_name: \{\{$json.customer_name\}\}
  - cart_items: \{\{$json.items\}\}
  - cart_total: \{\{$json.total\}\}
  - cart_url: \{\{$json.recovery_url\}\}

Node 6b: SendGrid (Email 2)

Template ID: abandoned-cart-social-proof
Dynamic Data:
  - customer_name
  - cart_items
  - testimonials: (pull from database)
  - cart_url

Node 6c: SendGrid (Email 3)

Template ID: abandoned-cart-discount
Dynamic Data:
  - customer_name
  - cart_items
  - discount_code: \{\{$json.discount_code\}\}
  - expiry_date: (calculate: now + 48 hours)
  - cart_url

Node 7: Google Sheets Update

Log which email was sent:

Operation: Append or Update
Columns:
  - Cart ID
  - Email 1/2/3 Sent: Current timestamp

Email Templates

Template 1: Reminder

<!DOCTYPE html>
<html>
<body>
  <h2>Hi \{\{customer_name\}\},</h2>
  
  <p>You left these items in your cart:</p>
  
  \{\{#each cart_items\}\}
  <div>
    <img src="\{\{image_url\}\}" width="100">
    <h3>\{\{name\}\}</h3>
    <p>$\{\{price\}\}</p>
  </div>
  \{\{/each\}\}
  
  <p><strong>Total: $\{\{cart_total\}\}</strong></p>
  
  <a href="\{\{cart_url\}\}" style="background: #007bff; color: white; padding: 12px 24px; text-decoration: none;">
    Complete Your Purchase
  </a>
  
  <p>Questions? Reply to this email.</p>
</body>
</html>

Template 2: Social Proof

<h2>Still thinking it over, \{\{customer_name\}\}?</h2>

<p>Here's what other customers say:</p>

<blockquote>
  "Best purchase I've made this year!" - Sarah M.
</blockquote>

<blockquote>
  "Exceeded my expectations." - John D.
</blockquote>

<p><strong>Only 3 left in stock!</strong> Secure yours now.</p>

<a href="\{\{cart_url\}\}">Claim Your Items</a>

Template 3: Discount

<h2>\{\{customer_name\}\}, here's 10% off</h2>

<p>We want to make this easy for you.</p>

<div style="background: #f0f0f0; padding: 20px; text-align: center;">
  <h3>Use code: \{\{discount_code\}\}</h3>
  <p>Save 10% on your order</p>
  <p><strong>Expires in 48 hours</strong></p>
</div>

<a href="\{\{cart_url\}\}">Complete Purchase & Save 10%</a>

<p><small>This is our final email about this cart.</small></p>

Testing Your Workflow

Test sequence:

  1. Create test abandoned cart in your store
  2. Wait 1 hour → Check Email 1 received
  3. Mark as “not recovered” in tracking sheet
  4. Wait 24 hours → Check Email 2 received
  5. Wait 72 hours → Check Email 3 received

Common issues:

Email not sending:

  • Check SendGrid API key
  • Verify template IDs
  • Check spam folder

Workflow not triggering:

  • Verify cron schedule is correct
  • Check store API credentials
  • Ensure workflow is activated

Optimization Tips

Timing Adjustments

Test different timings:

  • Email 1: Try 30 min, 1 hour, or 2 hours
  • Email 2: Try 12 hours or 48 hours
  • Email 3: Try 48 hours or 5 days

Track recovery rates for each timing.

Discount Strategies

A/B test:

  • 10% vs 15% discount
  • Free shipping vs percentage off
  • Dollar amount vs percentage

My results: 10% converts almost as well as 15%, keeps margins higher.

Personalization

Advanced tactics:

  • Reference specific products by name
  • Show related products customer might like
  • Mention items frequently bought together
  • Use customer’s browsing history

GDPR/Privacy:

  • Only email customers who opted in
  • Include unsubscribe link
  • Honor opt-outs immediately

Frequency caps:

  • Max 3 emails per abandoned cart
  • Don’t email if customer already purchased
  • Respect “do not email” preferences

Subject line rules:

  • No all caps
  • No excessive punctuation!!!
  • No misleading claims

ROI Calculation

Scenario: Small store (50 orders/month)

Orders: 50/month
Abandoned carts: 50 × (69.8% / 30.2%) = 115 abandoned
Recovery rate: 20%
Recovered: 115 × 20% = 23 orders
Average order: $75
Monthly recovered revenue: 23 × $75 = $1,725

Annual recovered revenue: $20,700
Setup time: 4 hours @ $50/hour = $200
Monthly cost: $0 (free tiers)

ROI: Infinite (after initial setup)

FAQ

Q: Won’t frequent emails annoy customers?

3 emails over 5 days is reasonable. Customers want reminders. High unsubscribe rates (>2%) mean you’re overdoing it.

Q: Should I always offer a discount?

No! Try the sequence without discounts first. Only add discount in Email 3 if needed.

Q: What if customer already purchased?

Add a check in your workflow to skip carts where order was completed.

Q: Can this work with Shopify/WooCommerce?

Yes! Same concept. Just connect to their APIs instead of DashNex.


Related:


About: I’m Mike Holownych. I build e-commerce automation systems that recover lost revenue. Learn more →

MH

About Mike Holownych

I help entrepreneurs build self-running businesses with DashNex + automation. n8n automation expert specializing in e-commerce, affiliate marketing, and business systems.