Shopping Cart Abandonment Recovery
Detect abandoned carts in real-time, trigger multi-step email recovery sequences, configure retargeting pixels, and track recovery analytics. Recapture 10-15% of lost revenue automatically.
Key Features
- Cart Detection — Identify abandoned carts based on inactivity timeout and exit signals
- Email Sequences — Multi-step recovery emails with configurable timing and content
- Retargeting Integration — Pixel firing for ad platform retargeting audiences
- Incentive Engine — Progressive discounts (no discount → 5% → 10% + free shipping)
- Recovery Analytics — Track recovery rate, revenue recaptured, and sequence performance
- A/B Testing — Test subject lines, timing, and discount levels
Quick Start
# 1. Extract and configure
unzip shopping-cart-abandonment.zip
cd shopping-cart-abandonment
cp config.example.yaml config.yaml
# 2. Start monitoring for abandoned carts
python -m cart_abandonment.core --monitor --config config.yaml
# 3. View recovery stats
python -m cart_abandonment.core --stats --period 2026-03
Architecture
src/cart_abandonment/
├── core.py # Detection engine and recovery orchestrator
├── detector.py # Cart activity monitoring, timeout logic
├── sequences.py # Email sequence builder and scheduler
├── incentives.py # Progressive discount and coupon generation
├── retargeting.py # Pixel event firing for ad platforms
├── analytics.py # Recovery rate, revenue, and funnel metrics
└── utils.py # Email templating, URL shortening, hashing
Recovery Flow: Cart Created → Inactivity Detected → Email #1 (1hr) → Email #2 (24hr) → Email #3 (72hr + discount)
Usage Examples
Detect Abandoned Carts
from cart_abandonment.detector import CartDetector
detector = CartDetector(
timeout_minutes=30,
exclude_logged_out=False,
min_cart_value=10.00
)
abandoned = detector.scan()
print(f"Found {len(abandoned)} abandoned carts worth ${sum(c['cart_value'] for c in abandoned):,.2f}")
for cart in abandoned[:3]:
print(f" Cart {cart['cart_id']}: ${cart['cart_value']:.2f}, "
f"abandoned {cart['minutes_ago']} min ago")
Configure Recovery Sequence
from cart_abandonment.sequences import RecoverySequence
sequence = RecoverySequence(steps=[
{"delay_minutes": 60, "subject": "You left something behind!",
"template": "reminder_gentle", "discount": None},
{"delay_minutes": 1440, "subject": "Your cart is waiting",
"template": "reminder_urgency", "discount": None},
{"delay_minutes": 4320, "subject": "Last chance — 10% off your cart",
"template": "reminder_incentive", "discount": {"type": "percent", "value": 10}},
])
sequence.activate()
Recovery Analytics Query
-- Cart abandonment recovery funnel
SELECT
DATE_TRUNC('week', c.abandoned_at) AS week,
COUNT(*) AS total_abandoned,
SUM(c.cart_value) AS abandoned_value,
SUM(CASE WHEN c.recovery_status = 'recovered'
THEN 1 ELSE 0 END) AS recovered_count,
SUM(CASE WHEN c.recovery_status = 'recovered'
THEN c.cart_value ELSE 0 END) AS recovered_value,
ROUND(SUM(CASE WHEN c.recovery_status = 'recovered'
THEN 1 ELSE 0 END) * 100.0
/ NULLIF(COUNT(*), 0), 1) AS recovery_rate_pct
FROM abandoned_carts c
WHERE c.abandoned_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY DATE_TRUNC('week', c.abandoned_at)
ORDER BY week DESC;
Email Sequence Performance
from cart_abandonment.analytics import RecoveryAnalytics
analytics = RecoveryAnalytics(config_path="config.yaml")
report = analytics.sequence_performance(period="2026-03")
for step in report["steps"]:
print(f"Step {step['step_number']} ({step['delay']}): "
f"sent={step['sent']}, opened={step['open_rate']:.1%}, "
f"clicked={step['click_rate']:.1%}, recovered={step['recoveries']}")
# Step 1 (1hr): sent=1200, opened=45.2%, clicked=12.1%, recovered=89
# Step 2 (24hr): sent=980, opened=38.7%, clicked=9.8%, recovered=52
# Step 3 (72hr): sent=820, opened=42.1%, clicked=15.3%, recovered=71
Configuration
detection:
timeout_minutes: 30 # Minutes of inactivity = abandoned
min_cart_value: 10.00 # Ignore carts below this value
check_interval_minutes: 5 # How often to scan for abandoned carts
sequence:
max_emails: 3 # Maximum emails per abandoned cart
respect_unsubscribe: true # Honor email opt-out preferences
suppress_if_purchased: true # Stop sequence if customer buys
steps:
- { delay_minutes: 60, template: "reminder_gentle", discount: null }
- { delay_minutes: 1440, template: "reminder_urgency", discount: null }
- { delay_minutes: 4320, template: "reminder_incentive", discount: { type: "percent", value: 10 } }
retargeting:
enabled: true
platforms:
- { name: "google_ads", pixel_id: "YOUR_GOOGLE_ADS_PIXEL" }
- { name: "meta", pixel_id: "YOUR_META_PIXEL_ID" }
email:
provider: "smtp"
from_address: "store@example.com"
smtp_host: "smtp.example.com"
smtp_port: 587
smtp_user: "YOUR_SMTP_USER"
smtp_password: "YOUR_SMTP_PASSWORD"
Best Practices
- Send the first email within 1 hour — Recovery rates drop sharply after 2 hours
- Don't lead with discounts — First email should be a gentle reminder, no incentive
- Limit to 3 emails — More than 3 recovery emails leads to unsubscribes
- Show cart contents — Include product images and names in every email
- A/B test aggressively — Subject lines and send timing have the biggest impact
- Suppress on purchase — Always stop the sequence if the customer completes checkout
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| No abandoned carts detected | Timeout too long | Reduce timeout_minutes to 30 |
| Emails not sending | SMTP credentials wrong | Test with --test-email flag |
| Low open rates | Subject lines too generic | A/B test with personalized subjects |
| Customers receiving emails after purchase | Suppression not enabled | Set suppress_if_purchased: true
|
| Recovery rate below 5% | Sequence timing too slow | Send first email at 30-60 minutes |
This is 1 of 11 resources in the Retail Automation Pro toolkit. Get the complete [Cart Abandonment Recovery] with all files, templates, and documentation for $29.
Or grab the entire Retail Automation Pro bundle (11 products) for $139 — save 30%.
Top comments (0)