📄 Plugin Documentation

Storzen — Cart Recovery
for WooCommerce

Automated abandoned cart recovery for WooCommerce stores. Capture lost revenue with smart cart tracking, 2-step email sequences, HMAC-signed recovery links, and a conversion-focused analytics dashboard — all self-hosted, no SaaS.

GPL v2 Licensed WordPress 6.4+ WooCommerce 8.0+ HPOS Compatible PHP 7.4+ Translation Ready
01 — Introduction

What is Storzen Cart Recovery?

Storzen Cart Recovery for WooCommerce gives store owners everything needed to recover abandoned carts — capture system, automated email sequences, one-click recovery links, and full analytics — all bundled into one lightweight, self-hosted WordPress plugin. No SaaS subscriptions, no phone-home requests, no third-party API dependencies.

The plugin tracks both guest and logged-in carts, detects abandonment based on a configurable inactivity threshold, queues automated recovery emails via WP-Cron, and presents the entire recovery funnel through a clean, modern admin dashboard built with conversion optimisation in mind.

🛒
Smart Cart Tracking
Captures cart contents, email, and customer name from both guests and logged-in users via AJAX and exit-intent triggers. Database-backed with configurable retention.
Free
✉️
2-Step Email Sequence
Automated recovery emails sent at customisable intervals (e.g. 1h and 24h) via WP-Cron. Each step has its own subject, template, and timing.
Free
🎨
2 Email Templates
Responsive HTML emails with cart items, product images, prices, store logo, and recovery CTA. Live preview with desktop/mobile toggle.
Free
🔐
HMAC-Signed Links
One-click recovery URLs use HMAC-SHA256 signatures (not nonces) — no expiration, tamper-proof, and safe to share via email.
Free
📊
Analytics Dashboard
KPI cards (abandoned, recovered, recovery rate, revenue), 30-day trend chart, and recent activity feed — all in a modern flat UI.
Free
🎯
Exit-Intent Popup
Optional email capture popup that triggers when a user moves to leave the page with items in cart — boosts capture rate before they bounce.
Free
wp-admin → Cart Recovery → Dashboard
Dashboard
Abandoned Carts
Email Templates
Settings
Dashboard v1.0.0
🛒
247
Abandoned
63
Recovered
📈
20.3%
Rate
💰
$4.8k
Recovered
$18k
At Risk
12
Active
30-day trend
Recent abandoned
Sarah M.Abandoned
James K.Recovered
GuestActive
Emma L.Abandoned
02 — Requirements

System Requirements

Storzen Cart Recovery is designed to work on modern WordPress + WooCommerce stacks with minimal overhead.

🌐
WordPress
6.4+  ·  tested up to 7.0
🛍️
WooCommerce
8.0+  ·  tested up to 9.4
🐘
PHP
7.4+  ·  tested on 8.2
🗄️
MySQL / MariaDB
5.7+ / 10.3+
⏱️
WP-Cron
Enabled (or real cron)
✉️
Email Delivery
Working wp_mail()
💡
HPOS Compatible The plugin declares full compatibility with WooCommerce High-Performance Order Storage (HPOS / Custom Order Tables). No legacy post-meta queries are used for orders.
03 — Installation

Installation

From WordPress.org

  1. In your WordPress admin, go to Plugins → Add New.
  2. Search for "Storzen Cart Recovery".
  3. Click Install Now, then Activate.
  4. You'll see a new Cart Recovery menu item in the WordPress admin sidebar.

Manual Installation (ZIP upload)

  1. Download the latest ZIP from wordpress.org/plugins/storzen-cart-recovery-for-woocommerce.
  2. Go to Plugins → Add New → Upload Plugin.
  3. Choose the ZIP, click Install Now, then Activate.

Via WP-CLI

# Install and activate from the .org repository
wp plugin install storzen-cart-recovery-for-woocommerce --activate

# Or install from a ZIP file
wp plugin install ./storzen-cart-recovery-for-woocommerce.zip --activate
⚠️
WooCommerce is required The plugin will not activate without WooCommerce. If you see an admin notice asking you to activate WooCommerce, install and activate WooCommerce first, then activate this plugin.
04 — Quick Start

5-Minute Setup

After activation, the plugin works out of the box with sensible defaults. The setup below covers the three most important configuration steps.

Step 1 — Configure Sender Information

Go to Cart Recovery → Settings → Email Sequence and update the sender details that customers will see in their inbox.

  • From Name: Your store name (shown in inbox)
  • From Email: An address on your store's domain (avoid Gmail / Yahoo for deliverability)
  • Reply-To: Optional address where customer replies should go

Step 2 — Set Inactivity Threshold

Go to Cart Recovery → Settings → General and adjust the inactivity threshold. After this many minutes of cart inactivity, the cart is marked as abandoned and email queue is scheduled.

💡
Recommended setting 60 minutes is a strong default. Too short (e.g. 5 min) catches users still browsing; too long (e.g. 24h) misses the impulse-buyer window.

Step 3 — Enable the Email Sequence

On the same settings page, toggle on Enable Automated Sequence and configure the two email steps:

  • Email 1: Sent 1 hour after abandonment with subject "You left something behind"
  • Email 2: Sent 24 hours after abandonment with subject "Your cart is waiting for you"

Each step has its own subject, template selector, and delay. Click Save Settings and you're live.

That's it Cart tracking and the recovery sequence start immediately. View captured carts under Cart Recovery → Abandoned Carts, and monitor the funnel from the Dashboard.
05 — Cart Tracking

How Cart Tracking Works

The plugin captures cart data via two AJAX entry points and stores everything in a dedicated database table — no external services involved.

What Gets Captured

  • Cart contents (serialised cart items array)
  • Cart total and currency
  • Customer email (when available — checkout, login, exit-intent popup)
  • First name and last name (if provided)
  • Visitor IP address (for analytics; configurable retention)
  • User agent (for device analytics)
  • Created at, updated at, and abandoned at timestamps

Capture Triggers

The plugin uses both standard WooCommerce hooks and AJAX listeners:

  • Cart updates — captured via woocommerce_cart_updated and AJAX storzen_cr_save_cart
  • Email capture — checkout email field, login, or exit-intent popup via AJAX storzen_cr_capture_email
  • Order placed — cart marked as recovered via woocommerce_thankyou when the customer email matches an abandoned cart

Cart Status Flow

// Cart status transitions
active      → user is browsing / updating cart
abandoned   → inactivity threshold reached, emails queued
recovered   → matching order placed
lost        → retention period exceeded with no recovery

Excluding User Roles

Under Settings → General → Tracking Scope, you can exclude certain roles (e.g. Administrator, Shop Manager) from being tracked. This prevents test carts created during development from polluting your analytics.

06 — Recovery Email Sequence

The Recovery Sequence

When a cart is marked as abandoned, the plugin schedules a 2-step email sequence based on your configured delays. Emails are queued in a dedicated database table and dispatched via the WordPress cron system.

How It Works

  1. Cron job storzen_cr_check_abandoned runs every 5 minutes and finds carts past the inactivity threshold.
  2. For each newly-abandoned cart with a valid email, two queue rows are created — one per email step, with their respective scheduled_at timestamps.
  3. Cron job storzen_cr_send_queue runs every 5 minutes and dispatches pending emails whose scheduled time has passed.
  4. If the customer completes checkout before all emails fire, remaining emails are automatically cancelled.
💡
Cancellation logic When a cart transitions to recovered, all pending email queue rows for that cart are set to status cancelled. The customer never receives reminder emails after they've already purchased.

Configuring the Sequence

Each of the two email steps has its own configuration block under Settings → Email Sequence:

FieldDescriptionDefault
enabledPer-step toggle to enable or disable this specific emailtrue
subjectEmail subject line (supports placeholders like {first_name})"You left something behind"
templateWhich of the bundled templates to use (Template 1 or Template 2)template_1
delay_hoursHours after abandonment before this email is sent1 (step 1), 24 (step 2)
07 — Email Templates

Recovery Email Templates

The plugin ships with two responsive, mobile-ready HTML email templates. Both are pre-styled and personalised with the customer's name, cart items, prices, store logo, and a recovery CTA button.

Template 1 — Friendly Reminder

Soft, friendly tone. Good for the first email (1h after abandonment). Subject line: "Hey [Name], you left something behind!"

Template 2 — Urgency Reminder

Direct, urgency-focused tone with red CTA. Good for the second email (24h after abandonment). Subject line: "[Name], your cart is still waiting!"

Template Preview

Go to Cart Recovery → Email Templates to preview both templates side by side, with desktop and mobile viewport toggle. The preview uses sample data — real emails will use actual customer names and cart items.

Template includes Personalised customer name · Cart items with product images and prices · Cart total · One-click recovery link · Open tracking pixel · Store logo · Responsive design
09 — Analytics Dashboard

The Dashboard

The Dashboard gives you an at-a-glance view of your recovery performance. All metrics are computed from the plugin's own database tables — no external analytics service is contacted.

KPI Cards

MetricWhat it Means
AbandonedTotal cart count with status abandoned or lost
RecoveredTotal cart count with status recovered
Recovery RateRecovered ÷ (Abandoned + Recovered) × 100
Revenue RecoveredSum of cart totals for all recovered carts
Revenue At RiskSum of cart totals for currently-abandoned carts (still recoverable)
Active NowCarts currently being browsed (status active)

30-Day Trend Chart

An inline SVG chart shows abandoned vs. recovered carts per day for the past 30 days. The chart is rendered via the bundled storzen-cr-chart.js library — no Chart.js or external CDN dependency.

Recent Activity Feed

The Dashboard's right column lists the 5 most recently abandoned carts with customer name (or "Guest"), email, cart value, status badge, and time-ago label. Click any row to jump to that cart's detail in the Abandoned Carts list.

10 — Exit-Intent Popup

Exit-Intent Email Capture

The optional exit-intent popup triggers when a visitor with items in their cart moves their cursor toward the browser close button (or, on mobile, scrolls up fast). It captures the email address before they leave, even if they never reach the checkout page.

Enabling the Popup

Go to Cart Recovery → Settings → General → Tracking Scope and toggle Enable Exit-Intent Popup. Once enabled:

  • Popup loads only on pages that have a non-empty WooCommerce cart
  • Triggers once per session (no repeat annoyance)
  • Can be dismissed; dismissal is remembered for the session
  • Captured email is immediately associated with the current cart
💡
Customise the popup The popup uses standard WordPress hooks. Filter storzen_cr_exit_popup_html to replace the markup with your own design, or use CSS overrides on .storzen-cr-exit-popup for styling tweaks.
11 — Settings Reference

All Settings Explained

General Tab

FieldDescriptionDefault
inactivity_thresholdMinutes of cart inactivity before the cart is marked abandoned60
retention_daysHow many days to keep abandoned cart records before auto-purge30
track_guestsWhether to track carts from guest (logged-out) visitorstrue
track_logged_inWhether to track carts from logged-in customerstrue
enable_exit_popupShow the exit-intent email capture popupfalse
excluded_rolesUser roles to exclude from tracking (multi-select)["administrator"]

Email Sequence Tab

FieldDescriptionDefault
from_name"From" name shown in customer's inboxSite title
from_email"From" email address (use your store's domain)admin_email
reply_toOptional Reply-To address(blank — uses from_email)
enable_sequenceMaster toggle for the entire recovery sequencetrue
step_1.delay_hoursHours after abandonment to send email 11
step_2.delay_hoursHours after abandonment to send email 224
12 — Hooks & Filters

Developer Hooks

The plugin exposes several hooks so you can extend behaviour without editing core files.

Actions

storzen_cr_cart_abandoned
Fires when a cart is marked as abandoned and emails are about to be queued.
$cart_id (int) — the cart row ID,   $cart_token (string) — the unique cart token
storzen_cr_cart_recovered
Fires when an abandoned cart is recovered (order placed). Useful for logging, analytics, or external CRM sync.
$cart_id (int),   $cart_token (string),   $order_id (int)
storzen_cr_email_sent
Fires immediately after a recovery email is successfully dispatched via wp_mail().
$cart_id (int),   $email_id (int — queue row ID),   $step (int — 1 or 2)
storzen_cr_recovery_link_clicked
Fires when a customer clicks a recovery link and the cart is restored, before the redirect to checkout.
$cart_token (string),   $email_id (int — 0 if not email-triggered)

Filters

storzen_cr_should_track_cart
Return false to skip tracking the current cart (e.g. test orders, internal users).
$should_track (bool, default true),   $cart (WC_Cart)
storzen_cr_email_subject
Modify the email subject line before sending. Useful for A/B testing or appending the customer's name.
$subject (string),   $cart (object),   $step (int)
storzen_cr_email_body_html
Filter the full HTML body of the recovery email. Returns the rendered template string before it's passed to wp_mail().
$html (string),   $cart (object),   $step (int)
storzen_cr_recovery_url
Modify the final recovery URL before it's embedded in the email body.
$url (string),   $cart_token (string),   $email_id (int)
13 — Database Schema

Database Tables

The plugin creates three custom tables on activation via dbDelta(). All tables use the {wp_prefix}storzen_cr_ namespace.

{prefix}_storzen_cr_carts

Primary cart capture table. One row per tracked cart.

CREATE TABLE {prefix}_storzen_cr_carts (
  id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  cart_token     VARCHAR(64)  NOT NULL UNIQUE,
  user_id        BIGINT UNSIGNED NULL,
  email          VARCHAR(190) NULL,
  first_name     VARCHAR(190) NULL,
  last_name      VARCHAR(190) NULL,
  cart_contents  LONGTEXT     NULL,
  cart_total     DECIMAL(20,4) DEFAULT 0,
  currency       VARCHAR(10)  NULL,
  status         VARCHAR(20)  DEFAULT 'active',
  ip_address     VARCHAR(45)  NULL,
  user_agent     TEXT         NULL,
  abandoned_at   DATETIME     NULL,
  recovered_at   DATETIME     NULL,
  created_at     DATETIME     NOT NULL,
  updated_at     DATETIME     NOT NULL,
  INDEX (status), INDEX (email), INDEX (updated_at)
);

{prefix}_storzen_cr_email_queue

Email queue table. One row per scheduled recovery email.

CREATE TABLE {prefix}_storzen_cr_email_queue (
  id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  cart_id        BIGINT UNSIGNED NOT NULL,
  step           TINYINT UNSIGNED NOT NULL,
  subject        VARCHAR(190) NOT NULL,
  template       VARCHAR(50)  NOT NULL,
  status         VARCHAR(20)  DEFAULT 'pending',
  scheduled_at   DATETIME     NOT NULL,
  sent_at        DATETIME     NULL,
  created_at     DATETIME     NOT NULL,
  INDEX (status, scheduled_at), INDEX (cart_id)
);

{prefix}_storzen_cr_events

Event log table. One row per recovery event (email opened, link clicked, etc.).

CREATE TABLE {prefix}_storzen_cr_events (
  id             BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  cart_id        BIGINT UNSIGNED NOT NULL,
  email_id       BIGINT UNSIGNED NULL,
  event_type     VARCHAR(50)  NOT NULL,
  event_data     LONGTEXT     NULL,
  created_at     DATETIME     NOT NULL,
  INDEX (cart_id, event_type)
);
Clean uninstall When the plugin is deleted via the Plugins screen (not just deactivated), uninstall.php drops all three tables and removes all plugin options. Deactivation alone preserves data.
14 — Privacy & GDPR

Privacy & Data Handling

The plugin is designed to be privacy-respecting by default. All data stays on your server and is never transmitted to the plugin author or any third party.

Data Collected

  • Cart contents (products and quantities)
  • Customer email, first name, last name (captured at checkout or via the optional exit-intent popup)
  • Visitor IP address (for abandonment analytics; configurable retention)
  • User agent string (for device analytics)
  • Email open and recovery-link click timestamps

Data Retention

Abandoned cart records are automatically deleted after the configured retention period (default: 30 days). You can change this under Settings → General → Retention Period. Recovered cart records are kept indefinitely for reporting.

Personal Data Export & Erase

The plugin integrates with WordPress's built-in Tools → Export Personal Data and Tools → Erase Personal Data features. When an admin runs these tools for a specific email address, the plugin includes / removes all matching cart and event records.

⚠️
Update your Privacy Policy Mention in your site's Privacy Policy that you collect cart contents, email, name, and IP address for the purpose of cart recovery, and that this data is stored on your server, deleted automatically after the retention period, and never sent to external services.
15 — FAQ

Frequently Asked Questions

Does this work without WooCommerce?
No. WooCommerce is a hard dependency — the plugin captures WooCommerce cart contents and integrates with WooCommerce order events. The plugin uses the Requires Plugins: woocommerce header so WordPress will block activation if WooCommerce is missing.
Will guest cart tracking work?
Yes. The plugin tracks both guest and logged-in carts. Guests are identified by a cookie-bound cart token. As soon as the guest enters their email (at checkout, in the exit-intent popup, or by logging in), that email is attached to the existing cart row.
Are recovery emails sent via wp_mail()?
Yes. The plugin uses standard wp_mail() for all outgoing emails, so any deliverability plugin (SMTP, SendGrid, Mailgun, Postmark, etc.) automatically applies. We recommend a transactional email service for production stores to maximise inbox placement.
Does WP-Cron handle the queue reliably enough?
WP-Cron is fine for low-to-moderate traffic stores. For high-traffic stores or strict timing requirements, we recommend disabling WP-Cron and configuring a real system cron job to hit wp-cron.php every 5 minutes. The plugin's cron handlers are designed to be idempotent — they're safe to run more often without causing duplicate emails.
How do recovery links survive long retention periods?
Recovery links use HMAC-SHA256 signatures based on a per-cart token and your site's secret salt (wp_salt('auth')). They don't rely on session data or WP nonces, so they remain valid as long as the cart record exists in the database — typically the full retention window.
Will this plugin slow down my store?
No. Cart tracking happens via lightweight AJAX calls that don't block page rendering. Database queries are indexed on status, email, and updated_at columns. The dashboard's analytics queries are scoped to the plugin's own tables and don't touch wp_posts or order tables. Admin assets are loaded only on the plugin's own admin pages.
Is the plugin HPOS compatible?
Yes. The plugin declares compatibility with WooCommerce High-Performance Order Storage via FeaturesUtil::declare_compatibility( 'custom_order_tables' ). Order matching for recovery uses the WooCommerce CRUD API, which automatically targets the right storage backend (HPOS or legacy).
Is the plugin translation ready?
Yes. All user-facing strings use the storzen-cart-recovery-for-woocommerce text domain and a .pot file is included in languages/. The plugin works with Loco Translate, WPML, Polylang, and standard .po / .mo file workflows.
What happens to data when I uninstall the plugin?
The uninstall.php file removes all plugin options and drops the three custom tables when the plugin is deleted via the Plugins screen. Deactivating (without deleting) preserves everything so you can reactivate later without losing data.
How do I get support?
Free support is available on the WordPress.org support forum. Please include your WordPress version, WooCommerce version, PHP version, active theme name, and a clear description of the issue when posting.