Cómo detectar y corregir inconsistencias de SKUs duplicados entre WooCommerce y ERP sin perder pedidos

Por · Publicado el · 9 min de lectura

Pasillo entre estanterías metálicas con cajas y carpetas almacenadas
Estanterías y cajas en depósito — imagen que evoca control de stock e inventario Foto: Pexels / Pixabay

Un SKU duplicado entre WooCommerce y el ERP provoca pedidos perdidos, artículos incorrectos y discrepancias de stock. Aprende a detectar y corregir inconsistencias de SKUs duplicados entre WooCommerce y ERP sin perder pedidos: diagnóstico SQL, criterios de decisión y scripts de ajuste, con un plan seguro que mantiene la operación en marcha.

Señales de SKUs duplicados y riesgos reales

La duplicidad de SKU suele aparecer en momentos críticos: cierre de caja, integración con marketplace o en el pico de una campaña. Detectarla temprano reduce el impacto en pedidos y stock.

Revisa indicios prácticos que apuntan a conflictos de SKUs y por qué ocurren.

  • Pedidos facturados con un artículo distinto al del carrito (SKU A en el pedido, pero se separó SKU B).
  • Stock negativo o overselling tras integraciones por lotes desde el ERP.
  • Pedidos rechazados por el ERP por “producto inexistente” aun cuando el SKU es visible en la tienda.
  • Informes de ventas que consolidan mal por SKU (fusionando variaciones o líneas distintas).
  • Webhooks/ETL que fallan aleatoriamente al crear/actualizar ítems por colisión de clave.

Causas técnicas más comunes y quién define el SKU

Antes de corregir, define la fuente de la verdad para el SKU. Si no hay un origen único, el problema se repetirá. Fíjate también en cómo se normaliza el SKU (mayúsculas/minúsculas, espacios, guiones).

Escenarios típicos:

  • El ERP exporta el catálogo y puede contener SKUs antiguos que colisionan con nuevos.
  • WooCommerce permite crear variaciones con el mismo SKU que el producto padre.
  • Importaciones CSV/ETL sin validación de unicidad (case-insensitive).
  • Plugins que generan SKUs automáticos sin comprobar conflictos.
  • Diferencias de normalización: “abc-001”, “ABC-001” y “abc‑001 ” tratados como distintos.
Fuente maestra del SKU Cuándo usarla Riesgos si se implementa mal
ERP El ERP controla catálogo, facturación y stock de forma oficial. Un importador sin validación o un mapeo erróneo de variaciones provoca colisiones.
WooCommerce El catálogo nace en la tienda y luego se replica al ERP. Una integración que sobrescriba SKUs en el ERP puede romper el historial fiscal.
Capa de integración Existe conciliación/ETL entre sistemas con reglas de mapeo. Si la capa no impone unicidad/normalización, se convierte en otro punto de fallo.

Diagnóstico con datos: SQL y verificación cruzada

Mapea duplicidades en la base de datos de WooCommerce considerando normalización (LOWER + TRIM) y el estado de los posts. Después, cruza los resultados con reportes del ERP para confirmar qué SKUs representan ítems distintos.

Ejecuta las consultas en una copia o en staging. Haz copia de seguridad antes de aplicar ajustes.

-- 1) Encontrar SKUs duplicados (case-insensitive, ignorando espacios)
SELECT LOWER(TRIM(pm.meta_value)) AS sku_norm,
       COUNT(*) AS total
FROM wp_postmeta pm
JOIN wp_posts p ON p.ID = pm.post_id
WHERE pm.meta_key = '_sku'
  AND pm.meta_value <> ''
  AND p.post_status IN ('publish','private')
GROUP BY sku_norm
HAVING COUNT(*) > 1
ORDER BY total DESC, sku_norm;

-- 2) Listar quais itens colidem por SKU normalizado
SELECT LOWER(TRIM(a.meta_value)) AS sku_norm,
       a.post_id AS product_id,
       p.post_type,
       p.post_title
FROM wp_postmeta a
JOIN wp_posts p ON p.ID = a.post_id
WHERE a.meta_key = '_sku'
  AND LOWER(TRIM(a.meta_value)) IN (
    SELECT LOWER(TRIM(pm.meta_value))
    FROM wp_postmeta pm
    JOIN wp_posts pp ON pp.ID = pm.post_id
    WHERE pm.meta_key = '_sku' AND pm.meta_value <> ''
    GROUP BY LOWER(TRIM(pm.meta_value))
    HAVING COUNT(*) > 1
  )
ORDER BY sku_norm, product_id;

-- 3) (Opcional) Pedidos recentes impactados por SKUs duplicados
-- Observação: itens de pedido guardam meta por linha; ajuste prefixos conforme seu schema
SELECT oi.order_id,
       oim_sku.meta_value AS sku_capturado,
       oim_pid.meta_value AS product_id
FROM wp_woocommerce_order_items oi
JOIN wp_woocommerce_order_itemmeta oim_sku
  ON oim_sku.order_item_id = oi.order_item_id AND oim_sku.meta_key = '_sku'
LEFT JOIN wp_woocommerce_order_itemmeta oim_pid
  ON oim_pid.order_item_id = oi.order_item_id AND oim_pid.meta_key = '_product_id'
WHERE oim_sku.meta_value IS NOT NULL
  AND LOWER(TRIM(oim_sku.meta_value)) IN (
    SELECT LOWER(TRIM(pm.meta_value))
    FROM wp_postmeta pm
    JOIN wp_posts pp ON pp.ID = pm.post_id
    WHERE pm.meta_key = '_sku' AND pm.meta_value <> ''
    GROUP BY LOWER(TRIM(pm.meta_value))
    HAVING COUNT(*) > 1
  )
ORDER BY oi.order_id DESC
LIMIT 200;

Corrección sin perder pedidos: plan seguro

Con las duplicidades mapeadas, aplica la corrección en ventanas controladas. El objetivo es preservar la relación de los pedidos ya emitidos e impedir nuevas colisiones mientras ajustas el catálogo.

Sigue este flujo:

  • Pausar las integraciones que crean/actualizan productos (jobs, webhooks, ETL).
  • Elegir el SKU canónico por colisión (regla: mantener el que aparece en pedidos recientes).
  • Renombrar los SKUs alternativos con un sufijo técnico provisional (ej.: -ALT o -LEGADO).
  • Actualizar los mapeos en la integración/ERP hacia el SKU canónico (mantener alias temporalmente).
  • Reprocesar colas solo después de validar pedidos y stock.
  • Activar idempotencia en la importación de pedidos para evitar duplicados durante el catch-up.

Scripts de corrección: renombrar SKUs duplicados con WP-CLI

Puedes automatizar el renombrado seguro de SKUs en conflicto. El ejemplo siguiente usa WP-CLI para: identificar colisiones normalizadas, definir un canónico por SKU y renombrar los demás con un sufijo predecible. Prueba en staging y haz backup antes.

Tras la ejecución, valida con las consultas del diagnóstico y solo entonces reactiva integraciones.

<?php
/**
 * wp eval-file fix-sku-dupes.php
 * Requer: WP-CLI + WooCommerce carregado
 */

if (!defined('WP_CLI')) { exit; }

WP_CLI::add_command('sku:dedupe', function() {
  global $wpdb;

  // 1) Mapear duplicidades normalizadas
  $dupes = $wpdb->get_results("SELECT LOWER(TRIM(pm.meta_value)) AS sku_norm
    FROM {$wpdb->postmeta} pm
    JOIN {$wpdb->posts} p ON p.ID = pm.post_id
    WHERE pm.meta_key = '_sku' AND pm.meta_value <> ''
      AND p.post_status IN ('publish','private')
    GROUP BY sku_norm HAVING COUNT(*) > 1");

  foreach ($dupes as $d) {
    $rows = $wpdb->get_results($wpdb->prepare("SELECT pm.post_id, pm.meta_value AS sku
      FROM {$wpdb->postmeta} pm
      JOIN {$wpdb->posts} p ON p.ID = pm.post_id
      WHERE pm.meta_key = '_sku' AND LOWER(TRIM(pm.meta_value)) = %s
      ORDER BY p.post_date ASC", $d->sku_norm));

    if (count($rows) < 2) continue;

    // 2) Definir canônico (ex.: o mais antigo)
    $canonical = array_shift($rows); // mantém SKU original
    WP_CLI::log("Canônico para {$d->sku_norm}: #{$canonical->post_id} ({$canonical->sku})");

    // 3) Renomear restantes com sufixo previsível
    foreach ($rows as $r) {
      $new = rtrim($canonical->sku) . '-ALT-' . $r->post_id;
      update_post_meta($r->post_id, '_sku', $new);
      WP_CLI::log("Renomeado #{$r->post_id} => {$new}");
    }
  }

  WP_CLI::success('Concluído. Revise amostras e reexecute o diagnóstico.');
});

// Uso: wp sku:dedupe

Prevención: validación, colas e idempotencia

Corregir es la mitad del trabajo. Para evitar reincidencias, trata la unicidad en capas: UI/validación, integración y persistencia. Aplica normalización consistente (TRIM + UPPER/LOWER) y rechaza duplicados antes de guardar.

Puedes añadir una comprobación simple en WooCommerce para bloquear colisiones durante la edición o la importación de productos.

<?php
// Plugin mu-plugins/sku-unique-guard.php
add_action('save_post_product', 'sku_unique_guard', 10, 3);
add_action('save_post_product_variation', 'sku_unique_guard', 10, 3);

function sku_unique_guard($post_id, $post, $update) {
  if (wp_is_post_revision($post_id)) return;
  $sku = get_post_meta($post_id, '_sku', true);
  if ($sku === '' || $sku === null) return;
  global $wpdb;
  $norm = strtolower(trim($sku));
  $count = (int) $wpdb->get_var($wpdb->prepare(
    "SELECT COUNT(*) FROM {$wpdb->postmeta} pm
      JOIN {$wpdb->posts} p ON p.ID = pm.post_id
     WHERE pm.meta_key = '_sku'
       AND LOWER(TRIM(pm.meta_value)) = %s
       AND pm.post_id <> %d
       AND p.post_status IN ('publish','private','draft')",
    $norm, $post_id
  ));
  if ($count > 0) {
    // Impede colisão: aplica sufixo técnico e registra flag
    $new = trim($sku) . '-DUP-' . $post_id;
    update_post_meta($post_id, '_sku', $new);
    update_post_meta($post_id, '_sku_duplicate_flag', 1);
  }
}

Preguntas frecuentes

¿Puedo cambiar SKUs de productos ya vendidos sin romper integraciones?

Sí, siempre que mantengas un periodo de alias/mapeo en la integración y no modifiques el SKU canónico usado por pedidos recientes. Renombra los duplicados, conserva el canónico, actualiza el ERP y reprocese después de validar muestras en staging.

¿Las variaciones pueden tener el mismo SKU que el producto padre?

Técnicamente sí, pero es mala práctica. Trata cada variación como un ítem único con su propio SKU. La duplicidad confunde integraciones, informes y la separación de pedidos. Aplica validación para bloquear colisiones al guardar.

¿El SKU debe ser case-sensitive?

Para catálogos e integraciones, trata el SKU como case-insensitive y normalízalo (TRIM + UPPER/LOWER). Así evitas colisiones como “abc‑001”, “ABC‑001” y “abc‑001 ”. Aplica esta norma en la importación, en la UI y en la capa de persistencia.

¿Cómo evito pérdida de pedidos durante la corrección?

Congela integraciones, elige el SKU canónico por colisión, renombra los demás con sufijos técnicos, valida los pedidos afectados y solo entonces reactiva las colas. Usa idempotencia en la creación de pedidos para no duplicar durante el reprocesamiento.

¿Necesito una cola para sincronizar catálogo y stock?

Las colas ayudan a aislar picos y garantizar el orden de eventos. Para catálogos grandes y múltiples canales, una cola con idempotencia y reprocesamiento facilita detectar colisiones y mantener consistencia entre tienda y ERP.

¿Quieres resolver SKUs duplicados sin parar las ventas?

Revisemos el diagnóstico, las reglas de normalización y tu integración (ERP, ETL, webhooks) y preparemos un plan de corrección seguro.

Hablar sobre tu caso

Ver también