En una tienda de repuestos y maquinaria, el carrito abandonado es el pan de cada día: el cliente cotiza, compara con la competencia y se va. Los plugins comerciales que resuelven esto cuestan entre 5 y 20 USD al mes por tienda, y casi todos hacen lo mismo por debajo. Para la tienda de Motormaq preferí escribirlo a medida dentro de un plugin propio, y el módulo completo quedó en unos cientos de líneas de PHP.
WooCommerce ya guarda la sesión del carrito; lo que falta es asociarla a un correo antes de que el cliente llegue al checkout. Dos fuentes:
updated_checkout + un endpoint AJAX) y guarda el carrito serializado en una tabla propia con su timestamp.Un cron de WordPress revisa cada hora los carritos sin orden asociada. Si pasaron más de N horas (en mi caso 3), se considera abandonado.
El correo de "se te quedó algo en el carrito" sin incentivo recupera poco. Lo que funciona es un cupón único, personal y con fecha de vencimiento corta:
$coupon = new WC_Coupon();
$coupon->set_code( 'VUELVE-' . strtoupper( wp_generate_password( 6, false ) ) );
$coupon->set_discount_type( 'percent' );
$coupon->set_amount( 5 );
$coupon->set_usage_limit( 1 );
$coupon->set_email_restrictions( [ $correo_cliente ] );
$coupon->set_date_expires( strtotime( '+7 days' ) );
$coupon->save();
El detalle importante es set_email_restrictions: el cupón solo funciona con el correo del cliente que abandonó, así no termina circulando en grupos de ofertas.
Un solo correo, simple, con la lista de productos, el cupón y un botón que restaura el carrito con un clic (un enlace con token que reconstruye la sesión desde la tabla). Evité las secuencias de 3 correos: para productos técnicos, el segundo y tercer correo aportan poco y queman la lista.
El módulo marca cada carrito como recuperado si aparece una orden del mismo correo dentro de los 7 días siguientes, use o no el cupón. Ese matiz importa: parte de la recuperación habría ocurrido igual, y si solo mides usos del cupón te cuentas el cuento.