¿Productos rechazados en Google Merchant Center? Los campos de WooCommerce que hay detrás
Dos síntomas, una causa. Menos productos en el feed de los que tiene tu tienda y artículos rechazados después de subirlos se deben casi siempre a un campo del producto, y puedes encontrarlos todos desde la línea de comandos, sin instalar nada.
Google Merchant Center es donde una tienda envía su feed de productos, la lista a partir de la cual se crean las fichas de Google Shopping y los anuncios de Shopping. Por el camino fallan dos cosas distintas que, desde fuera, se parecen.
Un producto puede faltar en el feed, porque nunca llegó a exportarse: la tienda no le dio al plugin del feed nada que exportar. O puede llegar al canal y ser rechazado allí. En los dos casos el plugin del feed suele ser solo el mensajero: el requisito que falla es un campo del producto, no una línea del feed.
Saber cuál de los dos tienes ahorra un día. Si el feed simplemente tiene menos productos que tu catálogo, empieza por el precio, la disponibilidad y la visibilidad: un artículo sin precio, sin existencias u oculto en el catálogo se descarta antes de que se haga la exportación, y ningún ajuste del feed lo recuperará. Si los productos están en el feed y el canal los rechaza, empieza por las imágenes y los identificadores.
Esta página repasa esos requisitos uno a uno: qué es cada uno, qué hace que falle en un catálogo de WooCommerce y cómo detectarlo tú mismo. Cada comprobación de abajo es un comando que puedes ejecutar hoy, en tu propia tienda, sin plugins y sin cuenta.
Los porcentajes vienen de Zero clean: 72 WooCommerce stores (en
inglés), donde analizamos los catálogos públicos de 72 tiendas polacas; los datos por tienda están
publicados con licencia CC BY 4.0. Cambia wp_ por el prefijo de
tus tablas.
Precio: un artículo sin precio no es una oferta
Google exige price en cada producto. WooCommerce publica un producto con el campo del precio vacío
sin decir ni una palabra; en la tienda, simplemente no se puede comprar.
El 38 % de las tiendas tenía productos sin precio o sin forma de comprarlos: 1138 artículos. De las tres cifras que cita esta página, el informe marca esta como la menos fiable, y explica por qué.
wp db query "SELECT p.ID, p.post_title FROM wp_posts p LEFT JOIN wp_postmeta m ON m.post_id = p.ID AND m.meta_key = '_price' WHERE p.post_type = 'product' AND p.post_status = 'publish' AND (m.meta_value IS NULL OR m.meta_value = '' OR m.meta_value = '0')"
Disponibilidad: el feed dice que hay existencias y la tienda dice que no
availability tiene que coincidir con lo que el cliente encuentra de verdad. Hay dos estados que lo
impiden, y necesitan dos consultas distintas.
El primero es el sencillo, todo lo que ahora está agotado:
wp db query "SELECT p.ID, p.post_title FROM wp_posts p JOIN wp_postmeta m ON m.post_id = p.ID AND m.meta_key = '_stock_status' WHERE p.post_type = 'product' AND p.post_status = 'publish' AND m.meta_value = 'outofstock'"
El segundo es el que se esconde: un producto variable con todas sus variaciones agotadas. El producto superior sigue diciendo que hay existencias, así que en un listado y en la consulta anterior parece correcto, y el cliente que hace clic no encuentra nada que pueda meter en el carrito.
wp db query "SELECT par.ID, par.post_title FROM wp_posts par \
JOIN wp_posts v ON v.post_parent = par.ID AND v.post_type = 'product_variation' AND v.post_status = 'publish' \
JOIN wp_postmeta s ON s.post_id = v.ID AND s.meta_key = '_stock_status' \
WHERE par.post_type = 'product' AND par.post_status = 'publish' \
GROUP BY par.ID, par.post_title HAVING SUM(s.meta_value = 'instock') = 0"
Ninguna de las dos consultas sabe si el artículo llegó a venderse: para eso hacen falta las tablas de pedidos, y eso marca la diferencia entre una lista de 400 productos agotados y los cuatro que facturaban hasta que se acabaron.
Imagen: sin foto, no hay ficha
image_link es obligatorio, y tres estados distintos acaban igual: el producto no tiene ninguna
imagen, la fila de la base de datos apunta a un archivo que ya no está en el disco, o el archivo
existe pero está vacío o mide unos pocos píxeles.
El 29 % de las tiendas tenía productos sin imagen propia: 421 artículos.
wp db query "SELECT p.ID, p.post_title FROM wp_posts p LEFT JOIN wp_postmeta t ON t.post_id = p.ID AND t.meta_key = '_thumbnail_id' WHERE p.post_type = 'product' AND p.post_status = 'publish' AND (t.meta_value IS NULL OR t.meta_value = '' OR t.meta_value = '0')"
Para los otros dos, wp media regenerate --dry-run recorre la biblioteca y avisa de cada archivo
que no puede leer.
Descripción: demasiado corta para ser una oferta
description es obligatorio, y una descripción de una línea se trata como tal. Además, es el campo
que decide si quien ha hecho clic encuentra una respuesta o se va.
wp db query "SELECT ID, post_title, CHAR_LENGTH(post_content) AS caracteres FROM wp_posts WHERE post_type = 'product' AND post_status = 'publish' AND CHAR_LENGTH(post_content) < 200 ORDER BY caracteres"
Enlace: la página del producto tiene que ser accesible
link tiene que llevar a una página que el cliente pueda ver. Un producto que se vendió en el pasado
y después se ocultó del catálogo, o volvió a borrador, sigue en el origen del feed aunque su página
ya no exista.
wp db query "SELECT p.ID, p.post_title FROM wp_posts p JOIN wp_term_relationships tr ON tr.object_id = p.ID JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id JOIN wp_terms t ON t.term_id = tt.term_id WHERE p.post_type = 'product' AND p.post_status = 'publish' AND tt.taxonomy = 'product_visibility' AND t.slug = 'exclude-from-catalog'"
Un id único: dos productos, una sola identidad
Google quiere que id sea único para cada producto, y la mayoría de los plugins de feed lo asignan
al SKU. Si dos productos tienen el mismo SKU, uno de ellos pierde.
El 10 % de las tiendas tenía un SKU duplicado: 134 artículos.
wp db query "SELECT meta_value AS sku, COUNT(*) AS n 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_type IN ('product','product_variation') AND p.post_status = 'publish' GROUP BY meta_value HAVING n > 1"
Las variaciones se incluyen a propósito: un feed exporta cada variación como un artículo propio, así que, en el feed, una variación que comparte SKU con un producto es una colisión real. Conviene saberlo antes de comparar cifras con cualquier herramienta: en WooCommerce, las comprobaciones de duplicados del propio Merchlint (de SKU y de GTIN) comparan solo los productos publicados, así que pueden informar de menos pares que las dos consultas de duplicados de esta página.
Si tu tienda es multilingüe, las traducciones de un mismo producto comparten SKU legítimamente. Son un solo producto, no un duplicado: cuenta los grupos de traducción, no las entradas.
GTIN: el número que une tu oferta con el mismo producto en otros sitios
gtin es muy recomendable si existe, y mpn pasa a ser obligatorio cuando un producto no lo
tiene. En la práctica, un artículo sin ninguno de los dos suele acabar solo: sin ofertas de la
competencia en la ficha, sin opiniones y en una posición mucho más débil.
WooCommerce tiene el campo desde la 9.2: Datos del producto → Inventario → GTIN, UPC, EAN o ISBN. Nada en la administración lo señala, y nada te avisa cuando dos productos llevan el mismo número.
wp db query "SELECT p.ID, p.post_title FROM wp_posts p LEFT JOIN wp_postmeta g ON g.post_id = p.ID AND g.meta_key = '_global_unique_id' WHERE p.post_type IN ('product','product_variation') AND p.post_status = 'publish' AND (g.meta_value IS NULL OR TRIM(g.meta_value) = '')"
wp db query "SELECT TRIM(meta_value) AS gtin, COUNT(*) AS n FROM wp_postmeta pm JOIN wp_posts p ON p.ID = pm.post_id WHERE pm.meta_key = '_global_unique_id' AND TRIM(pm.meta_value) <> '' AND p.post_type IN ('product','product_variation') AND p.post_status = 'publish' GROUP BY TRIM(meta_value) HAVING n > 1"
En un producto variable, el identificador va en cada variación: cada talla y cada color es un artículo comercial distinto con su propio número, y una variación no hereda el del producto superior. Un producto superior con número y seis variaciones sin él se exporta como seis artículos sin identificador.
Si tu tienda no usa identificadores en absoluto (productos artesanales, servicios, producción propia), no hay nada que inventar, e inventar es el error más grave: un número inventado choca con un producto real en algún sitio, y la oferta se rechaza en lugar de simplemente ignorarse.
En ese caso hay una cosa que ajustar, y es del feed, no del producto. Google espera que
identifier_exists sea no cuando un artículo no tiene ni GTIN ni una combinación de MPN y marca, y
la mayoría de los plugins de feed pueden ajustarlo, como valor fijo o por producto. Lo contrario
también es una trampa: enviar no para un producto que sí tiene identificador puede hacer que lo
rechacen.
Cómo encontrar los productos sin GTIN también desde la administración, y de dónde sale el número: producto de WooCommerce sin GTIN. Para comprobar el dígito de control de una lista entera de códigos: validador de códigos EAN.
Lo que esta página no comprueba
Ser claros con los límites es la razón de ser de esta página. Estos son requisitos reales que nada de lo anterior encontrará por ti:
| Requisito | Por qué no está aquí |
|---|---|
brand | Es obligatorio para la mayoría de los productos nuevos, pero WooCommerce no tiene un único campo nativo para la marca: se guarda en una taxonomía o en un plugin, así que no hay una comprobación fiable de una línea. |
mpn | Es obligatorio cuando un producto no tiene GTIN. Por el mismo motivo: no hay campo nativo. |
| Un GTIN guardado fuera del campo propio de WooCommerce | La consulta de arriba lee _global_unique_id, el campo que WooCommerce añadió en la 9.2. Una tienda que guarda el número en otro sitio (un plugin de EAN, los campos de WooCommerce de Yoast, un atributo de producto como pa_ean) le parecerá completamente vacía. Comprueba de dónde toma gtin tu feed antes de fiarte del recuento. Y la trampa contraria: si tu plugin de feed muestra el campo de WooCommerce solo dentro de un grupo genérico de «atributos personalizados», esa lista puede estar en caché (y guardar un producto no la actualiza) o haberse creado a partir de un solo producto, el último publicado. Un campo rellenado puede seguir invisible en la asignación hasta que vacíes la caché de atributos del plugin; hazlo primero, antes de concluir que el campo está vacío. |
| Que el precio coincida con la página de destino | Hace falta comparar el feed y la página renderizada uno al lado del otro. Una consulta a la base de datos no ve lo que muestra la página después de impuestos, moneda y precios dinámicos. |
| Que el título coincida con la página de destino | Lo mismo. La longitud se puede medir; la coincidencia, no. |
La resolución de las imágenes también merece un apunte: Merchant Center empieza a exigir un mínimo de 500 × 500 px el 31 de enero de 2027, y las imágenes demasiado pequeñas son un motivo habitual de rechazo silencioso. La comprobación de la tienda (en inglés) lista las imágenes principales por debajo de ese tamaño sin que tengas que instalar nada: lee sus dimensiones del catálogo público. En WordPress, el plugin gratuito Merchlint muestra las fotos, principales y de variaciones, que no llegan a ese tamaño, cada una con sus medidas: Photo too small for Google (en inglés). Google Merchant Center image size (en inglés) tiene las fechas y un comando de WP-CLI para todo el catálogo, y en Image too small for upcoming enforcement (en inglés) explicamos los dos avisos que Merchant Center ya muestra.
Todo lo anterior son consultas que ejecutas tú, en tu propia base de datos. Si prefieres que estas
comprobaciones se hagan sobre todo el catálogo de una vez, con recuentos, la lista de productos
afectados y lo que te cuesta cada uno, eso es lo que hace Merchlint. Es gratuito,
solo lee y no cambia nada en tu tienda. Lo único que te deja a ti es el tercer estado de imagen de
arriba, un archivo que existe pero no se puede mostrar, y eso lo encuentra
wp media regenerate --dry-run.