Ir al contenido

HubfiscalStoreShopify

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 es completed/failed). Evita duplicados en reintentos del webhook Shopify.
  • Auto-detección: Extrae el pais de billing_address.country_code y 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_attributes de Shopify (clave configurable).
  • Transacción atomica: Inserta en documents, fiscal_status y logs en una sola transacción.
CampoTipoRequeridoDescripción
credentials_idcredentialsSiCredencial Hub Fiscal MySQL/MariaDB (tipo sqlQuery)
country_isotextNoCódigo ISO del pais. Por defecto usa billing_address.country_code
document_typeselectNoFT, FR, ORC, NC. Default: FT
fiscal_providerselectNobillpt, fiskaly, sage. Auto-detectado por pais si esta vacío
initial_statusselectNopending (default) o completed
nif_attributetextNoClave del note_attributes de Shopify donde se guarda el NIF/VAT. Default: nif
entity_sourcetextNoOrigen del pedido: shopify, manual, api. Default: shopify
assign_numberingselectNoNo (default): solo guarda portal y zona. Sí: además asigna el número de serie y pasa a completed (portales sin tercero fiscal)
save_payloadselectNoGuardar el JSON completo en payload_json (hasta 50KB). Default: Si

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)

El nodo mapea los campos del pedido Shopify a Hub Fiscal automáticamente:

Campo Hub FiscalOrigen Shopify
entity_iddata.id
order_numberdata.order_number → data.name
country_isoconfig → billing_address.country_code → PT
typeconfig document_type → FT
fiscal_providerconfig → auto por pais
contact_namebilling_address.name
contact_emaildata.email
contact_nifnote_attributes[nif_attribute].value
total_netdata.subtotal_price
total_taxdata.current_total_tax → data.total_tax
total_grossdata.total_price
currencydata.currency
issued_atdata.created_at (solo fecha)

Cuando fiscal_provider esta vacío, el nodo selecciona el proveedor según country_iso:

PaisProveedor
PT, AO, MZ, CVbillpt
ES, DE, ATfiskaly
Otrosnull (se guarda vacío, rellenar manualmente)

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.

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 completed o failed: el estado se preserva, solo se actualizan totales y payload.

Esto garantiza que un webhook re-entregado nunca sobreescriba un documento ya fiscalizado.

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)"
}

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_status registra la acción inicial register con status: pending para trazabilidad.
  • contact_nif solo se rellena si el pedido Shopify tiene un note_attribute que coincide con nif_attribute. Si el NIF esta en otro lugar (metafields, tags), un nodo Transform anterior puede moverlo a note_attributes.
  • La fecha issued_at se extrae de created_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.
PortalFacturaAbono
equivalenza.comFESHAESH
equivalenza.com (Canarias)FCAHACAH
equivalenza.itFITHAITH
equivalenza.frFFRHAFRH
  • 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…).