HubfiscalStoreShopify
Descripción
Sección titulada «Descripción»Recibe el payload bruto de un pedido Shopify (desde un webhook o nodo anterior) y lo almacena en la base de datos centralizada Hub Fiscal (MySQL/MariaDB) con estado pending. Debe colocarse al inicio del flujo fiscal, antes de facturar, para encolar el pedido y garantizar que ninguno se pierda aunque el paso del proveedor fiscal falle después.
Caracteristicas principales:
- Upsert: Si el pedido ya tiene un registro (mismo
entity_id+entity_source+type), actualiza solo los campos seguros (el estado se preserva si ya escompleted/failed). Evita duplicados en reintentos del webhook Shopify. - Auto-detección: Extrae el pais de
billing_address.country_codey selecciona automáticamente el proveedor fiscal (PT/AO/MZ → billpt, ES/DE → fiskaly). - Resolución de NIF: Lee el NIF/VAT del cliente desde los
note_attributesde Shopify (clave configurable). - Transacción atomica: Inserta en
documents,fiscal_statusylogsen una sola transacción.
Configuración
Sección titulada «Configuración»| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| credentials_id | credentials | Si | Credencial Hub Fiscal MySQL/MariaDB (tipo sqlQuery) |
| country_iso | text | No | Código ISO del pais. Por defecto usa billing_address.country_code |
| document_type | select | No | FT, FR, ORC, NC. Default: FT |
| fiscal_provider | select | No | billpt, fiskaly, sage. Auto-detectado por pais si esta vacío |
| initial_status | select | No | pending (default) o completed |
| nif_attribute | text | No | Clave del note_attributes de Shopify donde se guarda el NIF/VAT. Default: nif |
| entity_source | text | No | Origen del pedido: shopify, manual, api. Default: shopify |
| assign_numbering | select | No | No (default): solo guarda portal y zona. Sí: además asigna el número de serie y pasa a completed (portales sin tercero fiscal) |
| save_payload | select | No | Guardar el JSON completo en payload_json (hasta 50KB). Default: Si |
Credenciales
Sección titulada «Credenciales»Requiere una credencial de tipo sqlQuery (MySQL/MariaDB) con:
- host: Host de la base de datos (ej:
127.0.0.1) - user: Usuario de la base de datos (ej:
user_hubfiscal) - password: Contrasena del usuario
- database: Nombre de la base de datos Hub Fiscal (ej:
hubfiscal) - port: Puerto (por defecto
3306)
Mapeo de Campos
Sección titulada «Mapeo de Campos»El nodo mapea los campos del pedido Shopify a Hub Fiscal automáticamente:
| Campo Hub Fiscal | Origen Shopify |
|---|---|
entity_id | data.id |
order_number | data.order_number → data.name |
country_iso | config → billing_address.country_code → PT |
type | config document_type → FT |
fiscal_provider | config → auto por pais |
contact_name | billing_address.name |
contact_email | data.email |
contact_nif | note_attributes[nif_attribute].value |
total_net | data.subtotal_price |
total_tax | data.current_total_tax → data.total_tax |
total_gross | data.total_price |
currency | data.currency |
issued_at | data.created_at (solo fecha) |
Auto-detección del Proveedor
Sección titulada «Auto-detección del Proveedor»Cuando fiscal_provider esta vacío, el nodo selecciona el proveedor según country_iso:
| Pais | Proveedor |
|---|---|
| PT, AO, MZ, CV | billpt |
| ES, DE, AT | fiskaly |
| Otros | null (se guarda vacío, rellenar manualmente) |
NIF desde note_attributes
Sección titulada «NIF desde note_attributes»Shopify no tiene un campo nativo para NIF/VAT. Configura tu checkout de Shopify para recogerlo como un note_attribute y establece nif_attribute con el nombre de clave correspondiente:
"note_attributes": [ { "name": "nif", "value": "PT999999990" }]Nombres de clave habituales: nif, vat, tax_id, nif_vat, numero_fiscal.
Comportamiento del Upsert
Sección titulada «Comportamiento del Upsert»La tabla documents tiene una restricción única sobre (entity_id, entity_source, type). En reintentos del webhook Shopify:
- Si el documento sigue en
pending: se actualizan todos los campos. - Si el documento ya esta
completedofailed: el estado se preserva, solo se actualizan totales y payload.
Esto garantiza que un webhook re-entregado nunca sobreescriba un documento ya fiscalizado.
Entrada
Sección titulada «Entrada»Entrada esperada: objeto Order de Shopify desde un webhook o nodo anterior:
{ "id": 6684429451477, "order_number": 14522, "name": "#14522", "email": "cliente@ejemplo.com", "financial_status": "paid", "currency": "EUR", "subtotal_price": "63.56", "current_total_tax": "14.62", "total_price": "78.18", "created_at": "2026-04-20T10:00:00Z", "billing_address": { "name": "Juan Garcia", "country_code": "PT" }, "note_attributes": [ { "name": "nif", "value": "PT999999990" } ]}{ "success": true, "hub_document_id": 22, "entity_id": "6684429451477", "order_number": "14522", "country_iso": "PT", "type": "FT", "status": "pending", "fiscal_provider": "billpt", "contact_name": "Juan Garcia", "contact_email": "cliente@ejemplo.com", "contact_nif": "PT999999990", "total_net": 63.56, "total_tax": 14.62, "total_gross": 78.18, "currency": "EUR", "message": "Pedido Shopify #14522 registrado en Hub Fiscal (ID: 22)"}Flujo Tipico
Sección titulada «Flujo Tipico»Patron 1 — Registrar y luego fiscalizar:
Shopify Webhook → HubfiscalStoreShopify (pending) → BillptCreateInvoiceFromShopify → HubfiscalStoreBillpt (actualiza a completed)Patron 2 — Solo registrar (fiscalización diferida):
Shopify Webhook → HubfiscalStoreShopify (pending)La fiscalización se gestiona desde un workflow programado que consulta status = 'pending' en Hub Fiscal.
- La tabla
fiscal_statusregistra la acción inicialregisterconstatus: pendingpara trazabilidad. contact_nifsolo se rellena si el pedido Shopify tiene unnote_attributeque coincide connif_attribute. Si el NIF esta en otro lugar (metafields, tags), un nodo Transform anterior puede moverlo anote_attributes.- La fecha
issued_atse extrae decreated_at(solo la parte de fecha, sin hora).
Portal y numeración (agregación diaria a Sage X3)
Sección titulada «Portal y numeración (agregación diaria a Sage X3)»Además de guardar el documento, el nodo determina el portal de venta (equivalenza.com, .it, .fr o .pt) a partir del pedido y la zona (Canarias, si el código postal de envío empieza por 35 o 38), y los guarda en el documento. Esto lo usa HubfiscalAggregateSales para agrupar las ventas del día.
Con la opción Numerar y completar en Sí, en los portales sin tercero fiscal (equivalenza.com, .it y .fr) el nodo además:
- asigna el siguiente número correlativo de la serie, sin ceros a la izquierda y sin reinicio anual (
FESH1,FESH2…), y - pasa el documento a
completed.
| Portal | Factura | Abono |
|---|---|---|
| equivalenza.com | FESH | AESH |
| equivalenza.com (Canarias) | FCAH | ACAH |
| equivalenza.it | FITH | AITH |
| equivalenza.fr | FFRH | AFRH |
- Sin huecos ni duplicados, aunque entren pedidos a la vez: el contador de cada serie se bloquea al asignar, y un error no consume el número.
- Idempotente: reenviar el mismo pedido no lo renumera.
- equivalenza.pt no se numera aquí: lo hace Bill.pt (
FHPT/AHPT). - Un tipo distinto de factura o abono (por ejemplo
ORC) o un portal sin regla no se numera. - Por defecto está desactivado (
No): solo se guardan portal y zona. Actívalo cuando decidas desde qué día se numera, porque la numeración consume números de serie reales.
Requiere aplicar en la base de datos de Hub Fiscal las columnas portal y zone y las tablas document_sequences y portal_providers. Si no están aplicadas, el nodo sigue funcionando como antes y no numera.
Salida adicional del nodo con estos datos: portal, zone, fiscal_doc_number y numbering (el resultado: numerado, ya_numerado, numeracion_desactivada, delegado_en_billpt, esquema_no_aplicado…).
Nodos Relacionados
Sección titulada «Nodos Relacionados»- HubfiscalAggregateSales - Agrupa las ventas del día por portal y las prepara para Sage X3
- HubfiscalStoreBillpt - Actualiza el registro tras crear la factura en Bill.pt
- BillptCreateInvoiceFromShopify - Crea la factura en Bill.pt
- HubfiscalGetDocuments - Consultar pedidos pendientes para workflows de reintento
- HubfiscalUpdateDocument - Actualizar manualmente un registro de documento