Genera la tua prima fattura elettronica XML per lo SDI in TypeScript — in 10 minuti

Iniciado por joomlamz, 30 de Maio de 2026, 00:00

Respostas: 0   |   Visualizações: 13

Tópico anterior - Tópico seguinte

0 Membros e 2 Visitantes estão a ver este tópico.

Genera la tua prima fattura elettronica XML per lo SDI in TypeScript — in 10 minuti



Tópico: Genera la tua prima fattura elettronica XML per lo SDI in TypeScript — in 10 minuti
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------


Genera la tua prima fattura elettronica XML per lo SDI in TypeScript (in 10 minuti)


Se hai mai dovuto integrare la fatturazione elettronica italiana in un progetto Node.js, sai già quanto è scomodo: specifiche FatturaPA di 200 pagine, regole cross-field non documentate, codici errore SDI criptici, e librerie npm o abbandonate o in PHP.

Questo articolo mostra come generare un XML valido per il Sistema di Interscambio (SDI) usando fattura-elettronica-sdi-builder, una libreria TypeScript open-source che copre B2B (FPR12) e Pubblica Amministrazione (FPA12).



Installazione


npm install fattura-elettronica-sdi-builder

Nessuna dipendenza pesante. La validazione è custom e tipizzata, zero runtime esterni.



Il flusso in tre funzioni


La libreria espone tre funzioni pubbliche che si usano sempre in sequenza:

import { applyDefaults, validate, buildXml } from 'fattura-elettronica-sdi-builder';

Funzione
Input
Output

applyDefaults(input)

FatturaElettronicaInput (campi deducibili opzionali)

FatturaElettronica completa

validate(fattura)
FatturaElettronica
Result<void, ValidationError>

buildXml(fattura, options?)
FatturaElettronica
Result<string, BuildError>

Tutte le funzioni restituiscono un Result<T, E> — mai eccezioni non gestite:

type Result<T, E> =
| { ok: true;  value: T }
| { ok: false; error: E }



Esempio completo: fattura B2B con IVA ordinaria


Genera una fattura TD01 da una Srl italiana a un cliente italiano, IVA al 22%, pagamento con bonifico.

import { applyDefaults, validate, buildXml } from 'fattura-elettronica-sdi-builder';
import type { FatturaElettronicaInput } from 'fattura-elettronica-sdi-builder';
import { writeFileSync } from 'fs';

const input: FatturaElettronicaInput = {
FatturaElettronicaHeader: {
DatiTrasmissione: {
ProgressivoInvio:   '00001',
CodiceDestinatario: 'ABC1234', // 7 caratteri per FPR12
},
CedentePrestatore: {
DatiAnagrafici: {
IdFiscaleIVA:  { IdPaese: 'IT', IdCodice: '01234567890' },
Anagrafica:    { Denominazione: 'La Mia Azienda Srl' },
RegimeFiscale: 'RF01',
},
Sede: {
Indirizzo: 'Via Roma 1',
CAP:       '00100',
Comune:    'Roma',
Provincia: 'RM',
Nazione:   'IT',
},
},
CessionarioCommittente: {
DatiAnagrafici: {
IdFiscaleIVA: { IdPaese: 'IT', IdCodice: '09876543210' },
Anagrafica:   { Denominazione: 'Cliente Spa' },
},
Sede: {
Indirizzo: 'Via Milano 10',
CAP:       '20100',
Comune:    'Milano',
Provincia: 'MI',
Nazione:   'IT',
},
},
},
FatturaElettronicaBody: {
DatiGenerali: {
DatiGeneraliDocumento: {
TipoDocumento: 'TD01',
Numero:        'FT-2026-001',
// Divisa e Data sono opzionali: applyDefaults li imposta a 'EUR' e oggi
},
},
DatiBeniServizi: {
DettaglioLinee: [
{
NumeroLinea:    1,
Descrizione:    'Servizio di consulenza',
Quantita:       1,
PrezzoUnitario: 100.00,
PrezzoTotale:   100.00,
AliquotaIVA:    22,
},
],
DatiRiepilogo: [
{
AliquotaIVA:       22,
ImponibileImporto: 100.00,
Imposta:           22.00, // opzionale: applyDefaults lo calcola
EsigibilitaIVA:    'I',
},
],
},
DatiPagamento: [
{
CondizioniPagamento: 'TP02',
DettaglioPagamento: [
{
ModalitaPagamento:     'MP05', // bonifico
DataScadenzaPagamento: '2026-06-18',
ImportoPagamento:      122.00,
IBAN:                  'IT60X0542811101000000123456',
},
],
},
],
},
};

// 1. Deduce i valori opzionali
const fattura = applyDefaults(input);

// 2. Valida
const validation = validate(fattura);
if (!validation.ok) {
validation.error.fields.forEach(({ code, field, message }) => {
console.error(`[${code}] ${field}: ${message}`);
});
process.exit(1);
}

// 3. Genera XML
const build = buildXml(fattura, { prettyPrint: true });
if (!build.ok) {
console.error(build.error.message);
process.exit(1);
}

// Naming convention SDI: {IdPaese}{IdCodice}_{Formato}_{Progressivo}.xml
writeFileSync('IT01234567890_FPR12_00001.xml', build.value, 'utf-8');
console.log('Fattura generata.');

Nota: IdTrasmittente e FormatoTrasmissione sono omessi — applyDefaults li deduce automaticamente da CedentePrestatore.



I default che applyDefaults gestisce per te


Uno dei problemi più fastidiosi della FatturaPA è la quantità di campi che si possono dedurre ma che comunque vanno valorizzati nell'XML. applyDefaults li gestisce:

Campo omesso
Valore dedotto

IdTrasmittente
Copiato da CedentePrestatore.DatiAnagrafici.IdFiscaleIVA

FormatoTrasmissione
"FPR12"

CodiceDestinatario

"XXXXXXX" se cliente estero

Divisa
"EUR"

Data
Data odierna YYYY-MM-DD

DatiRiepilogo.Imposta
Calcolato da ImponibileImporto × AliquotaIVA / 100



Gestione degli errori SDI


La validazione restituisce errori tipizzati con i codici errore SDI ufficiali. Esempio: se CodiceDestinatario ha lunghezza sbagliata per il formato scelto, o se AliquotaIVA = 0 senza Natura, o se PrezzoTotale non corrisponde al calcolo atteso (SDI 00423):

const validation = validate(fattura);

if (!validation.ok) {
validation.error.fields.forEach(({ code, field, message }) => {
console.error(`[${code}] ${field}: ${message}`);
// Esempio: [MISSING_NATURA] DatiBeniServizi.DettaglioLinee[0].Natura: ...
// Esempio: [INVALID_VALUE]  DatiTrasmissione.CodiceDestinatario: ...
});
}

I codici errore sono tipizzati (ErrorCode) — puoi fare switch su di essi senza magic string.



Tre casi d'uso in 30 righe




Fattura PA (FPA12)


DatiTrasmissione: {
FormatoTrasmissione: 'FPA12',
CodiceDestinatario:  'ABCDE1', // 6 caratteri: codice IPA
ProgressivoInvio:    '00001',
},



Cliente estero


// CodiceDestinatario deve essere 'XXXXXXX' se cliente non IT
DatiTrasmissione: {
CodiceDestinatario: 'XXXXXXX',
},
CessionarioCommittente: {
DatiAnagrafici: {
IdFiscaleIVA: { IdPaese: 'DE', IdCodice: 'DE123456789' },
Anagrafica:   { Denominazione: 'German GmbH' },
},
Sede: { Indirizzo: 'Hauptstrasse 1', CAP: '10115', Comune: 'Berlin', Nazione: 'DE' },
},



Operazione esente IVA (es. prestazione medica)


DettaglioLinee: [{
NumeroLinea:    1,
Descrizione:    'Prestazione medica',
PrezzoUnitario: 200.00,
PrezzoTotale:   200.00,
AliquotaIVA:    0,
Natura:         'N4', // obbligatorio quando AliquotaIVA = 0
}],
DatiRiepilogo: [{
AliquotaIVA:          0,
Natura:               'N4',
ImponibileImporto:    200.00,
Imposta:              0,
RiferimentoNormativo: 'art. 10 DPR 633/72',
}],



Tipi di documento supportati


La libreria copre tutti i TipoDocumento da TD01 a TD29, incluse autofatture (TD16–TD23), fatture differite (TD24/TD25), parcelle con ritenuta (TD06), e fatture semplificate (TD07–TD09). Per ognuno vengono applicate le regole cross-field specifiche delle specifiche SDI v1.7.1.



Link



npm: https://www.npmjs.com/package/fattura-elettronica-sdi-builder


GitHub: https://github.com/GiuseppeSerio/fattura-elettronica-sdi-builder

• Licenza MIT — contributi benvenuti

Se lo stai usando o valutando, apri una issue o scrivi a [email protected]. Qualsiasi feedback è utile.


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: