skills/marketing-growth/cart-abandonment-recovery/SKILL.md
Win back shoppers who leave items in their cart by setting up timed email, SMS, and push sequences with escalating incentives to complete their purchase
npx skillsauth add finsilabs/awesome-ecommerce-skills cart-abandonment-recoveryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Cart abandonment averages 70% across e-commerce, making recovery flows one of the highest-ROI automations available. A good recovery sequence sends 2–4 messages across email, SMS, and push — starting with a simple reminder, then adding social proof or urgency, and only offering a discount as a last resort. The sequence cancels immediately when the customer completes checkout.
This skill guides you through setting up cart abandonment recovery on your specific platform, choosing the right tools, and configuring the sequence for maximum revenue recovery without training customers to abandon on purpose.
Ask which platform the store runs on. The setup is completely different depending on the platform:
| Platform | Recommended Tool | Why | |----------|-----------------|-----| | Shopify | Klaviyo (free up to 250 contacts) or Shopify's built-in abandoned checkout emails | Klaviyo has deep Shopify integration, tracks cart events automatically, and supports email + SMS in one tool | | WooCommerce | AutomateWoo ($99/yr) or CartFlows + FluentCRM | AutomateWoo hooks directly into WooCommerce cart events; CartFlows adds funnel recovery | | BigCommerce | Klaviyo or Omnisend | Both integrate natively with BigCommerce cart events | | Magento | Dotdigital (bundled with Adobe Commerce) or Klaviyo | Dotdigital is the default marketing automation for Magento; Klaviyo works for open-source Magento | | Custom / Headless | Klaviyo (via API) or build a custom sequence with BullMQ + SendGrid | Use Klaviyo's Track API to send cart events, then build flows in their visual editor |
The optimal sequence follows this pattern — start without a discount and escalate only if needed:
Message 1 — Reminder (1 hour after abandonment)
Message 2 — Social proof or urgency (4–6 hours)
Message 3 — Small incentive (24 hours)
Message 4 — Final push (48 hours)
Never send more than 4 messages. Beyond that, you damage brand perception more than you recover revenue.
Option A: Built-in abandoned checkout emails (free, basic)
Limitations: Shopify's built-in recovery only supports one email (or two on Plus), no SMS, no conditional incentives. Move to Klaviyo when you need a full sequence.
Option B: Klaviyo (recommended for multi-step flows)
Checkout Started eventsTrigger: "Checkout Started" event
↓
Wait 1 hour → Check: "Has Placed Order since starting flow?" → If no:
↓
Email 1: Cart reminder (no discount)
↓
Wait 4 hours → Check: "Has Placed Order?" → If no:
↓
Email 2: Urgency/social proof
↓
Wait 20 hours → Check: "Has Placed Order?" → If no:
↓
Email 3: Include discount code (use Klaviyo's coupon block — creates unique single-use Shopify discount codes)
↓
Wait 24 hours → Check: "Has Placed Order?" → If no:
↓
SMS 4 (only to SMS-consented contacts): Final reminder with discount
$value of the checkout event:
Shopify Flow (Plus only) — auto-tag for advanced routing:
Trigger: Checkout abandoned
Condition: Cart total > 200
Action: Add customer tag "high-value-abandoner"
Then use this tag in Klaviyo to route high-value abandoners to a VIP recovery sequence.
Option A: AutomateWoo (recommended)
Workflow 1: Cart Reminder
Trigger: Cart Abandoned
Timing Rule: Wait 1 hour
Action: Send Email (template: cart contents with images)
Workflow 2: Urgency Email
Trigger: Cart Abandoned
Timing Rule: Wait 6 hours
Action: Send Email (template: "Items selling fast")
Workflow 3: Discount Email
Trigger: Cart Abandoned
Timing Rule: Wait 24 hours
Action: Generate Coupon (10% off, single-use, expires in 48 hours)
Action: Send Email (template: include generated coupon code)
Workflow 4: SMS Last Chance (requires Twilio add-on)
Trigger: Cart Abandoned
Timing Rule: Wait 48 hours
Opt-in Rule: Customer has SMS marketing consent
Action: Send SMS via Twilio
Customer → Total Spent > $500 to skip the discount workflowOption B: CartFlows + FluentCRM (free alternative)
For headless storefronts, you have two paths:
Path A: Use Klaviyo's API (recommended)
Send cart events to Klaviyo, then build the flow in Klaviyo's visual editor:
// When a cart is updated, send the event to Klaviyo
async function trackCartUpdate(cart: Cart) {
await fetch('https://a.]klaviyo.com/api/events/', {
method: 'POST',
headers: {
'Authorization': `Klaviyo-API-Key ${process.env.KLAVIYO_PRIVATE_KEY}`,
'Content-Type': 'application/json',
'revision': '2024-10-15',
},
body: JSON.stringify({
data: {
type: 'event',
attributes: {
metric: { data: { type: 'metric', attributes: { name: 'Checkout Started' } } },
profile: { data: { type: 'profile', attributes: { email: cart.customerEmail } } },
properties: {
value: cart.totalValue,
items: cart.items.map(i => ({
ProductName: i.name,
ProductURL: i.url,
ImageURL: i.imageUrl,
Price: i.price,
Quantity: i.quantity,
})),
checkout_url: `${process.env.STORE_URL}/checkout?cart=${cart.id}`,
},
},
},
}),
});
}
Then build the abandoned cart flow in Klaviyo's UI — same 4-step sequence, no need to manage timers or queues yourself.
Path B: Build it yourself (only if you need full control)
If you need custom logic that Klaviyo can't handle (custom discount rules, proprietary channels, etc.), build the sequence with a job queue:
// Detect abandoned carts — run every 5 minutes via cron
async function findAbandonedCarts() {
const cutoff = new Date(Date.now() - 60 * 60000); // 1 hour inactive
const carts = await db.carts.findWhere({
lastActiveAt: { lt: cutoff },
status: 'active',
recoveryTriggered: false,
customerEmail: { not: null },
});
for (const cart of carts) {
await db.carts.update(cart.id, { recoveryTriggered: true });
await recoveryQueue.add('send-step-1', { cartId: cart.id }, { delay: 0 });
await recoveryQueue.add('send-step-2', { cartId: cart.id }, { delay: 4 * 3600000 });
await recoveryQueue.add('send-step-3', { cartId: cart.id }, { delay: 24 * 3600000 });
await recoveryQueue.add('send-step-4', { cartId: cart.id }, { delay: 48 * 3600000 });
}
}
// Cancel on conversion
async function onOrderCompleted(orderId: string) {
const order = await db.orders.findById(orderId);
if (!order.cartId) return;
const jobs = await recoveryQueue.getJobs(['delayed']);
for (const job of jobs) {
if (job.data.cartId === order.cartId) await job.remove();
}
}
Regardless of platform, follow these rules for discounts:
Track these metrics weekly:
| Metric | Good Benchmark | How to Find It |
|--------|---------------|----------------|
| Recovery rate | 5–15% of abandoned carts | Klaviyo: Flow analytics. AutomateWoo: Reports → Workflows |
| Revenue recovered | Track with UTM params (?utm_source=recovery&utm_medium=email) | Google Analytics → Campaigns |
| Unsubscribe rate from recovery emails | < 0.5% per send | Your email provider's analytics |
| Discount usage rate | < 30% of recoveries should use a discount | Compare discount vs. non-discount recovery orders |
If more than 30% of recovered orders use a discount, you're revealing the discount too early. Push it to step 3 or 4, or increase the delay.
| Problem | Solution | |---------|----------| | Recovery email sent after order placed | Ensure your flow checks "Has Placed Order" before each step (Klaviyo does this with flow filters; AutomateWoo uses rules) | | Anonymous cart abandonment not captured | Require email at the first checkout step, before payment details | | Customers learn to abandon for discounts | Never offer discount on message 1; skip discounts for repeat customers; track and exclude serial abandoners | | SMS sends to customers who didn't opt in | Gate SMS behind explicit opt-in; use your platform's consent tracking (Klaviyo tracks SMS consent separately from email) | | High unsubscribe rate from recovery emails | Reduce to 2–3 messages instead of 4; ensure one-click unsubscribe link is prominent | | Recovery emails land in spam | Use your platform's authenticated sending domain (DKIM/SPF); avoid spam trigger words like "FREE" in caps |
tools
Let shoppers save products to a wishlist, share it with friends, and get notified when saved items come back in stock or drop in price
development
Build a themeable storefront with design tokens and CSS custom properties that supports white-labeling, multi-brand variants, and dark mode
development
Speed up product discovery with instant search suggestions, fuzzy typo matching, and category-aware results powered by Algolia or Elasticsearch
development
Build a mobile-first storefront with thumb-friendly navigation, sticky add-to-cart buttons, and touch-optimized components for high mobile conversion