Skip to content 📞 Book Free Call Now
Blog

WooCommerce Abandoned Cart Recovery Without Plugins (Step-by-Step)

By Rajan Gupta

⏱ 6 min read

WooCommerce Abandoned Cart Recovery (Email + Auto Restore Cart)

Abandoned carts are one of the biggest silent revenue killers for WooCommerce stores. Customers add products, reach checkout, enter their email… and then disappear.

The good news? You can recover 15–30% of those lost orders using a smart abandoned cart recovery flow — without using any plugin.

In this guide, you’ll learn exactly how WooCommerce abandoned cart recovery works, why most setups fail, and how to build a production-ready solution with:

  • Automated abandoned cart emails
  • Restore cart links (no empty cart issue)
  • Auto-apply coupon logic
  • Guest + logged-in user support
  • Cron-based email scheduling

WooCommerce Abandoned Cart Recovery

What Is an Abandoned Cart in WooCommerce?

A cart is considered abandoned when a user:

  • Adds products to the cart
  • Reaches checkout or cart page
  • Leaves the website without completing payment

In WooCommerce, this happens very frequently, especially on mobile devices.

Common reasons include:

  • Unexpected shipping cost
  • Distraction or interruption
  • No coupon or discount
  • Slow checkout experience
  • Just “thinking about it”

Why WooCommerce Abandoned Cart Recovery Is Important

Here’s why abandoned cart recovery is critical:

  •  Average cart abandonment rate: 70%+
  •  Recovery emails can convert 5–30% of lost carts
  •  Email has the highest ROI among marketing channels

Even recovering 10% of abandoned carts can significantly boost monthly revenue.

How WooCommerce Abandoned Cart Recovery Works

At a high level, the flow looks like this:

  1. User adds product to cart
  2. Email is captured (guest or logged-in)
  3. Cart data is stored in database
  4. User leaves the site
  5. Automated email is sent after delay
  6. Email contains a restore-cart link
  7. Cart is rebuilt when user clicks
  8. Coupon is auto-applied (optional)

This approach works even for guest users, which is where most abandoned carts come from.

WooCommerce Abandoned Cart Recovery Without Plugin

Most abandoned cart plugins:

  • Are heavy
  • Slow down checkout
  • Conflict with themes
  • Break sessions
  • Lock features behind paid plans

A custom code-based solution gives you:

  • Full control
  • Better performance
  • No recurring costs
  • Clean data handling

And yes — WooCommerce provides enough hooks to do this properly.

Capturing Email for Guest Users

WooCommerce does not automatically save guest emails until order creation.

To recover guest carts, we capture the email when the user:

  • Enters it on checkout

This allows abandoned cart tracking before payment.

Logged-in users are handled automatically using their account email.

 

email after 1 hour

email with coupon after 24 hour

Storing Cart Data Safely

A common mistake is relying on WooCommerce sessions.

Sessions expire, regenerate, and break — causing the infamous:

❌ “Empty cart after clicking email link”

Instead, the correct approach is:

  • Generate a persistent cart key (email hash)
  • Store cart data in WordPress options or custom table
  • Restore cart using that key

This guarantees cart restoration every time.

Sending Abandoned Cart Emails Automatically

Emails are sent using WordPress cron:

  • First reminder → after 1 hour
  • Second reminder → after 24 hours

For testing, delays can be reduced to minutes.

Each email includes:

  • Friendly reminder copy
  • Cart summary
  • Clear CTA button
  • Optional discount incentive


add_action('wp_ajax_save_guest_email', 'save_guest_email');
add_action('wp_ajax_nopriv_save_guest_email', 'save_guest_email');

function save_guest_email() {
    if (!empty($_POST['email'])) {
        WC()->session->set('guest_email', sanitize_email($_POST['email']));
    }
    wp_die();
}

add_action('woocommerce_after_checkout_validation', function ($data) {
    if (!empty($data['billing_email'])) {
        WC()->session->set('guest_email', sanitize_email($data['billing_email']));
    }
}, 10, 1);

add_action('woocommerce_cart_updated', 'store_abandoned_cart');

function store_abandoned_cart() {
    if (WC()->cart->is_empty()) return;

    $session_id = WC()->session->get_customer_id();
    if (!$session_id) return; 

    $user_id = get_current_user_id();
    $email = '';

    if ($user_id) {
        $user = get_user_by('id', $user_id);
        $email = $user->user_email;
    } else {
        $email = WC()->session->get('guest_email');
    }

    if (!$email) return;

    $existing = get_option('abandoned_cart_' . $session_id);

    $cart_data = [
        'session_id'  => $session_id, 
        'email'       => $email,
        'cart'        => WC()->cart->get_cart(),
        'time'        => $existing['time'] ?? time(),
        'first_sent'  => $existing['first_sent'] ?? false,
        'second_sent' => $existing['second_sent'] ?? false,
    ];

    update_option('abandoned_cart_' . $session_id, $cart_data);
}


add_action('wp', function () {
    if (!wp_next_scheduled('send_abandoned_cart_reminders')) {
        wp_schedule_event(time(), 'hourly', 'send_abandoned_cart_reminders');
    }
});


add_action('send_abandoned_cart_reminders', 'send_cart_reminder_emails');

function send_cart_reminder_emails() {
    $options = wp_load_alloptions();

    foreach ($options as $key => $value) {
        if (strpos($key, 'abandoned_cart_') === false) continue;

        $session_id = str_replace('abandoned_cart_', '', $key);
        $data = maybe_unserialize($value);
        if (!$data || empty($data['cart'])) continue;

        $now = time();
        if (!$data['first_sent'] && ($now - $data['time']) >= 3600) {

            set_transient('ac_session_' . md5($data['email'] . $data['time']), $session_id, 3600);

            wp_mail(
                $data['email'],
                '🛒 Still thinking? Your cart is waiting',
                abandoned_cart_email_template($data, false),
                ['Content-Type: text/html; charset=UTF-8']
            );

            $data['first_sent'] = true;
            update_option($key, $data);
            continue;
        }

    
        if ($data['first_sent'] && !$data['second_sent'] && ($now - $data['time']) >= 86400) {

            set_transient('ac_session_' . md5($data['email'] . $data['time']), $session_id, 3600);

            wp_mail(
                $data['email'],
                '🎁 Extra 10% OFF – Complete your order',
                abandoned_cart_email_template($data, true),
                ['Content-Type: text/html; charset=UTF-8']
            );

            $data['second_sent'] = true;
            update_option($key, $data);
        }

        // Cleanup after 2 emails
        if ($data['first_sent'] && $data['second_sent']) {
            delete_option($key);
            // Cleanup transient too
            delete_transient('ac_session_' . md5($data['email'] . $data['time']));
        }
    }
}

function abandoned_cart_email_template($data, $with_coupon = false) {
    $coupon = 'abessenceig10';
    $session_id = get_transient('ac_session_' . md5($data['email'] . $data['time'])) ?: $data['session_id'];

    ob_start(); ?>
    Email Html
    
    

Yes, using cron-based emails and restore cart links.

Can I send abandoned cart emails without a plugin?
Absolutely. WooCommerce hooks are enough.

Does this work for guest users?
Yes, as long as email is captured.

Can coupons be auto-applied?
Yes, via URL-based coupon logic.

Need Help Implementing This on Your WooCommerce Store?

Recover lost WooCommerce sales automatically with abandoned cart emails, restore-cart links, and coupon automation — fully set up and tested on your store. Need this implemented on your store? Contact Us for Setup

For Store Owners & Admins

If you’re a WooCommerce store admin, you don’t need to worry about daily monitoring or manual follow-ups. Once this abandoned cart recovery system is set up, it runs automatically in the background — capturing carts, sending reminder emails, restoring items, and applying coupons without any ongoing effort from your side. You’ll simply start seeing recovered orders come through your store.

admin can check email open or not

As an admin, you can review abandoned cart behavior, validate email delivery, and test the full recovery flow without affecting live customers. The system is designed to be safe for production stores, excludes admin carts automatically, and works reliably for both guest and logged-in users — giving you full confidence before and after going live.


Need help setting up or optimizing your WooCommerce abandoned cart recovery system? Let’s boost your store’s conversions together — Contact us today!

Rajan Gupta

Rajan Gupta

FullStack Web Developer

Rajan Gupta is a passionate web developer and digital creator who loves sharing insights on WordPress, modern web design, and performance optimization. When not coding, they enjoy exploring the latest tech trends and helping others build stunning, high-performing websites.

Related Articles