Checkout & payments
Cart Abandonment Recovery
Indicative price, not an offer: $15-29/mo as module or $5 add-on to Email Marketing
Generated from docs/plan/paid/cart-abandonment-recovery/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
30–40% of carts are abandoned; merchants lose revenue. This paid module automates email reminders at configurable intervals with a direct link to recover the abandoned cart.
The problem
Customers add items to cart but don’t checkout. I have no way to remind them, and I leave 10–20% of potential revenue on the table.
What it does
- Abandoned cart detection: flag a cart as abandoned if unpurchased for N days (configurable, default 3 days)
- Recipient list: identify customers by email (guest or registered users)
- Email sequence: send first reminder at +1 day, second at +3 days, optional third at +5 days (configurable)
- Cart recovery link: secure, one-time link that restores the abandoned cart (no login required for guests)
- Discount incentive: merchant can optionally attach a coupon code (e.g., ‘10% off’) to the recovery email
- Automation: cron job runs daily to identify and email abandoned carts; log sent emails
- Analytics: report how many recovery emails sent, clicked, and converted to orders
- Unsubscribe: customers can opt out via link in email (respected by future recovery emails)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- SMS reminders — that’s a separate SMS channel; this module is email-only. Merchants who want SMS use a multi-channel email/SMS platform.
- Push notifications — browser push is storefront-specific; merchants implement via their own service.
- Dynamic cart value or personalization — module just sends the cart link; template text is static (merchant can edit the email template).
Data model
Migration: add abandoned_at (date, nullable) to Cart (if carts are persisted server-side) or to a new AbandonedCart collection: { id, email, cart_contents (JSON), abandoned_at, recovery_sent_count, last_recovery_sent_at, converted_order_id (nullable), unsubscribed }. Store recovery email sends in audit log or a dedicated Email Event table.
API
- POST /api/cart-abandonment/recovery-link — { email, cart_id } → { recovery_link, expires_at }
- GET /api/cart-abandonment/recover?token={secure_token} — restore abandoned cart for unauthenticated user
- POST /api/cart-abandonment/configure — { enabled, days_threshold, email_sequence, discount_code } (admin only)
- GET /api/reports/abandonment — analytics: sent, clicked, converted counts
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
New ‘Cart Abandonment Recovery’ panel under Settings or Marketing. Merchant can enable/disable, set days threshold, configure email sequence (1st email at +1 day, 2nd at +3 days, etc.), and attach a discount code. Dashboard shows today’s abandoned carts and pending recovery sends. Analytics tab shows sent count, click-through rate, and conversion rate (orders from recovery links).
The seam — why this is paid
Core owns the Email layer and audit log. Paid module owns cart tracking, abandonment detection, recovery link generation, and dunning logic. Storefront theme owns the email template (subject, body, styling); module provides variables ({{ customer.name }}, {{ cart.total }}, {{ recovery_link }}).
Paid module owns cart event hook, recovery sequence logic, and personalization engine; ships as sub-feature of email or SMS infrastructure
Dependencies
- shopping-cart — abandonment only applies if carts are tracked
- payment-status-tracking — conversion = order with payment_status=‘paid’
- Email layer (core) — module sends via existing email system
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Cart created 4 days ago, no checkout: abandoned_at flag set; recovery email queued
- Recovery email sent; unsubscribe link clicked; unsubscribed flag set; next recovery email is not sent
- Customer clicks recovery link; cart is restored in browser with same items
- Customer checks out from recovered cart; conversion is logged and attributed to recovery email
- Merchant configures 3-email sequence: +1 day, +3 days, +7 days; carts receive exactly 3 emails, not more
- Analytics show: 100 emails sent, 15 clicked (15% CTR), 3 converted to orders (3% conversion rate)
- Discount code ‘RECOVER10’ attached; recovery emails include the code; merchant tracks how many use it
Risks
Privacy: recovery link must be one-time or time-limited to prevent cart sharing. Storing email addresses of non-customers may violate GDPR unless explicit consent was collected at cart abandonment. Spam perception: sending too many recovery emails (more than 3) annoys customers and damages brand reputation. Merchants are responsible for managing list frequency. Cart changes: if customer’s cart changes (product deleted, price changed) between abandonment and recovery, the recovered cart may be invalid. Link generation must be idempotent (same email + cart = same link) so replays don’t create new links.
Commercial context
| Suggested price | $15-29/mo as module or $5 add-on to Email Marketing |
| Rival anchor | Privy mentions abandonment recovery ($30-299/mo), rolled into email/SMS platforms (Klaviyo, Omnisend, Postscript) |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.