Como personalizar campos del checkout de WooCommerce con hooks en WordPress

Contents

Introducción

WooCommerce proporciona un sistema flexible de campos en el checkout que puedes adaptar mediante hooks de WordPress. Con ellos puedes modificar, eliminar, añadir, validar y guardar campos personalizados, además de mostrarlos en el panel de administración y en los correos. Este artículo explica en detalle cómo trabajar con los hooks principales, y ofrece ejemplos prácticos listos para copiar y pegar.

Conceptos clave

  • Campos estándar: están agrupados por secciones como billing, shipping y order.
  • Filtro principal: woocommerce_checkout_fields para modificar la estructura del array de campos.
  • Acciones importantes: woocommerce_checkout_process (validación), woocommerce_checkout_update_order_meta (guardar meta al crear el pedido), woocommerce_admin_order_data_after_billing_address (mostrar en admin).
  • Claves de campos: usan prefijos como billing_ o shipping_ y luego el nombre del campo. Ej.: billing_phone, shipping_company.

Modificar, eliminar y reorganizar campos

Para cambiar una etiqueta, placeholder, requerimiento, clase o prioridad se utiliza el filtro woocommerce_checkout_fields. El filtro recibe un array multidimensional donde cada sección (billing, shipping, order) contiene la definición de campos.

Ejemplo: cambiar placeholder y hacer un campo opcional

add_filter(woocommerce_checkout_fields, mi_modificar_campos_checkout)
function mi_modificar_campos_checkout(fields) {
    // Cambiar placeholder del teléfono de facturación
    fields[billing][billing_phone][placeholder] = Ej:  34 600 000 000

    // Hacer opcional el apellido
    if ( isset(fields[billing][billing_last_name]) ) {
        fields[billing][billing_last_name][required] = false
    }

    return fields
}

Ejemplo: eliminar un campo del checkout

add_filter(woocommerce_checkout_fields, mi_quitar_campos_checkout)
function mi_quitar_campos_checkout(fields) {
    // Eliminar el campo de empresa en billing
    unset(fields[billing][billing_company])

    return fields
}

Añadir campos personalizados al checkout

Para añadir un campo nuevo se agrega una nueva entrada al array dentro de la sección correspondiente. Puedes definir tipo, etiqueta, placeholder, clases, prioridad y si es requerido o no.

Ejemplo: añadir un campo de Número de cliente en billing

add_filter(woocommerce_checkout_fields, mi_agregar_campo_numero_cliente)
function mi_agregar_campo_numero_cliente(fields) {
    fields[billing][billing_customer_number] = array(
        type        => text,
        label       => Número de cliente,
        placeholder => Si tienes número de cliente, indícalo,
        required    => false,
        class       => array(form-row-wide),
        priority    => 120,
    )

    return fields
}

Validación personalizada

Para validar campos de checkout usamos la acción woocommerce_checkout_process. En caso de error lanzamos una excepción de tipo notice con wc_add_notice (tipo error).

Ejemplo: validar que el número de cliente, si se rellena, tenga 6 dígitos

add_action(woocommerce_checkout_process, mi_validar_numero_cliente)
function mi_validar_numero_cliente() {
    if ( isset(_POST[billing_customer_number])  ! empty(_POST[billing_customer_number]) ) {
        valor = sanitize_text_field(_POST[billing_customer_number])
        if (! preg_match(/^d{6}/, valor) ) {
            wc_add_notice(El número de cliente debe tener 6 dígitos., error)
        }
    }
}

Guardar el campo en los metadatos del pedido

Una vez validado, hay que guardar el valor en los meta del pedido. Para ello se utiliza la acción woocommerce_checkout_update_order_meta. Además, es buena práctica sanitizar y/o escapar el dato antes de guardarlo.

Ejemplo: guardar número de cliente en el pedido

add_action(woocommerce_checkout_update_order_meta, mi_guardar_numero_cliente_en_pedido)
function mi_guardar_numero_cliente_en_pedido(order_id) {
    if ( isset(_POST[billing_customer_number])  ! empty(_POST[billing_customer_number]) ) {
        valor = sanitize_text_field(_POST[billing_customer_number])
        update_post_meta(order_id, _billing_customer_number, valor)
    }
}

Mostrar el valor en la página de pedido (frontend) y en Gracias por tu compra

Puedes mostrar los metadatos del pedido en la página de agradecimiento o en la vista del pedido con la acción woocommerce_thankyou o utilizando métodos del objeto pedido.

Ejemplo: mostrar en la página de gracias y en la página de pedido

add_action(woocommerce_thankyou, mi_mostrar_numero_cliente_thankyou, 20)
add_action(woocommerce_view_order, mi_mostrar_numero_cliente_thankyou, 20)

function mi_mostrar_numero_cliente_thankyou(order_id) {
    numero = get_post_meta(order_id, _billing_customer_number, true)
    if (numero) {
        echo ltpgtltbgtNúmero de cliente:lt/bgt  . esc_html(numero) . lt/pgt
    }
}

Mostrar el campo en el panel de administración (editar pedido)

Para que los administradores vean el dato en la pantalla de pedido se usan acciones como woocommerce_admin_order_data_after_billing_address. También puedes hacer que sea editable con campos personalizados si lo deseas.

Ejemplo: mostrar el número de cliente en la caja de billing del admin

add_action(woocommerce_admin_order_data_after_billing_address, mi_mostrar_numero_cliente_en_admin, 10, 1)
function mi_mostrar_numero_cliente_en_admin(order){
    order_id = order->get_id()
    numero = get_post_meta(order_id, _billing_customer_number, true)
    if (numero) {
        echo ltpgtltstronggtNúmero de cliente:lt/stronggt  . esc_html(numero) . lt/pgt
    }
}

Incluir el campo en los correos

Si deseas que el dato aparezca en los emails, puedes usar filtros o añadir el meta a la lista de campos mostrados. Un filtro útil es woocommerce_email_order_meta_fields que permite registrar campos adicionales a incluir.

Ejemplo: añadir número de cliente a los correos

add_filter(woocommerce_email_order_meta_fields, mi_agregar_meta_emails, 10, 3)
function mi_agregar_meta_emails(fields, sent_to_admin, order) {
    fields[billing_customer_number] = array(
        label => Número de cliente,
        value => get_post_meta(order->get_id(), _billing_customer_number, true),
    )
    return fields
}

Campos condicionales: mostrar/ocultar con JavaScript

Si un campo debe mostrarse solo cuando otro tiene un valor concreto, suele hacerse con JavaScript en el checkout. Añade el script correctamente encolado o, para ejemplos rápidos, muestra cómo realizarlo con jQuery (WooCommerce ya incluye jQuery en el checkout).

Ejemplo: mostrar ID empresa solo si el usuario marca ¿Soy empresa?

/ 1) Añadir un checkbox y el campo oculto desde PHP /
add_filter(woocommerce_checkout_fields, mi_campo_condicional_empresa)
function mi_campo_condicional_empresa(fields) {
    fields[billing][billing_is_company] = array(
        type     => checkbox,
        label    => Soy empresa,
        class    => array(form-row-wide),
        priority => 115,
    )

    fields[billing][billing_company_id] = array(
        type        => text,
        label       => ID empresa,
        required    => false,
        class       => array(form-row-wide, hidden-company-id),
        priority    => 116,
    )

    return fields
}

/ 2) Script para mostrar/ocultar el campo (este JS debe encolarse correctamente en un plugin o tema) /
jQuery(function(){
    function toggleCompanyId(){
        if ((#billing_is_company).is(:checked)) {
            (#billing_company_id_field).show()
        } else {
            (#billing_company_id_field).hide()
        }
    }

    // Ejecutar al cargar
    toggleCompanyId()

    // Ejecutar al cambiar checkbox
    (document).on(change, #billing_is_company, function(){
        toggleCompanyId()
    })

    // Cuando WooCommerce actualiza los fragments del checkout (por ejemplo al cambiar país)
    (document.body).on(updated_checkout, function(){
        toggleCompanyId()
    })
})

Nota: Los ID y estructura del DOM pueden variar según la versión o personalizaciones. Asegúrate de inspeccionar los elementos y usar los selectores correctos.

Validaciones y seguridad

  • Sanitiza siempre los datos que vienen por _POST antes de guardarlos (sanitize_text_field, sanitize_email, etc.).
  • Escapa al mostrar información (esc_html, esc_attr).
  • Usa capacidades adecuadas si permites editar metadatos desde el admin.
  • Comprueba compatibilidad con plugins de checkout que reordenan o manipulan campos.

Buenas prácticas y rendimiento

  • Evita añadir lógica compleja en filtros que se ejecutan en cada carga separa la lógica en funciones reutilizables.
  • Si encolas scripts, hazlo condicionalmente solo en las páginas de checkout para no cargar JS innecesario.
  • Usa prioridades en los campos para controlar el orden y evita colisiones con otros plugins.
  • Documenta los meta keys que creas (ej.: _billing_customer_number) para mantenimiento futuro.

Ejemplo completo: añadir campo, validar, guardar y mostrar en admin emails

Este bloque resume todo en un único set de funciones que puedes integrar en un plugin o en functions.php del tema hijo.

/ 1) Añadir campo /
add_filter(woocommerce_checkout_fields, agregar_campo_ejemplo)
function agregar_campo_ejemplo(fields) {
    fields[billing][billing_customer_number] = array(
        type        => text,
        label       => Número de cliente,
        placeholder => 000000,
        required    => false,
        class       => array(form-row-wide),
        priority    => 120,
    )
    return fields
}

/ 2) Validar /
add_action(woocommerce_checkout_process, validar_campo_ejemplo)
function validar_campo_ejemplo() {
    if (! empty(_POST[billing_customer_number]) ) {
        valor = sanitize_text_field(_POST[billing_customer_number])
        if (! preg_match(/^d{6}/, valor) ) {
            wc_add_notice(El número de cliente debe tener exactamente 6 dígitos., error)
        }
    }
}

/ 3) Guardar en meta del pedido /
add_action(woocommerce_checkout_update_order_meta, guardar_campo_ejemplo)
function guardar_campo_ejemplo(order_id) {
    if ( isset(_POST[billing_customer_number])  _POST[billing_customer_number] !==  ) {
        update_post_meta(order_id, _billing_customer_number, sanitize_text_field(_POST[billing_customer_number]))
    }
}

/ 4) Mostrar en la página de pedido/gracias /
add_action(woocommerce_thankyou, mostrar_numero_cliente, 20)
add_action(woocommerce_view_order, mostrar_numero_cliente, 20)
function mostrar_numero_cliente(order_id) {
    numero = get_post_meta(order_id, _billing_customer_number, true)
    if (numero) {
        echo ltpgtltbgtNúmero de cliente:lt/bgt  . esc_html(numero) . lt/pgt
    }
}

/ 5) Mostrar en admin /
add_action(woocommerce_admin_order_data_after_billing_address, mostrar_numero_cliente_admin, 10, 1)
function mostrar_numero_cliente_admin(order){
    numero = get_post_meta(order->get_id(), _billing_customer_number, true)
    if (numero) {
        echo ltpgtltbgtNúmero de cliente:lt/bgt  . esc_html(numero) . lt/pgt
    }
}

/ 6) Incluir en correos /
add_filter(woocommerce_email_order_meta_fields, incluir_numero_cliente_emails, 10, 3)
function incluir_numero_cliente_emails(fields, sent_to_admin, order) {
    fields[billing_customer_number] = array(
        label => Número de cliente,
        value => get_post_meta(order->get_id(), _billing_customer_number, true),
    )
    return fields
}

Consideraciones finales

Personalizar el checkout de WooCommerce con hooks es potente y seguro si sigues buenas prácticas: sanitización, escape, control de prioridades, y pruebas en diferentes escenarios (usuarios registrados, invitados, diferentes países y métodos de envío). Si trabajas en un entorno de producción, prueba siempre estas personalizaciones en un entorno de staging antes de desplegar.

Recursos útiles

  • Documentación de WooCommerce sobre hooks y fields (consulta la documentación oficial de WooCommerce).
  • Inspecciona el HTML del checkout para detectar IDs y clases que varían entre versiones.


Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *