Skip to content

HubfiscalCreateDocument

Registers a fiscal document in the Hub Fiscal, an external SQL Server database that acts as a central hub for all fiscal operations. The node consolidates orders from Shopify (or other sources) along with the results from fiscal providers (Bill.pt, Fiskaly, Sage) into a single unified database.

Key features:

  • MERGE (upsert): If the order already exists it updates, otherwise creates. Prevents duplicates.
  • Auto-detection: Extracts country from billing_address, detects fiscal provider by country (PT=billpt, ES=fiskaly).
  • Atomic transaction: Inserts into documents, fiscal_status and logs tables in one transaction.
  • Ticket storage: Stores the HTML ticket and/or PDF binary returned by the fiscal provider.
FieldTypeRequiredDescription
credentials_idcredentialsYesHub Fiscal SQL Server (MSSQL) credential
entity_idtextNoOrder ID (Shopify). If empty, uses data.id
entity_sourceselectNoOrigin: shopify, prestashop, woocommerce, manual, api. Default: shopify
order_numbertextNoVisible order number (e.g. PT14684). If empty, uses data.name
country_isotextNoISO country code (PT, ES, AO, MZ). If empty, extracts from billing_address
doc_typeselectNoDocument type: FT, FR, NC, ORC. Default: FT
fiscal_providerselectNoFiscal provider: billpt, fiskaly, sage. Auto-detected by country if empty
fiscal_doc_idtextNoDocument ID returned by fiscal provider
fiscal_doc_numbertextNoInvoice number from fiscal provider
contact_nametextNoContact name. If empty, extracts from billing_address
contact_niftextNoContact tax number (NIF)
contact_emailtextNoContact email
total_nettextNoNet total (tax base). If empty, uses data.subtotal_price
total_taxtextNoTax total. If empty, uses data.current_total_tax
total_grosstextNoGross total. If empty, calculated as net + tax
currencytextNoISO currency (default: EUR)
issued_attextNoIssue date ISO. If empty, uses current date
ticket_htmltextareaNoTicket HTML from Bill.pt or other provider
ticket_pdftextareaNoTicket PDF in base64. Stored as binary in SQL Server
assign_numberingselectNoNo (default): only stores portal and zone. Yes: also assigns the series number and sets completed (portals without a fiscal third party)
save_payloadselectNoSave full order JSON in payload_json (max 50KB). Default: Yes
timeouttextNoTimeout in milliseconds (default: 30000)

This module requires a hubfiscalCreateDocument type credential (SQL Server) with:

  • host: SQL Server hostname or IP
  • user: Database username
  • password: Database password
  • database: Hub Fiscal database name
  • port: Port (default: 1433)

The credential test verifies the connection and checks that all Hub Fiscal tables exist (documents, fiscal_status, logs, countries, reports_cache).

The Hub Fiscal database requires 5 tables. The SQL schema is included in the module at modules/hubfiscalCreateDocument/schema.sql.

TablePurpose
documentsCentral fiscal document (order + status + totals + tickets)
fiscal_statusEach fiscalization attempt (request/response per provider)
logsSystem events and errors
countriesEnabled countries for fiscalization
reports_cachePre-calculated report cache for dashboard KPIs
{
"success": true,
"hub_document_id": 42,
"entity_id": "6702987051221",
"order_number": "PT14684",
"country_iso": "PT",
"type": "FT",
"status": "completed",
"fiscal_provider": "billpt",
"fiscal_doc_id": "789",
"fiscal_doc_number": "FT 2026/1",
"total_gross": 19.90,
"currency": "EUR",
"message": "Documento registrado en Hub Fiscal (ID: 42)"
}

Typical flow: Shopify Webhook → Decision (country) → Bill.pt (create invoice) → HubfiscalCreateDocument

{
"credentials_id": "10",
"entity_id": "{{id}}",
"order_number": "{{name}}",
"country_iso": "{{billing_address.country_code}}",
"doc_type": "FT",
"contact_name": "{{billing_address.name}}",
"contact_email": "{{email}}",
"total_net": "{{subtotal_price}}",
"total_tax": "{{current_total_tax}}",
"total_gross": "{{total_price}}"
}

Most fields are auto-detected from the previous node’s data, so a minimal configuration works:

{
"credentials_id": "10",
"save_payload": "true"
}
  • The documents table has a unique constraint on (entity_id, entity_source, type) to prevent duplicates
  • If the previous node returned error, the document is saved with status: "failed" and the error message is stored
  • If the previous node returned success: true, the document is saved with status: "completed"
  • The ticket_html field stores HTML content as NVARCHAR(MAX) (up to 2GB, queryable)
  • The ticket_pdf field stores binary PDF as VARBINARY(MAX) (accepts base64 input, converted to Buffer)
  • The original order payload is truncated to 50KB to avoid excessive storage
  • Provider auto-detection: PT → billpt, ES → fiskaly, AO → billpt, MZ → billpt

Portal and numbering (daily aggregation to Sage X3)

Section titled “Portal and numbering (daily aggregation to Sage X3)”

Besides storing the document, the node determines the sales portal (equivalenza.com, .it, .fr or .pt) from the order and the zone (Canary Islands, if the shipping postal code starts with 35 or 38), and stores them on the document. HubfiscalAggregateSales uses this to group the day’s sales.

With the Number and complete option set to Yes, on portals without a fiscal third party (equivalenza.com, .it and .fr) the node also:

  • assigns the next sequential number of the series, with no leading zeros and no yearly reset (FESH1, FESH2…), and
  • sets the document to completed.
PortalInvoiceCredit note
equivalenza.comFESHAESH
equivalenza.com (Canary Islands)FCAHACAH
equivalenza.itFITHAITH
equivalenza.frFFRHAFRH
  • No gaps or duplicates, even when orders arrive at the same time: each series counter is locked while assigning, and an error does not consume the number.
  • Idempotent: resending the same order does not renumber it.
  • equivalenza.pt is not numbered here: Bill.pt does it (FHPT / AHPT).
  • A type other than invoice or credit note (for example ORC) or a portal with no rule is not numbered.
  • It is off by default (No): only portal and zone are stored. Turn it on when you decide from which day numbering starts, because numbering consumes real series numbers.

It requires applying to the Hub Fiscal database the portal and zone columns and the document_sequences and portal_providers tables. If they are not applied, the node keeps working as before and does not number.

Extra node output with this data: portal, zone, fiscal_doc_number and numbering (the result: numerado, ya_numerado, numeracion_desactivada, delegado_en_billpt, esquema_no_aplicado…).