Dos checkouts, dos vías de integración
WooCommerce tiene dos motores de checkout y Finseed soporta ambos. Comparten la misma forma canónica de datos en el pedido, pero la superficie de personalización es completamente distinta. Identifica primero cuál usa tu tienda antes de tocar nada.- Checkout Blocks (moderno). El checkout basado en bloques de Gutenberg, con validación de campos por JSON Schema y personalización desde el editor de bloques. Es el predeterminado en las versiones recientes de WooCommerce. Nuestros campos se registran a través de la Additional Checkout Fields API (WooCommerce 8.9 o posterior) bajo el namespace
finseed. - Checkout Classic (heredado). El checkout del shortcode
[woocommerce_checkout], basado en$_POSTy personalizado mediante el filtrowoocommerce_checkout_fields. Muchas tiendas antiguas y muchos themes o page builders siguen ancladas a este modo. Nuestros campos se registran con prioridades de la 34 a la 39, entrebilling_company(prioridad 30) ybilling_country(prioridad 40).
Qué añade el plugin y dónde
Los campos existen solo si has activado Solicitar NIF / CIF en el checkout en los ajustes del plugin. El ajuste viene desactivado, y hasta que lo actives ninguno de los dos motores registra nada. Con el ajuste activo, Finseed añade estos campos al checkout. El checkout clásico solo los registra si la tienda opera en EUR; en cualquier otra divisa no aparecen. El checkout Blocks los registra siempre, sea cual sea la divisa, pero fuera del euro no aplica el umbral ni exige el NIF/CIF: la casilla y el NIF/CIF quedan visibles y opcionales. La casilla y el NIF/CIF aparecen según el importe del pedido (ver “Comportamiento por umbral”, más abajo). En los dos checkouts, también en Blocks con WooCommerce 8.9 a 10.0, un script del plugin muestra los campos que acompañan al NIF/CIF solo cuando el comprador marca la casilla o el pedido exige NIF/CIF (por encima del umbral, o en todos los pedidos con Siempre obligatorio). La lista recoge todos los campos y, para los que acompañan al NIF/CIF, cuándo aparece cada uno:- Casilla
finseed_wants_full_invoice. Tipocheckbox, con la etiqueta “Quiero factura con mis datos fiscales”. Es la petición del comprador de una factura con sus datos fiscales. - Selector
finseed_buyer_kind. Tiposelect, con la etiqueta Compras como y las opciones Particular y Empresa. Aparece junto al NIF/CIF solo cuando la dirección de facturación está fuera de España. - Campo
finseed_tax_id. Tipotext. Recoge el identificador fiscal del comprador. Su etiqueta depende del país de facturación y de la respuesta a Compras como: con una dirección española es “NIF / CIF / NIE”. - Campo
finseed_company_name. Tipotext, con la etiqueta Empresa. El plugin trata al comprador como empresa en dos casos: con una dirección española, cuando el NIF/CIF escrito tiene forma de CIF o es un número de IVA de la UE bien formado con el prefijo de otro país (por ejemplo,DE815892943), y el comprador no ha elegido nada en Tipo de documento; fuera de España, cuando el comprador elige la opción Empresa de Compras como. Solo entonces aparece el campo Empresa, así que con una dirección española y un NIF personal no aparece. Debajo lleva el texto de ayuda “El nombre completo de la empresa, con S.L., S.A. u otra forma al final.” Mientras está visible, es obligatorio en cuanto el NIF/CIF tiene un valor. Si queda vacío, el checkout muestra el error “Indica el nombre de la empresa.” La primera vez que aparece, toma como valor inicial el del campo de empresa de WooCommerce (billing_company). Si la tienda no muestra ese campo, toma la empresa guardada en la cuenta del comprador. El comprador puede cambiar ese valor. En la factura, el nombre escrito en Empresa tiene prioridad sobrebilling_company. Si el script del checkout clásico no se carga, el campo aparece para todos los compradores con la etiqueta “Empresa (solo si facturas a una empresa)”, y el servidor solo lo exige cuando trata al comprador como empresa. - Selectores
finseed_document_typeyfinseed_issuing_country. Tiposelect, con las etiquetas Tipo de documento (opciones Pasaporte y Documento de identidad de otro país) y País que expide el documento. Tipo de documento aparece con una dirección fuera de España cuando el comprador no elige la opción Empresa de Compras como. Con una dirección española aparece cuando el checkout rechaza el identificador con un mensaje que termina con “Si es un pasaporte o un documento de otro país, indica el tipo y el país.” País que expide el documento aparece cuando el comprador elige un tipo.
billing_company) → nuestros campos → país → dirección.
En el checkout Blocks los campos se registran vía woocommerce_register_additional_checkout_field con location: 'order', por lo que aparecen en la sección de pedido del bloque. Sus identificadores internos son finseed/wants_full_invoice, finseed/buyer_kind, finseed/tax_id, finseed/company_name, finseed/document_type y finseed/issuing_country (con barra, no con guion bajo). El checkout clásico usa la forma con guion bajo porque envía los campos por $_POST con la convención de claves de WooCommerce, mientras que Blocks los envía en JSON a través de la Store API.
Ambos motores persisten la misma información canónica en el pedido bajo los metadatos _finseed_wants_full_invoice (yes/no) y _finseed_tax_id. Cuando el plugin trata al comprador como empresa, el nombre escrito en Empresa se guarda en _finseed_company_name, junto al NIF/CIF.
Comportamiento por umbral
El umbral es el importe a partir del cual la factura completa con NIF/CIF es obligatoria. Es configurable en los ajustes del plugin y admite dos valores, ambos límites de la factura simplificada del RD 1619/2012: 400€ y 3.000€. El valor por defecto es 3.000€. En el checkout clásico, y en el checkout Blocks a partir de WooCommerce 10.1.0, el comportamiento de revelado depende de ese umbral:- Carrito ≤ umbral. La casilla está visible. El NIF/CIF está oculto hasta que el comprador marca la casilla. Al marcarla, aparece el campo NIF/CIF como opcional.
- Carrito > umbral. La casilla desaparece (la factura completa es obligatoria de todas formas) y el NIF/CIF se muestra siempre como obligatorio. Debajo del campo aparece el texto de ayuda “Necesario en compras superiores a 3.000 €”, con el umbral que se aplique a tu tienda.
_finseed_wants_full_invoice en yes junto al NIF/CIF del comprador, así que Finseed lo recibe como una petición de factura completa. Con el checkout Blocks por debajo de WooCommerce 8.9, este modo impide completar cualquier venta en euros: el plugin no puede registrar el campo, pero la comprobación del servidor sigue activa.
La lógica de revelado vive en el navegador, pero la validación final se hace en el servidor. Un comprador sin JavaScript no puede saltarse el requisito.
Hooks y técnicas seguras para personalizar (checkout clásico)
Las técnicas de esta sección solo aplican al checkout clásico (shortcode). El checkout Blocks se personaliza desde el editor de Gutenberg y los ajustes del propio bloque.Reordenar los campos
Para reubicar nuestros campos en el orden de facturación, engancha un filtro awoocommerce_checkout_fields con prioridad mayor que 10 (la nuestra) y reescribe la clave priority. WooCommerce ordena los campos por priority desde la versión 3.5.1; en 3.5.0 ignora ese valor y nuestros campos salen al final de la sección de facturación, así que en esa versión el único modo de moverlos es reordenar el array del filtro a mano. Por defecto, nuestros campos ocupan las prioridades de la 34 a la 39, justo después de billing_company. Muévelos juntos y en el mismo orden, para que Empresa siga justo debajo del NIF/CIF. Este ejemplo los coloca entre el país (prioridad 40) y la dirección (prioridad 50), con las prioridades de la 41 a la 46:
Restilizar con CSS
Los campos exponen ganchos por ID y por clase. Úsalos para alinear con el diseño del theme:#finseed_wants_full_invoice,#finseed_buyer_kind,#finseed_tax_id,#finseed_company_name,#finseed_document_typey#finseed_issuing_countrypara los inputs y selectores..finseed-legacy-checkout__wants-full-invoice,.finseed-legacy-checkout__buyer-kind,.finseed-legacy-checkout__tax-id,.finseed-legacy-checkout__company-name,.finseed-legacy-checkout__document-typey.finseed-legacy-checkout__issuing-countrypara las clases del contenedor<p class="form-row">..finseed-field-helppara el texto de ayuda que el script añade debajo del NIF/CIF y de Empresa.
.form-row, .form-row-wide) si tu hoja de estilos ya las trata.
Renombrar las etiquetas
El plugin rotula la casilla como “Quiero factura con mis datos fiscales”. La etiqueta de la casilla se puede cambiar con este filtro:woocommerce_checkout_fields, el script lo sustituye antes de que el comprador lo vea. Para controlar ese texto tendrías que intervenir el script del cliente, algo que no recomendamos.
Añadir contenido adyacente
Para insertar texto o componentes alrededor de la sección de facturación, usa los hooks de acción nativos de WooCommerce:woocommerce_before_checkout_billing_formwoocommerce_after_checkout_billing_form
Qué rompe la integración y cómo detectarlo
La mayoría de incidencias en personalizaciones avanzadas caen en uno de estos patrones. Reconocerlos te ahorrará tiempo de soporte.Page builders que reemplazan la plantilla del checkout
Elementor Pro, Divi, Beaver Builder o Bricks ofrecen widgets de checkout que sustituyen por completo la plantilla nativa. Cuando lo hacen, el pipeline de campos de WooCommerce no se ejecuta y nuestros campos no se renderizan. Solución. Configura el módulo de checkout del builder para usar los campos nativos de WooCommerce, no una lista de campos definida en el propio builder. Cada producto lo nombra de forma diferente, pero la opción suele estar etiquetada como “Use WooCommerce fields”, “Default fields” o similar.Plugins de editor de campos del checkout
“Checkout Field Editor for WooCommerce”, “WooCommerce Checkout Manager”, “Flexible Checkout Fields” y similares mantienen una lista interna de campos permitidos. Cualquier campo que no esté en esa lista (como los nuestros) puede quedar eliminado del formulario. Solución. Añadefinseed_wants_full_invoice, finseed_buyer_kind, finseed_tax_id, finseed_company_name, finseed_document_type y finseed_issuing_country a la lista de campos permitidos del editor. Si el editor quita finseed_company_name, el plugin deja de exigir Empresa: solo lo exige cuando el campo llega con el pedido, y el pedido de una empresa pasa sin ese nombre.
Themes que sobrescriben las plantillas de checkout
Algunos themes incluyen sobrescrituras dewoocommerce/checkout/form-checkout.php u otras plantillas del checkout. Si la sobrescritura no itera dinámicamente los campos del filtro y los lista a mano, nuestros campos no aparecerán.
Solución. Revisa el archivo form-checkout.php del theme dentro de wp-content/themes/<tu-theme>/woocommerce/checkout/. Asegúrate de que llama a woocommerce_checkout_billing() o que recorre los campos devueltos por el filtro woocommerce_checkout_fields. Una plantilla que codifica a mano la lista de campos rompe cualquier personalización dinámica, no solo la nuestra.
Contrato DOM del que depende el revelado condicional
El script de revelado y validación en el cliente espera una estructura DOM concreta. Si tu theme o un plugin la alteran, el revelado y la validación inline se degradan en silencio. La validación de servidor sigue funcionando, pero la experiencia del comprador empeora.- Contenedor
<p class="form-row">alrededor de cada campo. Lo usamos para mostrar u ocultar la fila y para marcar el estado de error. - Selector
.order-total .woocommerce-Price-amount(o.order-total bdi). Lo leemos para conocer el total del carrito en vivo y aplicar el umbral. - IDs
#billing_first_name,#billing_last_name,#billing_country. Los leemos para componer el nombre del comprador y el código de país que enviamos al validador de identificadores fiscales. - Evento
updated_checkoutdisparado con jQuery sobredocument.body. WooCommerce lo emite tras cada cambio en el carrito (cupón, envío, etc.) y lo reescuchamos para reaplicar el estado tras el re-renderizado del formulario.
#billing_company si existe, pero no depende de él. Para una empresa enviamos al validador el nombre escrito en Empresa, y #billing_company solo cuenta si Empresa está vacío. #billing_company también da el valor inicial de Empresa. Si #billing_company no existe, el revelado y la validación siguen funcionando.
Diagnóstico rápido desde el navegador
Antes de pedir soporte, abre la consola del navegador en la página de checkout y comprueba lo siguiente:undefined, nuestro script no se ha cargado. Comprueba primero que Solicitar NIF / CIF en el checkout está activado en los ajustes del plugin: con el ajuste apagado no se registra ningún campo ni se carga el script. Si está activado, confirma que el theme y los plugins activos no están bloqueando wp_enqueue_scripts en la página de checkout. Si devuelve un objeto, debe contener al menos restUrl, restNonce, thresholdCents, fieldWantsFullInvoice, fieldTaxId, fieldCompanyName y copy.
Después, escribe un NIF inválido en el campo y quita el foco. En la pestaña Network deberías ver una petición POST a /wp-json/finseed/v1/validate-tax-id (en tiendas con enlaces permanentes personalizados) o a /?rest_route=/finseed/v1/validate-tax-id (en tiendas con la configuración “Sencillo” de enlaces permanentes). Si la petición no se dispara, el manejador de blur no se ha enlazado (suele indicar un bundle cacheado obsoleto en el servidor de WordPress o que el theme reemplaza el input antes de que lo enlacemos). Si la petición devuelve 401 o 403, el nonce REST no es válido, lo que suele indicar una caché de página agresiva que sirve nonces caducados a usuarios distintos.
Cuando la validación inline funciona, el input gana el atributo aria-invalid="true" y la fila añade las clases woocommerce-invalid y woocommerce-invalid-required-field.
Cuando la posición estándar no encaja con tu diseño
Hoy no ofrecemos un shortcode independiente para colocar los campos en cualquier zona de la página. Los campos aparecen en la posición que indican las prioridades de la 34 a la 39 del filtrowoocommerce_checkout_fields. Para reubicarlos basta con cambiar esas prioridades como se muestra más arriba.
Si tu diseño exige una posición que ninguna prioridad alcanza (por ejemplo, fuera del bloque de facturación), escríbenos. El campo renderizado debe terminar dentro del <form class="checkout"> para que su valor se envíe con el resto del pedido, así que la vía de escape correcta tiene restricciones que preferimos resolver contigo.
Tu personalización no rompe el cumplimiento
Sea cual sea el comportamiento del cliente, los hooks de servidor son la fuente de verdad. Cada motor de checkout usa los suyos:- Checkout clásico. La validación sobre
woocommerce_after_checkout_validationaplica el requisito de NIF/CIF (por encima del umbral, o en todos los pedidos con Siempre obligatorio), consulta al validador de identificadores fiscales en cada envío y rechaza el pedido de una empresa que escribe su NIF/CIF y deja Empresa vacío. La persistencia sobrewoocommerce_checkout_create_orderescribe la información canónica en el pedido. - Checkout Blocks. Ninguno de esos dos hooks se ejecuta. En todas las versiones, el plugin actúa sobre
woocommerce_store_api_checkout_update_order_from_request. Ahí rechaza el envío si falta el NIF/CIF cuando es obligatorio (por encima del umbral, o en todos los pedidos con Siempre obligatorio), si el identificador no es válido o si una empresa escribe su NIF/CIF y deja Empresa vacío. Esta última comprobación solo se hace si la petición a la Store API incluyefinseed/company_name. Después guarda los datos en el pedido.
woocommerce_checkout_fields; en Blocks, mientras la petición a la Store API los incluya), el servidor rechaza todo envío del checkout que no cumple esas comprobaciones. Está diseñado así a propósito.
Cuando algo no funciona
Antes de contactar con soporte, captura la siguiente información. Reduce el tiempo de diagnóstico a la mitad.- Logs de WooCommerce filtrados por
finseed. Ve a WooCommerce > Estado > Registros y abre el log más reciente con esa fuente. - Consola y Network del navegador en la página de checkout. Captura el contenido de
window.finseedLegacyCheckouty la petición al endpoint de validación (con enlaces permanentes personalizados aparece como/wp-json/finseed/v1/validate-tax-id; con la configuración “Sencillo” aparece como/?rest_route=/finseed/v1/validate-tax-id). Incluye cuerpo, respuesta, código de estado y cualquier error de consola. - Estado actual de los campos del checkout. Si tienes acceso WP-CLI, ejecuta
wp option get woocommerce_checkout_fields. Si no, copia el HTML del<form class="checkout">renderizado. - Theme activo y plugins de personalización del checkout activos. Nombre exacto y versión.
- Una grabación de pantalla del fallo. Cualquier vídeo corto del problema vale más que una descripción escrita.