10 min de lecturacarritos abandonadosWooCommerceconversiónanalítica ecommerce

Carritos abandonados en WooCommerce: qué se recupera de verdad

Medido en una tienda WooCommerce real: de la búsqueda al pedido pasan 7,5 minutos de mediana, y el 90 % de los pedidos ocurre en la primera hora. El correo de carrito abandonado llega cuando ya se decidió. Aquí está dónde se pierde de verdad, y cómo leer hoy los carritos que ya tienes guardados en tu base de datos.

El correo de carrito abandonado es de lo primero que te recomienda cualquiera cuando dices que tu tienda no convierte. Se instala un plugin, se programa a la hora, y a esperar.

He medido cuánto tarda de verdad una persona en comprar. Y el resultado deja el correo de la hora en un sitio incómodo.

Esto son 40.770 búsquedas y 170 pedidos de una tienda WooCommerce real de coleccionismo, entre el 10 de julio y el 28 de agosto de 2026 — 50 días. Para cada pedido he medido el tiempo entre la primera búsqueda de esa persona y el momento en que el pedido quedó registrado:

Desde la primera búsqueda Pedidos %
Menos de 10 minutos 96 56 %
Dentro de la primera hora 153 90 %
Más de 4 horas 8 4,7 %

Mediana: 7 minutos y medio. Percentil 90: 59 minutos.

Es decir: cuando el correo de carrito abandonado sale a la hora, nueve de cada diez personas que iban a comprar ya han comprado. No las rescata: les manda un recordatorio de algo que ya hicieron. Y el resto, en su inmensa mayoría, no volvió nunca.

Por qué esto no es un fallo del correo

El correo de carrito abandonado no está mal hecho. Está pensado para otra cosa.

Funciona bien cuando la compra es cara y meditada —un sofá, un portátil, un viaje—, porque ahí la gente sí se toma dos días. Pero en una tienda de ticket medio bajo, con un catálogo que se navega en cinco minutos, la decisión entera cabe en el tiempo que tarda en salir el primer correo.

Ojo con lo que esto significa y con lo que no:

  • No significa que el correo de carritos abandonados no sirva nunca.
  • Sí significa que antes de instalarlo deberías saber en qué ventana de tiempo compra tu gente. Si tu mediana también son minutos, ese plugin va a competir contra un botón de comprar que ya estaba en pantalla.

Cómo medirlo en tu tienda está más abajo, y no hace falta comprar nada.

El agujero está antes del carrito

Y aquí viene la parte que de verdad cambia dónde poner el esfuerzo.

En esos mismos 50 días, 2.949 sesiones hicieron clic en un producto después de buscarlo. Gente que escribió lo que quería, vio resultados y entró en una ficha. Intención de compra sin ninguna ambigüedad.

131 acabaron en pedido. Las otras 2.818 se fueron: el 95,6 %.

La mayoría de esas 2.818 nunca llegó a añadir nada al carrito. Y eso tiene una consecuencia que se pasa por alto: no aparecen en ningún informe de carritos abandonados. Ese informe solo ve a quien llegó a poner algo dentro. Todo el que se cayó antes —el que no encontró su talla, el que no vio el precio de envío, el que buscó y no le salió nada— es invisible ahí.

Estás mirando el último escalón de una escalera de la que la gente se cae en el segundo.

Tus carritos abandonados ya están en tu base de datos

Esto casi nadie lo cuenta, y es lo más útil del artículo: WooCommerce ya guarda los carritos vivos. No hace falta plugin para verlos.

Están en la tabla wp_woocommerce_sessions, con tres columnas: session_key, session_value y session_expiry. Lo he comprobado hoy en el código de WooCommerce, en includes/class-wc-session-handler.php. Dos detalles que importan:

  • Cuánto duran. La sesión caduca a los 2 días si el visitante es anónimo, y a la semana si tenía la sesión iniciada. Pasado eso, WooCommerce la borra. Tienes una ventana, no un histórico.
  • Cómo están guardados. session_value es un array serializado, y cada valor de dentro está serializado otra vez. Hay que deshacerlo dos veces. Es la razón por la que casi todo el mundo que abre esa tabla a pelo se rinde a los diez segundos.

Para saber cuántos tienes ahora mismo, una línea:

SELECT COUNT(*) FROM wp_woocommerce_sessions WHERE session_value LIKE '%s:4:"cart"%';

(Cambia wp_ por el prefijo de tus tablas si lo tienes distinto.)

Y para verlos de verdad —con lo que llevan dentro, cuánto valen y quién es— guarda esto como wp-content/mu-plugins/carritos-vivos.php. La carpeta mu-plugins la puedes crear si no existe, y lo que hay dentro se activa solo. Te añade una pantalla nueva bajo el menú de WooCommerce:

<?php
/**
 * Plugin Name: Carritos vivos
 * Description: Lista los carritos que hay ahora mismo en la tabla de sesiones de WooCommerce.
 */

add_action('admin_menu', function () {
    add_submenu_page(
        'woocommerce',
        'Carritos vivos',
        'Carritos vivos',
        'manage_woocommerce',
        'carritos-vivos',
        'wr_pantalla_carritos_vivos'
    );
});

function wr_pantalla_carritos_vivos() {
    global $wpdb;

    $filas = $wpdb->get_results(
        "SELECT session_key, session_value, session_expiry
         FROM {$wpdb->prefix}woocommerce_sessions"
    );

    $carritos = [];

    foreach ($filas as $fila) {
        $sesion = maybe_unserialize($fila->session_value);
        if (!is_array($sesion) || empty($sesion['cart'])) {
            continue;
        }

        // Cada valor de la sesión va serializado por separado: hay que deshacerlo dos veces.
        $cart = maybe_unserialize($sesion['cart']);
        if (!is_array($cart) || !$cart) {
            continue;
        }

        $valor  = 0.0;
        $lineas = [];

        foreach ($cart as $item) {
            $id = !empty($item['variation_id']) ? $item['variation_id'] : ($item['product_id'] ?? 0);
            $producto = $id ? wc_get_product($id) : null;
            if (!$producto) {
                continue;
            }
            $cantidad = (int) ($item['quantity'] ?? 0);
            $valor   += (float) $producto->get_price() * $cantidad;
            $lineas[] = $cantidad . ' × ' . $producto->get_name();
        }

        if (!$lineas) {
            continue;
        }

        // session_key es el ID de usuario cuando la sesión estaba iniciada.
        $usuario = is_numeric($fila->session_key) ? get_user_by('id', $fila->session_key) : null;

        $carritos[] = [
            'valor'  => $valor,
            'que'    => implode(', ', $lineas),
            'quien'  => $usuario ? $usuario->user_email : 'anónimo',
            'caduca' => date_i18n('j M H:i', (int) $fila->session_expiry),
        ];
    }

    usort($carritos, fn($a, $b) => $b['valor'] <=> $a['valor']);

    echo '<div class="wrap"><h1>Carritos vivos (' . count($carritos) . ')</h1>';
    echo '<table class="widefat striped"><thead><tr>
            <th>Valor</th><th>Qué lleva</th><th>Quién</th><th>Caduca</th>
          </tr></thead><tbody>';

    foreach ($carritos as $c) {
        printf(
            '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>',
            wc_price($c['valor']),
            esc_html($c['que']),
            esc_html($c['quien']),
            esc_html($c['caduca'])
        );
    }

    echo '</tbody></table></div>';
}

Cinco minutos, cero euros, y tienes la lista ordenada por valor.

Un aviso honesto sobre esa lista: un carrito vivo no es necesariamente un carrito abandonado. Puede ser alguien que está comprando ahora mismo. Lo que sí es seguro es lo contrario: cuando se completa un pedido, WooCommerce vacía el carrito, así que lo que queda ahí dentro es, por definición, todo lo que no se ha comprado todavía.

Qué hacer con esa lista

Miradla dos veces por semana durante quince días. Se aprenden tres cosas, y ninguna requiere un plugin:

  1. Qué productos aparecen una y otra vez. Un producto que entra mucho en carritos y sale poco en pedidos tiene un problema concreto y localizable: el envío, el plazo, una talla agotada, una foto.
  2. Cuánto valen. Si la suma de tus carritos vivos es cuarenta euros, esto no es tu problema y hay que mirar más arriba en el embudo. Si son mil, ya sabes qué priorizar.
  3. Quién estaba identificado. Esos tienen email, y a esos sí les puedes escribir a mano. Escribir diez correos a mano enseña más en una semana que una secuencia automática en tres meses, porque te contestan y te dicen por qué no compraron.

Y luego, lo que de verdad mueve la aguja según los números de arriba: si la decisión se toma en los diez primeros minutos, el arreglo tiene que estar dentro de esos diez minutos. No en el correo de después. El coste de envío visible antes del carrito, el plazo de entrega en la ficha, el stock real, y que se encuentre lo que se busca a la primera.

Cuántas tiendas tienen esto puesto

Un contexto que me pareció revelador, comprobado hoy, 29 de agosto de 2026, en la API de WordPress.org:

Instalaciones activas
WooCommerce 7.000.000
Cart Abandonment Recovery for WooCommerce (el plugin de carritos abandonados más instalado) 300.000
Abandoned Cart Lite for WooCommerce 20.000

El más instalado de la categoría está en el 4 % de las tiendas WooCommerce. No lo cuento como crítica al plugin, que está bien valorado: lo cuento porque si estabas convencido de que todo el mundo menos tú tiene esto montado, no es el caso. Y porque el 96 % restante tiene sus carritos guardados en la tabla de sesiones sin saberlo.

Cómo medir tu propia ventana de decisión

Los números de arriba son de una sola tienda, de coleccionismo, con un ticket medio de unos 67 €, y salen de las sesiones que pasaron por su buscador — no de todo el tráfico. Tu tienda será distinta, y ese es justo el motivo por el que conviene medirla en vez de creerse la mía.

Lo mínimo para tenerlo: la hora de la primera interacción de cada cliente y la hora de su pedido. Con otro mu-plugin de diez líneas que anote la primera visita de cada usuario identificado ya lo tienes:

<?php
/**
 * Plugin Name: Primera visita
 * Description: Anota cuándo empezó cada sesión de compra de un usuario identificado.
 */

add_action('wp', function () {
    if (is_admin() || !is_user_logged_in()) {
        return;
    }

    $clave = 'wr_primera_visita_' . gmdate('Y-m-d');
    if (get_user_meta(get_current_user_id(), $clave, true) === '') {
        update_user_meta(get_current_user_id(), $clave, current_time('mysql', true));
    }
});

Déjalo un mes y luego cruza esa marca con los pedidos. En WooCommerce moderno los pedidos viven en la tabla wp_wc_orders:

SELECT
  COUNT(*) AS pedidos,
  ROUND(AVG(TIMESTAMPDIFF(MINUTE, um.meta_value, o.date_created_gmt)), 1) AS media_min,
  SUM(TIMESTAMPDIFF(MINUTE, um.meta_value, o.date_created_gmt) <= 60) AS en_1h
FROM wp_wc_orders o
JOIN wp_usermeta um
  ON um.user_id = o.customer_id
 AND um.meta_key = CONCAT('wr_primera_visita_', DATE(o.date_created_gmt))
WHERE o.status IN ('wc-processing', 'wc-completed')
  AND o.date_created_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 60 DAY);

(Si tu tienda es antigua y no usa el almacenamiento nuevo de pedidos, cambia wp_wc_orders o por wp_posts o con o.post_type = 'shop_order', o.post_date_gmt en vez de o.date_created_gmt, y saca el customer_id del meta _customer_user. Y cambia wp_ por tu prefijo si lo tienes distinto.)

Lo que te importa de ahí es en_1h contra pedidos. Si la mayoría de tus pedidos entra dentro de la primera hora, el correo de carrito abandonado programado a la hora llega tarde por diseño en tu tienda, igual que en esta.

Dos advertencias para no engañarte a ti mismo con este número: solo cuenta a los clientes identificados —los que compran como invitados no dejan esta marca— y conviene mirar la mediana más que la media, porque cuatro rezagados que compran al día siguiente te la disparan. Con las cifras de arriba se ve bien: media 56,8 minutos, mediana 7,5.


Por orden, lo que yo haría:

  1. Pega el mu-plugin de carritos vivos. Es la lista que ya tenías y no estabas mirando.
  2. Mírala dos veces por semana, quince días. Anota qué productos se repiten.
  3. Mide tu ventana de decisión. Si tu mediana son minutos, deja de invertir en la secuencia de correos y arregla lo que pasa en pantalla.
  4. Sube un escalón. El informe de carritos abandonados solo ve a quien llegó a añadir algo. En esta tienda, por cada persona que acabó comprando había 21 que habían entrado en una ficha de producto y se fueron antes. Ese escalón es más grande, y casi nadie lo mira.

Ese último punto es el que más sorprende cuando se pone en números: de 2.949 sesiones con intención clara, 2.818 se fueron sin llegar al carrito. Buena parte de esa caída empieza en el sitio más tonto —no encontrar lo que se busca—, y eso sí se mide y se arregla. Está la guía completa de cómo elegir un buscador para ecommerce, con los precios de cada opción comprobados, y cuánto te cuesta el buscador de tu ecommerce, con los datos de pedidos de esta misma tienda. Y si quieres ver de dónde salen estos números, están en WildRock.

¿Tu tienda pierde ventas por búsquedas que no encuentran nada?

WildRock añade a tu WooCommerce un buscador que entiende lo que tus clientes quieren decir, y te dice en euros cuánto te está generando. Plugin gratuito, sin tocar código.