Saltar al contenido
WooRescueHQ

WooCommerce / HPOS

HPOS en WooCommerce: problemas habituales con código personalizado

Respuesta corta

Con HPOS como almacenamiento principal, los pedidos viven en wp_wc_orders y sus tablas relacionadas, no en wp_posts y wp_postmeta. El código que lee o escribe pedidos con funciones de entradas, WP_Query o SQL sobre las tablas de entradas deja de funcionar, a menudo en silencio y devolviendo valores vacíos. Reescríbelo con la API de pedidos (wc_get_order(), wc_get_orders(), $order->get_meta(), $order->update_meta_data() más $order->save()), actualiza los hooks de administración para la nueva pantalla de pedidos y declara la compatibilidad con HPOS en tus plugins.

Síntomas

  • Los meta de pedido que lee el código a medida llegan vacíos tras activar HPOS.
  • Faltan columnas, filtros o cajas meta personalizados en la nueva pantalla de pedidos.
  • Las exportaciones, los informes o las integraciones dejan de incluir los pedidos nuevos.
  • Los valores que guarda el código a medida no aparecen en el pedido, o desaparecen con el siguiente guardado.
  • WooCommerce avisa de que hay plugins activos incompatibles y no te deja cambiar a HPOS.

Causas más comunes

Patrón Por qué falla
get_post_meta( $order_id, '_my_key', true ) Lee wp_postmeta, que no es la fuente de verdad con HPOS
update_post_meta( $order_id, … ) Escribe en el almacenamiento de entradas; HPOS no lo ve, o la sincronización lo sobrescribe
new WP_Query( [ 'post_type' => 'shop_order' ] ) / get_posts() Consulta wp_posts, donde puede que los pedidos nuevos no existan
Consultas $wpdb sobre wp_posts / wp_postmeta para pedidos Esquema antiguo escrito a mano
wp_insert_post() / wp_update_post() sobre pedidos Se salta los almacenes de datos de pedidos
Solo manage_edit-shop_order_columns Hooks de la pantalla antigua; la pantalla de HPOS usa otros
add_meta_box( …, 'shop_order' ) ID de pantalla incorrecto para la pantalla de edición de HPOS

Diagnóstico

1. Comprueba qué almacenamiento es el principal

WooCommerce → Ajustes → Avanzado → Características muestra si los pedidos se guardan en las tablas de HPOS o en las antiguas tablas de entradas, y si el modo de compatibilidad mantiene ambos sincronizados. Mientras la sincronización está activa, el código antiguo puede parecer que funciona al leer, lo que oculta el problema hasta que se desactiva.

2. Busca en el código

Busca en el tema, los plugins a medida, los mu-plugins y los plugins de snippets:

Bash
$ grep -rnE "get_post_meta|update_post_meta|delete_post_meta|wp_insert_post|wp_update_post" wp-content/themes/my-theme wp-content/plugins/my-plugin
$ grep -rnE "shop_order|wp_posts|wp_postmeta|post_type *=" wp-content/themes/my-theme wp-content/plugins/my-plugin

Cada resultado requiere una decisión: ¿toca pedidos? El código de productos y páginas no se ve afectado.

3. Revisa las extensiones

WooCommerce lista los plugins incompatibles en la pantalla de Características. Para cada uno, comprueba si alguna actualización declara la compatibilidad; si no, pregunta al desarrollador o planifica un sustituto.

4. Prueba en staging con la sincronización activada y después desactivada

Activa HPOS en staging con el modo de compatibilidad, recorre los flujos críticos (checkout, notificaciones de pago, emails, ediciones en la administración, exportaciones, integraciones) y después desactiva la sincronización y vuelve a recorrerlos. El código que solo funciona con la sincronización activada no es compatible.

Registros y comprobaciones técnicas

  • La pantalla de Características: almacenamiento principal, estado de la sincronización, plugins incompatibles.
  • WooCommerce → Estado → Registros: fatal-errors tras cambiar de almacenamiento.
  • Notas y meta de pedidos de prueba, comparados antes y después del cambio.
  • Comparaciones de solo lectura del mismo pedido en ambos almacenamientos mientras la sincronización está activa.

Soluciones

Lee y escribe pedidos con la API de pedidos

PHPmy-plugin/includes/orders.php
// Leer
$order = wc_get_order( $order_id );
if ( ! $order ) {
    return;
}
$po_number = $order->get_meta( '_po_number' );

// Escribir: los cambios no se guardan hasta llamar a save()
$order->update_meta_data( '_po_number', sanitize_text_field( $value ) );
$order->save();

// Consultar
$orders = wc_get_orders( [
    'status'     => [ 'wc-processing' ],
    'limit'      => 50,
    'meta_query' => [
        [ 'key' => '_po_number', 'compare' => 'EXISTS' ],
    ],
] );

Da soporte a las dos pantallas de administración

PHPmy-plugin/includes/admin.php
use Automattic\WooCommerce\Utilities\OrderUtil;

// Columnas: pantalla antigua y pantalla de HPOS
add_filter( 'manage_edit-shop_order_columns', 'myplugin_add_column' );
add_filter( 'manage_woocommerce_page_wc-orders_columns', 'myplugin_add_column' );

add_action( 'manage_shop_order_posts_custom_column', function ( $column, $post_id ) {
    myplugin_render_column( $column, wc_get_order( $post_id ) );
}, 10, 2 );
add_action( 'manage_woocommerce_page_wc-orders_custom_column', function ( $column, $order ) {
    myplugin_render_column( $column, $order );
}, 10, 2 );

// Caja meta en la pantalla de edición de pedidos que esté activa
add_action( 'add_meta_boxes', function () {
    add_meta_box( 'myplugin-box', 'Orden de compra', 'myplugin_render_box', wc_get_page_screen_id( 'shop-order' ), 'side' );
} );

function myplugin_render_box( $post_or_order ) {
    $order = $post_or_order instanceof WP_Post ? wc_get_order( $post_or_order->ID ) : $post_or_order;
    // …
}

Declara la compatibilidad en tus propios plugins

PHPmy-plugin/my-plugin.php
add_action( 'before_woocommerce_init', function () {
    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    }
} );

Qué no hacer

  • No declares la compatibilidad para quitar el aviso antes de revisar el código.
  • No desactives el modo de compatibilidad nada más cambiar: mantenlo como camino de vuelta atrás hasta que la tienda lleve un tiempo funcionando bien.
  • No «arregles» los valores que faltan copiando meta entre tablas con SQL.

Cuándo recurrir a un experto

Recurre a un ingeniero cuando la auditoría encuentra accesos a pedidos repartidos por muchos archivos, cuando una extensión imprescindible no tiene versión compatible, cuando los datos de pedidos ya difieren entre almacenamientos, o cuando la tienda es tan grande que la propia migración necesita planificación.

Preguntas frecuentes

¿Cómo sé si mi código es compatible con HPOS?

Busca accesos directos a pedidos: get_post_meta y update_post_meta sobre IDs de pedido, WP_Query o get_posts con shop_order, wp_insert_post para pedidos y SQL contra wp_posts o wp_postmeta para pedidos. El código que solo usa wc_get_order, wc_get_orders y los métodos del objeto pedido suele ser compatible.

¿Por qué desaparece mi columna personalizada de la lista de pedidos?

La pantalla de pedidos de HPOS es otra página de administración con otros hooks. Las columnas registradas con manage_edit-shop_order_columns necesitan también sus equivalentes manage_woocommerce_page_wc-orders_columns.

¿Tengo que declarar la compatibilidad?

Sí, en tus propios plugins. WooCommerce usa esa declaración para decidir si se puede activar HPOS. Decláralo solo después de revisar el código.

¿Puedo seguir ejecutando SQL sobre los pedidos?

Mejor usa wc_get_orders(). Si de verdad necesitas SQL, obtén los nombres de tabla de WooCommerce en lugar de escribir wp_posts a mano, y recuerda que el esquema es distinto en cada almacenamiento.

$ describe el problema

¿Tienes un problema con WooCommerce?Solicita un diagnóstico.

Cuéntanos qué falla, qué ha cambiado últimamente y cómo afecta al negocio. Revisamos cada solicitud y te recomendamos el siguiente paso.

Solicitar un diagnóstico Ver servicios y precios

Nunca envíes contraseñas, claves API ni datos de tarjetas a través del formulario.

Diagnóstico desde299 €

Solicitar un diagnóstico