← Torna a tutti gli articoli

Come generare una fattura elettronica conforme con n8n e SealDoc

SealDoc Team · · 6 min di lettura

Generare una fattura elettronica conforme comporta più elementi di quanto non sembri. Serve una fattura XML valida, il profilo EN 16931 corretto, un contenitore PDF/A-3 con quell’XML incorporato e, idealmente, un timestamp RFC 3161 prima che il documento finisca in archivio. Costruire tutto questo in un’integrazione personalizzata richiede settimane di lavoro.

Questo tutorial ottiene lo stesso risultato in n8n con il nodo community n8n-nodes-sealdoc. Nessun codice personalizzato. Il flusso di lavoro genera la fattura, recupera l’XML e il PDF/A-3 e li memorizza entrambi.

Prerequisiti

  • Un’istanza n8n self-hosted con i nodi community abilitati.
  • Un workspace SealDoc con accesso API: il piano gratuito Developer o qualsiasi piano a pagamento. Consultare i prezzi.
  • Una chiave API SealDoc. Crearla nell’app SealDoc sotto Integration → API Keys. Copiarla subito: viene mostrata una sola volta.
  • I dati della propria azienda. Il venditore in fattura è la propria azienda, e la sua partita IVA deve corrispondere alla partita IVA del proprio workspace SealDoc.

Installare il nodo in n8n da Settings → Community nodes → Install, con il nome del pacchetto n8n-nodes-sealdoc. Se invece si installano i nodi a mano, eseguire questo comando nella cartella dei nodi di n8n (di solito ~/.n8n/nodes) e riavviare n8n:

npm i n8n-nodes-sealdoc

Poi creare la credenziale: Credentials → New → SealDoc API, e incollare la chiave nel campo API Key. Lasciare Base URL su https://api.sealdoc.eu.

Cosa fa il flusso di lavoro

  1. Un trigger fornisce i dati della fattura come JSON: un webhook, una riga di database, l’invio di un modulo o qualsiasi altra sorgente n8n.
  2. SealDoc · Invoice · Generate costruisce la fattura elettronica, la valida e la sigilla in un PDF/A-3. Tutto avviene all’interno della chiamata: il nodo restituisce un job già concluso.
  3. SealDoc · Invoice · Get XML restituisce l’XML della fattura elettronica come file.
  4. Un nodo HTTP Request scarica il PDF/A-3.
  5. Un nodo di storage deposita entrambi i file nel proprio archivio.

Fase 1: impostare il trigger

Creare un nuovo flusso di lavoro e aggiungere un trigger Webhook con metodo HTTP POST. Si ottiene così un URL che qualsiasi sistema può chiamare con i dati della fattura. Per i test, un Manual Trigger con dati fissi funziona altrettanto bene.

Un esempio minimale di ciò che il trigger può fornire:

{
  "invoiceNumber": "INV-2026-00042",
  "invoiceDate": "2026-05-06",
  "dueDate": "2026-06-05",
  "buyer": {
    "name": "Widget BV",
    "vatNumber": "NL987654321B01",
    "address": "Keizersgracht 10",
    "postalCode": "1015 CN",
    "city": "Amsterdam",
    "country": "NL"
  },
  "line": {
    "description": "Consulting services May 2026",
    "quantity": 10,
    "unitPriceExclVat": 150.00
  }
}

Il venditore non compare in questo payload. È la propria azienda, quindi lo si imposta una volta sola nel nodo.

Fase 2: aggiungere Invoice · Generate

Aggiungere un nodo SealDoc, rinominarlo in Generate invoice e impostare:

  • Resource: Invoice. Operation: Generate.
  • Invoice Number Source: Own Number. Invoice Number: {{ $json.invoiceNumber }}. Si preferisce che sia SealDoc a numerare le fatture? Scegliere invece SealDoc Numbering Series.
  • Invoice Date: {{ $json.invoiceDate }}. Due Date: {{ $json.dueDate }}.
  • Currency: EUR.
  • VAT Rate: 0.21. L’aliquota è una frazione, quindi il 21% è 0.21. Lasciare VAT Category su “derive from the rate” e VAT Label vuoto: per un’aliquota ordinaria, SealDoc scrive da sé la dicitura IVA.
  • Seller: la propria azienda, con Name, VAT Number, Address, Postal Code, City e Country (codice a due lettere).
  • Buyer Source: Buyer Details. Buyer: mappare ogni campo dal trigger, ad esempio {{ $json.buyer.name }} e {{ $json.buyer.postalCode }}. I clienti salvati in SealDoc si possono usare direttamente con Buyer Profile.
  • Lines: aggiungere una riga con Description {{ $json.line.description }}, Quantity {{ $json.line.quantity }}, Unit Hour e Unit Price (Excl. VAT) {{ $json.line.unitPriceExclVat }}.
  • Profile: Basic (Factur-X 1.0). Il nodo offre anche XRechnung DE, che richiede un Buyer Reference (il Leitweg-ID) e un contatto del venditore, e Peppol BIS 3.0 (UBL 2.1), che richiede gli ID endpoint Peppol di entrambe le parti.
  • RFC 3161 Timestamp: attivo, come da impostazione predefinita.

Selezionare la credenziale SealDoc API ed eseguire il nodo. La risposta ha questo aspetto:

{
  "jobId": "3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10",
  "status": "completed",
  "statusUrl": "/api/jobs/3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10"
}

completed significa che la fattura è costruita, validata secondo EN 16931 e sigillata. Non c’è nulla su cui fare polling. Se una risposta dovesse indicare invece queued o processing, un nodo SealDoc · Job · Get con lo stesso jobId segnala quando il job è concluso.

Fase 3: ottenere l’XML

Aggiungere un secondo nodo SealDoc: Resource Invoice, Operation Get XML, Job ID {{ $('Generate invoice').item.json.jobId }}. Il nodo restituisce l’XML della fattura elettronica come file binario nel campo data: factur-x.xml per il profilo Basic, xrechnung.xml per XRechnung e peppol-ubl.xml per Peppol BIS.

Fase 4: scaricare il PDF/A-3

Aggiungere un nodo HTTP Request:

  • Method: GET
  • URL: https://api.sealdoc.eu/api/download/{{ $('Generate invoice').item.json.jobId }}
  • Authentication: Generic Credential Type, poi Header Auth, con nome X-Api-Key e la propria chiave API come valore.
  • Response Format: File.

Il risultato è il PDF/A-3 sigillato con l’XML incorporato.

Fase 5: memorizzare il risultato

Aggiungere il nodo di storage più adatto al proprio stack: Google Drive, Dropbox, un bucket compatibile S3, SFTP verso il proprio server, oppure Write Binary File direttamente sull’host n8n.

A partire dal piano Starter, ogni job ha anche un Legal Evidence Pack: GET /api/jobs/{id}/evidence-pack, con lo stesso header X-Api-Key. SealDoc lo assembla subito dopo il job; se lo si richiede nei primi istanti, l’API risponde 409 con un header Retry-After, quindi basta un breve nodo Wait prima della richiesta.

Quando qualcosa va storto

Gli errori tornano immediatamente, come risposta con un code:

  • 400 per input non valido, ad esempio seller_required, currency_required o invalid_vat_rate.
  • 402 plan_feature_required quando il piano non include la funzionalità.
  • 403 seller_vat_mismatch quando la partita IVA del venditore è diversa da quella del workspace.
  • 409 quota_reached quando il limite mensile è esaurito.
  • 422 einvoice_invalid quando la fattura non supera la validazione.

Per impostazione predefinita il nodo SealDoc interrompe il flusso di lavoro in caso di errore. Impostare On Error del nodo in modo che continui con un output di errore e instradare quell’output verso Slack o e-mail, così che una persona veda cosa va corretto.

Cosa si ottiene

Un PDF/A-3 che qualsiasi visualizzatore PDF apre come fattura leggibile, con l’XML incorporato per i software contabili che importano Factur-X o ZUGFeRD. Il token di timestamp RFC 3161 è conservato insieme al job e si può scaricare separatamente (GET /api/jobs/{id}/timestamp). Basta caricare il PDF nel nostro Validator gratuito per vedere di persona il verdetto e ogni singolo rilievo.

Prossimi passi

  • Validare fatture esistenti: SealDoc · Validator · Check valida un file Factur-X o ZUGFeRD già in proprio possesso, senza generare nulla.
  • Produrre altri documenti: SealDoc · Document · Generate trasforma Markdown o HTML in un PDF/A-3 sigillato con una sola chiamata.
  • Rileggere ciò che è stato emesso: SealDoc · Invoice · Get Summary restituisce numero di fattura, profilo, lingua e totali IVA di una fattura generata.

Il riferimento completo dell’API, con spec OpenAPI ed esempi curl, è raggiungibile dalla nostra pagina developers.

Valida la tua fattura, senza account →
← Torna a tutti gli articoli