Ir al contenido

Italia — E-INVOICE IT (Unified API)

En Italia, fiskaly admite el envío de facturas electrónicas B2B y B2C, y la recepción de facturas electrónicas B2B. Actualmente admitimos la Factura estándar (Fattura, TD01) y la Nota de crédito (Nota di credito, TD04). El tipo de documento se deriva de la operación de la Unified API y no se establece directamente. Las facturas de anticipo (TD02) y las facturas diferidas (TD24, TD25) no se emiten actualmente. El soporte para la Factura simplificada (Fattura semplificata, TD07) llegará próximamente.

La facturación electrónica es obligatoria y está regulada por la Agenzia delle Entrate (Agencia Tributaria). Todas las facturas B2B deben intercambiarse a través del SDI (Sistema di Interscambio — Sistema de Intercambio) en el formato XML FatturaPA (factura electrónica) y son obligatorias por ley desde enero de 2019. Las facturas también deben conservarse a largo plazo mediante archivado certificado (conservazione a norma).

Esta página cubre los requisitos específicos para Italia que complementan la Guía de integración general paso a paso para dar de alta un Taxpayer en la facturación electrónica.

fiskaly gestiona ambas direcciones del intercambio con el SDI, y las dos funcionan de forma diferente:

Además del intercambio en ambas direcciones, fiskaly archiva automáticamente cada factura que envías y recibes. Esto supone la conservación certificada a largo plazo (conservazione a norma) durante los 10 años exigidos por ley, sin ninguna configuración por tu parte.

Estos requisitos se aplican a cualquier Taxpayer que des de alta para la facturación electrónica en Italia, ya sea que envíes, recibas o hagas ambas cosas. Asegúrate de tener disponible la siguiente información del Taxpayer antes de continuar.

Datos de registro específicos para Italia — enviados en content.fiscalization.registration:

  • company_id — Numero Registro Imprese (número del Registro Mercantil)
  • office — código de provincia de la Camera di Commercio que emitió el número REA, p. ej. MI, RM
  • entry — número REA (6 o 7 dígitos)
  • legal_form — forma jurídica de la entidad (p. ej. LIMITED_LIABILITY_COMPANY, JOINT_STOCK_COMPANY)
  • capital — capital social registrado en EUR (p. ej. "10000.00")
  • shareholder_status — SOLE_SHAREHOLDER o MULTIPLE_SHAREHOLDERS
  • liquidation_status — IN_LIQUIDATION o NOT_IN_LIQUIDATION
  • tax_regime — opcional, ORDINARY (predeterminado) o FLAT_RATE_SCHEME (Regime Forfettario)

Campos estándar del Taxpayer — parte del propio Taxpayer (compartidos con SIGN IT si lo utiliza):

  • content.name — denominación legal registrada de la empresa o del individuo
  • content.address — dirección legal registrada
  • content.address.region — Provincia (código de provincia, p. ej. MI, RM); obligatorio en el Taxpayer y validado al poner en servicio

Envío de facturas electrónicas: requisitos del destinatario

Sección titulada «Envío de facturas electrónicas: requisitos del destinatario»

Para enviar una factura electrónica, indica su destinatario y sus datos de enrutamiento directamente en el Record de la factura. Cuando crees la factura (TRANSACTION::INVOICE) con createRecord, añade el destinatario a su array recipients. Los campos que debes rellenar dependen de a quién facturas:

Todo destinatario lleva invoicing.type = SDI. Lo que cambia entre los tres casos es la identificación, el código de destinatario y si interviene o no una PEC:

EmpresaConsumidor en ItaliaConsumidor en el extranjero
typeBUSINESSCONSUMERCONSUMER
identificationVAT — validadoTAX — codice fiscale, validadocualquier tipo; sin validar
invoicing.destination_codeel código de 7 caracteres del destinatario, o "0000000", o "XXXXXXX""0000000""XXXXXXX"
invoicing.pecobligatoria con "0000000"opcionalno se utiliza
address.regionobligatoria cuando la dirección está en Italiaobligatoriano obligatoria
namenombre de la empresagender, forename, surnamegender, forename, surname

Cada destinatario empresa es de tipo BUSINESS con el bloque invoicing cumplimentado, como explica la integración general paso a paso. Además de los datos estándar que requiere toda factura electrónica (nombre del destinatario, dirección, identificación fiscal, líneas de factura, etc.), Italia añade los campos de enrutamiento SDI indicados arriba.

Los valores que toman destination_code y pec dependen del destinatario:

Escenariodestination_codepec
El destinatario tiene un buzón SDI registradosu código de 7 caracteres (p. ej. ABC1234)opcional
El destinatario no está registrado en el SDI"0000000"obligatorio
El destinatario está fuera de Italia"XXXXXXX"no se utiliza

Cuando tu cliente es un particular y no una empresa, establece recipients[].type en CONSUMER. La factura circula por el SDI como documento FatturaPA (TD01), igual que una factura B2B.

Los consumidores no tienen buzón SDI, así que el enrutamiento funciona de otra manera. Cómo identifique al consumidor depende de si reside en Italia:

  • Residente en Italia — se identifica por su codice fiscale y se enruta con el código de destinatario "0000000".
  • Fuera de Italia — no existe codice fiscale, por lo que un identificador extranjero ocupa su lugar y la factura se enruta con "XXXXXXX".

Además de los campos de la tabla anterior, un destinatario consumidor lleva siempre name.gender, name.forename y name.surname, junto con su dirección.

Envía el codice fiscale como identificación de tipo TAX (16 caracteres), el domicilio de residencia incluida la region (Provincia) y el código de destinatario "0000000". Puede añadirse una pec, pero no es obligatoria.

Un consumidor que no reside en Italia no tiene codice fiscale, así que envía en su lugar un identificador extranjero, normalmente un número fiscal o de IVA extranjero.

CampoValor
recipients[].identificationobligatoria; VAT, TAX, PASSPORT, DOCUMENT u OTHER, según el identificador del que disponga
recipients[].address.countryel país del consumidor como código ISO 3166-1 alfa-2
recipients[].address.code"00000": FatturaPA solo acepta un código postal de 5 dígitos
recipients[].invoicing.destination_code"XXXXXXX"

El identificador viaja al SDI como IdCodice; ni fiskaly ni el SDI comprueban su validez en cuanto el país de la dirección no es Italia. La region no es obligatoria para una dirección no italiana.

Para un consumidor residente en Italia, el SDI deposita la factura original en su área reservada en el portal de la AdE (Fatture e Corrispettivi).

Cuando el cliente necesita una factura en lugar de un documento commerciale

Sección titulada «Cuando el cliente necesita una factura en lugar de un documento commerciale»

Italia declara los dos documentos por canales separados —el documento commerciale por los corrispettivi, la factura por el SDI— y nada los vincula automáticamente.

Recoge la petición antes de cerrar la venta. Cuando el cliente te indique que necesita una fattura, emite una TRANSACTION::INVOICE en lugar de una TRANSACTION::RECEIPT. Es el flujo que fiskaly admite de principio a fin hoy, tanto si el cliente lo pide antes como durante la venta.

A diferencia de una llamada de API síncrona, el resultado del SDI es asíncrono. Tras crear la factura (TRANSACTION::INVOICE) con createRecord, consulta periódicamente el Record E_INVOICE::TRANSMISSION para saber si el SDI la ha aceptado. No existe ningún webhook.

Los tres Records alcanzan su estado final de forma conjunta:

RecordEstado final
E_INVOICE::TRANSMISSIONCOMPLETED o FAILED, mode=FINISHED
TRANSACTION::INVOICECOMPLETED o FAILED, mode=FINISHED
INTENTION::TRANSACTIONCOMPLETED o FAILED, mode=FINISHED

En caso de fallo, el motivo de rechazo del SDI está disponible en logs[].message en los tres Records. Para más detalles, consulta How to check the status of an e-invoice en nuestra página de Soporte.

state te indica en qué punto está una factura y logs[] te indica por qué. Léelos juntos y actúa según lo que encuentres:

Qué vesQué significaQué hacer
4xx de createRecord, ningún Record creadoEl payload se rechazó. No se creó nada y no se envió nada.Corrige el payload y reinténtalo en el mismo INTENTION::TRANSACTION.
state=ACCEPTEDTodavía en curso.Consulta el Record E_INVOICE::TRANSMISSION. Los resultados suelen llegar en cuestión de minutos.
state=FAILEDFinalizada, y la factura no es legalmente válida. O se detuvo camino al SDI o el SDI la rechazó con NS.Lee logs[].message para conocer el motivo, corrige los datos e inicia una nueva cadena — consulta Fallos y reenvío.
state=COMPLETED con una entrada ERROR en logs[]Algo salió mal por el camino sin detener la factura.Lee logs[].message antes de dar la factura por enviada.
state=COMPLETED, sin entradas ERROREl SDI aceptó la factura.Nada más.

Cada entrada de logs[] es un ERROR o un WARNING. Un WARNING es informativo y nunca bloquea una factura — recibes uno cuando algo de tu payload se ajustó o no cuadraba, por ejemplo si enviaste varios pagos pendientes y solo se usó el primero, o si los totales de IVA de tu payload difieren de los totales calculados a partir de las líneas de la factura.

Dónde se manifiestan los fallos de validación

Sección titulada «Dónde se manifiestan los fallos de validación»

No todo rechazo parece un rechazo. Los datos de la factura se comprueban en tres puntos distintos, y cada uno falla de una forma diferente:

Dónde fallaEjemploQué ves
Restricciones de esquemaidentification.number fuera de AlphaNumerical28; document.number fuera de ^[0-9A-Z_/\-\.]{1,20}$400 de createRecord. No se crea nada.
Validación de campoUn codice fiscale con formato incorrecto o dígito de control erróneocreateRecord funciona. El Record se cierra en COMPLETED / FINISHED, pero content.used_in está ausente y no se transmite nada. El motivo aparece únicamente como entrada de content.logs con severidad ERROR.
Aguas abajoUn recipients[].address.region ausentecreateRecord funciona y la cadena pasa después a FAILED.

Si el SDI devuelve NS (Notifica di Scarto), la factura es legalmente inexistente:

  1. Lee logs[].message en cualquiera de los tres Records para obtener el motivo de rechazo del SDI
  2. Crea una nueva INTENTION::TRANSACTION y una nueva TRANSACTION::INVOICE con los datos corregidos
  3. El mismo document.number puede reutilizarse dentro de los 5 días posteriores al rechazo NS
  4. La cadena fallida permanece FAILED de forma permanente — se conserva con fines de auditoría

Un System E_INVOICE_SERVICE puede tanto enviar como recibir facturas electrónicas. La recepción es opcional — un Taxpayer que solo envía puede omitir esta sección.

Intervienen dos cosas separadas e independientes:

  • Disponibilidad para recibir — fiskaly la configura automáticamente cuando pones en servicio el System.
  • Registro del código de destinatario SDI (manual, realizado por ti) — en tu portal de la Agenzia delle Entrate (AdE), establece el código de destinatario SDI de fiskaly JKKZDGR como el destino SDI de tu empresa, de modo que el SDI enrute tus facturas entrantes a fiskaly.

La respuesta de la puesta en servicio muestra compliance.state como TRANSMISSION_ONLY. Luego pasa a TRANSMISSION_RECEPTION automáticamente una vez que se completa el registro del Taxpayer — lo cual normalmente ocurre, independientemente de si ha realizado el registro en la AdE o de si tiene previsto recibir.

Llama a retrieveSystem en cualquier momento para leer el compliance.state actual, que refleja únicamente la disponibilidad — no el registro en la AdE:

  • TRANSMISSION_RECEPTION — fiskaly ha configurado el System para recibir.
  • TRANSMISSION_ONLY — esa configuración no se ha completado.

No hay nada adicional que configurar para el enrutamiento: fiskaly asocia automáticamente cada factura entrante al Taxpayer correcto mediante su tax ID — razón por la cual cada tax ID debe pertenecer a un único Taxpayer registrado. No necesitas configurar ni almacenar un código de enrutamiento aparte.

Cuando se te envía una factura a través del SDI, fiskaly la recibe automáticamente:

  • la entrega entrante se procesa automáticamente por nuestra parte
  • se crea un Record de recepción para la factura
  • el XML firmado, el PDF y los metadatos se almacenan asociados al Record
  • las entregas duplicadas se deduplican

En la práctica, la primera factura que te llega de esta forma es también tu confirmación de que la recepción está configurada correctamente.

Cada factura dirigida a tu Taxpayer se recibe, valida y almacena automáticamente como Record — no existe ningún webhook, por lo que debes consultar la API para detectar las nuevas:

  1. Llama a listRecords y filtra por E_INVOICE::RECEPTION.
  2. Para cada Record nuevo, llama a retrieveRecord con compliance-artifact para obtener el XML firmado.

listRecords devuelve los Records más recientes (limit es 10 por defecto, del más reciente al más antiguo), así que lleve un registro de los que ya ha procesado.

La ley italiana exige que las facturas electrónicas se conserven a largo plazo mediante archivado digital certificado (conservazione a norma): deben conservarse durante al menos 10 años y almacenarse de modo que permanezcan inmutables, auténticas y fácilmente recuperables, con firmas digitales y sellos de tiempo (marca temporale). Conservar tu propia copia del XML no es suficiente — fiskaly se encarga de ello por ti.

Para Italia, el archivado es automático y siempre está activo: cada factura que envías y cada factura que recibes a través del SDI se conserva legalmente, sin configuración adicional ni llamada a la API por tu parte. Solo depende del tax ID italiano del Taxpayer, que ya forma parte del alta. Cada factura conservada obtiene un recibo de conservación como prueba de la conservazione a norma. La conservación se basa en eventos y suele completarse en segundos; el propio recibo puede tardar hasta unos seis minutos en emitirse, tras lo cual fiskaly lo adjunta automáticamente — no se requiere nada por tu parte.

Recupera los artefactos de una factura electrónica desde su Record con retrieveRecord, seleccionando el artefacto mediante un parámetro de consulta:

  • compliance-artifact — el documento legalmente vinculante. Para Italia, el XML FatturaPA validado por el SDI.
  • archive-artifact — el recibo de conservación que atestigua la conservación legal (conservazione a norma), devuelto como XML firmado.

Ambos artefactos tienen en cuenta la cabecera de petición Accept, que determina la forma de la respuesta:

AcceptQué obtienes
application/xmlEl artefacto en sí: el XML FatturaPA o el XML del recibo de conservación.
application/jsonEl Record en JSON, con el artefacto codificado en Base64 en el campo content habitual.

compliance-artifact y archive-artifact no existen durante toda la vida de un Record. Ninguno se produce al crear el Record: ambos se escriben una vez que la transmisión se completa, es decir, una vez que el SDI ha respondido, algo que la especificación del SDI permite que tarde hasta 48 horas. Ambos quedan fijados en el mismo momento, porque el paso de archivado se ejecuta antes de que cambie el estado del Record.

De ahí sale una regla basada únicamente en el estado, sin nada que cronometrar:

Estado del RecordQué indica sobre los artefactos
state: ACCEPTED, mode: PROCESSINGNo es terminal. Los artefactos pueden faltar todavía, y que falten significa aún no: siguen en camino.
state: COMPLETED / FAILED / REJECTED, mode: FINISHEDTerminal. Lo que haya es todo lo que va a haber; un artefacto ausente ya no aparecerá.

El recibo de conservación pertenece al Record E_INVOICE::TRANSMISSION y no a la TRANSACTION::INVOICE. Toma content.used_in.id del Record de la factura y, a continuación:

GET /records/{transmissionId}?archive-artifact

El recibo se devuelve codificado en Base64 en content.compliance.archive.data. Las facturas que envías y las que recibes tienen cada una su propio recibo. Mientras el artefacto no esté disponible, el campo está ausente de la respuesta en lugar de presente y vacío.

La legislación italiana exige un impuesto de timbre (imposta di bollo) de 2,00 € en las facturas cuyas líneas exentas de IVA superen en conjunto los 77,47 €. fiskaly lo aplica automáticamente: cuando el total de las líneas exentas de IVA correspondientes supera ese umbral, el impuesto de timbre se añade a la FatturaPA transmitida.

No existe ningún campo para el impuesto de timbre ni en la solicitud ni en la respuesta: no hay nada que establecer al crear la factura y no se devuelve nada en el Record. El único lugar donde aparece el valor aplicado es el elemento DatiBollo del XML FatturaPA, que puedes leer desde el documento transmitido:

GET /records/{transmissionId}?compliance-artifact

El XML llega codificado en Base64, así que descodifícalo antes de buscar DatiBollo.

Espera dos avisos de descuadre en los totales

Sección titulada «Espera dos avisos de descuadre en los totales»

Los 2,00 € se añaden después de calcular los totales de la factura, de modo que en toda factura que supera el umbral los totales transmitidos son 2,00 € más altos que los que enviaste. El Record registra esa diferencia como dos entradas WARNING en content.logs, por ejemplo:

provided '100.00000000', calculated '102.00'

Es lo esperado, y es la señal de que se aplicó el impuesto de timbre. Sigue enviando tus totales sin el impuesto: no existe ninguna carga útil que incluya el impuesto de timbre y a la vez evite los avisos. Trata estas dos entradas WARNING como informativas y no hagas fallar tu integración por ellas.

En Italia el tipo de documento es el identificador de tipo FatturaPA: una CORRECTION se transmite como TD04 (Nota di credito) y una INVOICE como TD01 (Fattura). Como el tipo se deriva de la operación, una factura que fiskaly no transmitió no puede abonarse: emitir una TD01 que referencie la factura anterior incrementa el importe adeudado en lugar de cancelarlo. Consulta Nota de crédito para la regla general.

Para casos puntuales, el SdI concede acceso al portal a todos los comerciantes, donde puede emitirse una nota de crédito manualmente. Esto no escala y no es un patrón de integración: trátalo como alternativa de migración y mantén disponible el sistema de facturación electrónica anterior hasta que todo lo emitido en él esté liquidado o abonado.