Build FatturaPA electronic invoices with a type-safe fluent API.
import { FatturaBuilder, FatturaSerializer, FatturaValidator } from '@fatturazione-elettronica-aruba/xml-builder';
Use the flat-input helpers (cedentePrestatore, cessionario) together with
addLinea to skip nested objects and manual VAT math. The builder computes
DatiRiepilogo and ImportoTotaleDocumento from the lines, and toResult()
returns the object, the XML, the validation result and the SDI filename in one call.
import {
FatturaBuilder,
cedentePrestatore,
cessionario,
} from '@fatturazione-elettronica-aruba/xml-builder';
const { xml, filename, validazione } = FatturaBuilder.create()
.setTrasmissioneB2B({
idPaese: 'IT',
idCodice: '01234567890',
progressivoInvio: '1',
codiceDestinatario: 'ABC1234',
})
.setCedentePrestatore(cedentePrestatore({
piva: '01234567890',
denominazione: 'Azienda SRL',
regimeFiscale: 'RF01',
indirizzo: 'Via Roma 1', cap: '00100', comune: 'Roma', provincia: 'RM',
email: 'info@azienda.it',
}))
.setCessionarioCommittente(cessionario({
piva: '09876543210',
denominazione: 'Cliente SPA',
indirizzo: 'Via Milano 10', cap: '20100', comune: 'Milano', provincia: 'MI',
}))
.setDatiGenerali({
datiGeneraliDocumento: { tipoDocumento: 'TD01', divisa: 'EUR', data: '2024-01-15', numero: '1' },
})
// numeroLinea, prezzoTotale, datiRiepilogo and importoTotaleDocumento are computed automatically
.addLinea({ descrizione: 'Consulting service', quantita: 10, unitaMisura: 'hours', prezzoUnitario: 100, aliquotaIVA: 22 })
.toResult();
// validazione.valid === true
// filename === 'IT01234567890_00001.xml'
number) no longer crash the
serializer — you don't need to convert them manually.The full fluent API below remains supported for advanced cases (explicit
DatiRiepilogo, batch invoices, etc.).
const fattura = FatturaBuilder.create()
.setTrasmissioneB2B({
idPaese: 'IT',
idCodice: '01234567890',
progressivoInvio: '00001',
codiceDestinatario: 'ABC1234',
})
.setCedentePrestatore({
datiAnagrafici: {
idFiscaleIVA: { idPaese: 'IT', idCodice: '01234567890' },
anagrafica: { denominazione: 'Azienda SRL' },
regimeFiscale: 'RF01',
},
sede: {
indirizzo: 'Via Roma 1',
cap: '00100',
comune: 'Roma',
provincia: 'RM',
nazione: 'IT',
},
})
.setCessionarioCommittente({
datiAnagrafici: {
idFiscaleIVA: { idPaese: 'IT', idCodice: '09876543210' },
anagrafica: { denominazione: 'Cliente SPA' },
},
sede: {
indirizzo: 'Via Milano 10',
cap: '20100',
comune: 'Milano',
provincia: 'MI',
nazione: 'IT',
},
})
.setDatiGenerali({
datiGeneraliDocumento: {
tipoDocumento: 'TD01',
divisa: 'EUR',
data: '2024-01-15',
numero: '1',
},
})
.setDatiBeniServizi({
dettaglioLinee: [
{
numeroLinea: 1,
descrizione: 'Consulting service',
quantita: 10,
unitaMisura: 'hours',
prezzoUnitario: 100.0,
prezzoTotale: 1000.0,
aliquotaIVA: 22.0,
},
],
datiRiepilogo: [
{
aliquotaIVA: 22.0,
imponibileImporto: 1000.0,
imposta: 220.0,
esigibilitaIVA: 'I',
},
],
})
.build();
For invoices to Public Administration:
const fattura = FatturaBuilder.create()
.setTrasmissionePA({
idPaese: 'IT',
idCodice: '01234567890',
progressivoInvio: '00001',
codiceDestinatario: 'ABCDEF', // 6-char IPA code
})
// ... rest of the invoice
.build();
const fattura = FatturaBuilder.create()
// ... invoice data
.addDatiPagamento({
condizioniPagamento: 'TP02', // Full payment
dettaglioPagamento: [
{
modalitaPagamento: 'MP05', // Bank transfer
importoPagamento: 1220.0,
iban: 'IT60X0542811101000000123456',
dataScadenzaPagamento: '2024-02-15',
},
],
})
.build();
const fattura = FatturaBuilder.create()
.setTrasmissioneB2B({ /* ... */ })
.setCedentePrestatore({ /* ... */ })
.setCessionarioCommittente({ /* ... */ })
// First invoice
.setDatiGenerali({ datiGeneraliDocumento: { numero: '1', /* ... */ } })
.setDatiBeniServizi({ /* ... */ })
.newBody() // Start new invoice in batch
// Second invoice
.setDatiGenerali({ datiGeneraliDocumento: { numero: '2', /* ... */ } })
.setDatiBeniServizi({ /* ... */ })
.build();
// fattura.fatturaElettronicaBody.length === 2
import { FatturaValidator, validateFattura } from '@fatturazione-elettronica-aruba/xml-builder';
// Method 1: Instance
const validator = new FatturaValidator({ strict: true });
const result = validator.validate(fattura);
// Method 2: Helper
const result = validateFattura(fattura, { validateTotals: true });
// Method 3: Directly from the builder (no need to call build() first)
const result = FatturaBuilder.create()/* ... */.validate({ strict: true });
if (!result.valid) {
console.log('Errors:', result.errors);
console.log('Warnings:', result.warnings);
}
const result = validateFattura(fattura, {
validateTotals: true, // Verify totals
validateCodiceFiscale: true, // Verify fiscal code
validatePartitaIVA: true, // Verify VAT number
validateDates: true, // Verify dates
strict: false, // Treat warnings as errors
});
import { FatturaSerializer } from '@fatturazione-elettronica-aruba/xml-builder';
const serializer = new FatturaSerializer({
includeSchemaLocation: true,
});
const xml = serializer.serialize(fattura);
console.log(xml);
// <?xml version="1.0" encoding="UTF-8"?>
// <p:FatturaElettronica xmlns:p="..." versione="FPR12">
// ...
// </p:FatturaElettronica>
To send the invoice, use the invoices module:
import { ArubaClient } from '@fatturazione-elettronica-aruba/core';
import { InvoicesClient } from '@fatturazione-elettronica-aruba/invoices';
import { FatturaBuilder, FatturaSerializer, validateFattura } from '@fatturazione-elettronica-aruba/xml-builder';
// 1. Setup client
const client = new ArubaClient({ environment: 'demo' });
await client.auth.signin('username', 'password');
const invoices = new InvoicesClient(client.http);
// 2. Build invoice
const fattura = FatturaBuilder.create()
.setTrasmissioneB2B({ /* ... */ })
.setCedentePrestatore({ /* ... */ })
.setCessionarioCommittente({ /* ... */ })
.setDatiGenerali({ /* ... */ })
.setDatiBeniServizi({ /* ... */ })
.build();
// 3. Validate (optional)
const validation = validateFattura(fattura);
if (!validation.valid) {
throw new Error(`Invalid invoice: ${JSON.stringify(validation.errors)}`);
}
// 4. Serialize to XML
const serializer = new FatturaSerializer();
const xml = serializer.serialize(fattura);
// 5. Encode to Base64
const base64 = Buffer.from(xml, 'utf-8').toString('base64');
// 6. Send
const result = await invoices.upload({
dataFile: base64,
dryRun: false, // true for validation only
});
console.log('Invoice sent:', result.uploadFileName);
| Code | Description |
|---|---|
TD01 | Invoice |
TD02 | Advance/Down payment on invoice |
TD03 | Advance/Down payment on fee note |
TD04 | Credit note |
TD05 | Debit note |
TD06 | Fee note |
TD16 | Reverse charge integration (internal) |
TD17 | Integration/self-invoice for foreign services |
TD24 | Deferred invoice |
TD25 | Deferred invoice (triangulation) |
TD26 | Transfer of depreciable assets |
| Code | Description |
|---|---|
RF01 | Ordinary |
RF02 | Minimum taxpayers |
RF04 | Agriculture |
RF19 | Flat-rate |