SDI (FatturaPA)
El SDI (Sistema di Interscambio) es la plataforma obligatoria de facturación electrónica de Italia, gestionada por la Agenzia delle Entrate. Todas las facturas entre operadores italianos —B2B, B2C y B2G— deben emitirse y recibirse a través del SDI en formato FatturaPA (el formato XML estructurado nacional italiano).
La API REST de B2Brouter se encarga de generar el XML FatturaPA, transmitirlo al SDI y recuperar los acuses de recibo, de modo que tu integración puede centrarse en la lógica de negocio.
¿Qué es el SDI?
Sección titulada «¿Qué es el SDI?»El SDI es el punto de acceso central por el que pasan todas las facturas electrónicas italianas. En la práctica:
- Las facturas se emiten en formato FatturaPA 1.2 (
xml.fatturapa.1.2), un XML propio italiano. - El SDI valida el documento contra el esquema oficial (XSD) y lo hace llegar al destinatario.
- Cada factura aceptada recibe un identificador de registro (IdentificativoSdI).
- Si el destinatario no puede recibir el documento electrónicamente, el SDI lo deposita en su cassetto fiscale.
La obligatoriedad aplica a todas las empresas italianas desde enero de 2019.
Identificación del destinatario
Sección titulada «Identificación del destinatario»Para encaminar una factura, el SDI necesita saber dónde entregarla. Hay varias vías, y es importante no confundirlas:
| Concepto | Campo en B2Brouter | Qué es |
|---|---|---|
| Codice Destinatario | recipient_code | Código de encaminamiento asignado por el SDI al destinatario. 7 caracteres para empresas privadas, 6 para administraciones públicas (Codice Ufficio). |
| PEC (Posta Elettronica Certificata) | certified_email | Correo electrónico certificado, alternativa al Codice Destinatario cuando el destinatario no tiene. |
| Codice Fiscale / Partita IVA | cin_value / tin_value | Identificación fiscal del destinatario (no es un código de encaminamiento). |
| CUP / CIG | file_reference (CUP) / lot_reference (CIG) | Códigos de proyecto y licitación obligatorios en ciertas operaciones con la Administración; no sirven para encaminar. |
Para recibir facturas en B2Brouter a través del SDI, tu proveedor debe indicar el Codice Destinatario de B2Brouter: EPKDZJB (previo registro de tu empresa en la Agenzia delle Entrate).
B2B, B2C y B2G
Sección titulada «B2B, B2C y B2G»El flujo técnico es el mismo en los tres casos; lo que cambia es la identificación del destinatario:
- B2B (empresa): identificada por la Partita IVA (
tin_scheme: 9906). Elrecipient_codetiene 7 caracteres (o0000000si el cliente no tiene). - B2C (consumidor particular): identificado por el Codice Fiscale (
cin_scheme: 9907). Normalmente no tiene Codice Destinatario, así que se usa0000000y el SDI deposita la factura en el cassetto fiscale del ciudadano. En facturas exentas puede aplicarse el bollo. - B2G (Administración pública): se identifica con el Codice Ufficio de 6 caracteres. Marca el contacto como
public_sector: truee informa el código de 6 caracteres enrecipient_code. Con la Administración suele aplicarse el split payment (consulta Esigibilità IVA y split payment).
B2Brouter valida la longitud del código (7 privado / 6 Administración) en el momento del envío.
Antes de empezar
Sección titulada «Antes de empezar»- Una empresa italiana con una Partita IVA válida y dirección completa (se validan al enviar, no al crear la cuenta).
- Una cuenta en el entorno de pruebas de B2Brouter: Regístrate aquí.
- Permisos de API (solicítalos abriendo un ticket de soporte).
Empieza con el sandbox para las primeras pruebas de payload. Pasa a staging (
api-staging.b2brouter.net) cuando quieras probar el envío completo al SDI de pruebas.
Activar el SDI
Sección titulada «Activar el SDI»Para que una cuenta pueda emitir al SDI, hay que darla de alta con un tax report setting de la autoridad sdi. Consulta la Tax Report Settings Guide para el detalle general.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_report_settings \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/json' \ --data '{ "tax_report_setting": { "code": "sdi" } }'Respuesta:
{ "tax_report_setting": { "code": "sdi", "start_date": null, "auto_generate": true, "auto_send": true, "enabled": true, "locked": false }}Al crearlo, B2Brouter activa por defecto enabled, auto_generate y auto_send, de modo que las facturas FatturaPA se generan y se envían automáticamente al SDI.
Crear la empresa italiana
Sección titulada «Crear la empresa italiana»curl --request POST \ --url https://api-staging.b2brouter.net/accounts \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{ "account": { "country": "it", "rounding_method": "half_up", "tin_value": "20339260422", "tin_scheme": 211, "name": "Test Sender Italy", "address": "Milano street, 1", "city": "Milano", "postalcode": "20019", "province": "MI", "email": "john.doe@example.com", "tax_regime": "RF01" } }'El campo tax_regime indica el régimen fiscal del emisor (consulta Regime fiscale); si no se informa, se aplica RF01 (ordinario).
Crear el contacto de cliente
Sección titulada «Crear el contacto de cliente»Al crear un cliente italiano:
- Usa
tin_valuepara la Partita IVA contin_scheme: 9906. - Usa
cin_valuepara el Codice Fiscale concin_scheme: 9907(lista de esquemas). Basta con uno de los dos identificadores. - La dirección y el código postal del contacto son obligatorios para enviar al SDI.
transport_type_codedebe serit.sdi.document_type_codedebe serxml.fatturapa.1.2.- Si el contacto tiene Codice Destinatario, infórmalo en
recipient_code(7 car. privado / 6 Administración). Si no tiene, se usa0000000. Opcionalmente, informa la PEC del comprador encertified_email.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/contacts \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{ "contact": { "tin_scheme": "9906", "tin_value": "IT12345678901", "name": "Esempio S.r.l.", "address": "Via Inventata 88", "postalcode": "00184", "city": "Roma", "province": "RM", "country": "it", "transport_type_code": "it.sdi", "document_type_code": "xml.fatturapa.1.2", "recipient_code": "{CODICE_DESTINATARIO}" } }'Crear y enviar una factura
Sección titulada «Crear y enviar una factura»curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/json' \ --data '{ "send_after_import": true, "invoice": { "type": "IssuedInvoice", "invoice_lines_attributes": [ { "quantity": 10, "price": 47, "description": "Test Item", "taxes_attributes": [ { "name": "IVA", "percent": 22 } ] } ], "number": "1", "date": "2025-01-22", "due_date": "2025-02-22", "contact_id": {YOUR_CONTACT_ID} } }'Notas:
- El número de factura puede tener como máximo 20 caracteres.
- Cada línea debe tener descripción y al menos un impuesto.
due_datees opcional para el transporteit.sdi.
Campos adicionales para facturas italianas
Sección titulada «Campos adicionales para facturas italianas»type_document(en la factura): fija elTipoDocumentode FatturaPA. Opcional; si no lo informas, B2Brouter lo asigna automáticamente. Consulta Tipo de documento.receipt_reference(en cada línea, no en la factura): referencia a un recibo/scontrino asociado a la línea, con los camposidentifier,numberydate. Opcional, solo FatturaPA:
"invoice_lines_attributes": [ { "quantity": 1, "price": 47, "description": "Test Item", "taxes_attributes": [{ "name": "IVA", "percent": 22 }], "receipt_reference": { "identifier": "SCONTRINO-001", "number": "42", "date": "2025-01-20" } }]Tipo de documento (TipoDocumento)
Sección titulada «Tipo de documento (TipoDocumento)»El TipoDocumento (type_document) clasifica la factura (fattura, nota di credito, autofattura…). B2Brouter lo asigna automáticamente según el tipo y el contenido de la factura, pero puedes forzarlo con un código válido (TD01–TD06, TD16–TD27).
Comportamiento:
- Si no informas
type_document, se asigna solo:TD01por defecto,TD04para abonos/rectificativas,TD16cuando hay impuestos con NaturaN6, yTD17/TD18/TD19para autofacturas (consulta Autofattura). - Si lo informas con un código válido, se emite tal cual. Si el valor no es válido, se ignora y se aplica la asignación automática (no se genera ningún error).
Para ver cómo se corresponde cada campo del JSON con los nodos del XML FatturaPA, usa el mapeador de campos de factura.
Natura IVA (operaciones sin IVA)
Sección titulada «Natura IVA (operaciones sin IVA)»Cuando una operación no lleva IVA (exenta, no imponible, reverse charge…), FatturaPA no usa un porcentaje sino un código Natura (N1–N7). En B2Brouter se informa en category dentro de taxes_attributes, con percent: 0:
"taxes_attributes": [ { "name": "IVA", "percent": 0, "category": "N2.1" }]| Código | Significado |
|---|---|
N1 | Excluidas ex art. 15 |
N2.1 / N2.2 | No sujetas (art. 7-bis y otras) |
N3.1–N3.6 | No imponibles (exportación, intracomunitaria, San Marino…) |
N4 | Exentas |
N5 | Régimen del margen / IVA no expuesta |
N6.1–N6.9 | Inversión del sujeto pasivo (reverse charge) — consulta Autofattura |
N7 | IVA exigible en otro estado de la UE |
B2Brouter completa automáticamente el motivo asociado a cada código Natura; solo hay que informar la category.
Regime fiscale
Sección titulada «Regime fiscale»El régimen fiscal del emisor se informa en el campo tax_regime de la cuenta (empresa). Por defecto es RF01 (ordinario). Valores admitidos:
| Código | Régimen | Código | Régimen | |
|---|---|---|---|---|
RF01 | Ordinario | RF12 | Agriturismo | |
RF02 | Contribuenti minimi | RF13 | Vendite a domicilio | |
RF04 | Agricoltura e pesca | RF14 | Rivendita beni usati / oggetti d’arte | |
RF05 | Vendita sali e tabacchi | RF15 | Agenzie di vendite all’asta | |
RF06 | Commercio fiammiferi | RF16 | IVA per cassa P.A. | |
RF07 | Editoria | RF17 | IVA per cassa | |
RF08 | Servizi telefonia pubblica | RF18 | Altro | |
RF09 | Documenti di trasporto/sosta | RF19 | Regime forfettario | |
RF10 | Intrattenimenti e giochi | |||
RF11 | Agenzie viaggi e turismo |
Modalità di pagamento
Sección titulada «Modalità di pagamento»La forma de pago se establece con el campo payment_method (en el contacto o en la factura) y B2Brouter la traduce al código FatturaPA ModalitaPagamento (MPxx). Consulta la Payment Method Guide para los valores de payment_method.
Correspondencias más habituales:
MP FatturaPA | Forma de pago |
|---|---|
MP01 | Efectivo (contanti) |
MP02 | Cheque (assegno) |
MP05 | Transferencia bancaria (bonifico) |
MP06 | Pagaré (vaglia cambiario) |
MP08 | Tarjeta de crédito/débito |
Esigibilità IVA y split payment
Sección titulada «Esigibilità IVA y split payment»La esigibilità indica cuándo es exigible el IVA. Se informa en el campo vat_payability del contacto (por defecto I):
| Valor | Significado |
|---|---|
I | Inmediata (por defecto) |
D | Diferida (esigibilità differita) |
S | Split payment (scissione dei pagamenti) |
El valor S (split payment) se aplica típicamente en facturas a la Administración: el comprador ingresa el IVA directamente a la Hacienda, de modo que B2Brouter lo descuenta del importe a pagar (el subtotal y el IVA se muestran, pero el payable_amount no incluye el IVA).
Ritenuta d’acconto
Sección titulada «Ritenuta d’acconto»Para los profesionales sujetos a retención (ritenuta d’acconto), informa en la factura amounts_withheld_reason (la causal de pago) y el importe retenido. B2Brouter descuenta el importe del importe a pagar y genera el bloque DatiRitenuta en el XML.
Tienes dos maneras de indicar el importe:
amounts_withheld: el importe exacto a retener. Recomendado cuando la base de la retención no es el total (por ejemplo, solo la base imponible).withheld_percent: un porcentaje que B2Brouter aplica sobre el total de la factura (IVA incluido). Atención: si esperas la retención sobre la base imponible, usaamounts_withheld.
{ "invoice": { "type": "IssuedInvoice", "withheld_percent": 20, "amounts_withheld_reason": "A", "...": "..." }}Con el ejemplo anterior sobre una base con IVA, la respuesta devuelve el amounts_withheld calculado y el payable_amount reducido en ese importe.
El bollo (imposta di bollo) es un sello de 2,00 € obligatorio en facturas sin IVA de importe superior a 77,47 €.
B2Brouter lo aplica automáticamente cuando se cumplen todas estas condiciones:
- La empresa tiene activada la opción de bollo (
apply_stamp_duty), que se configura en la empresa (no por esta API). - El emisor es italiano y el total supera los 77,47 €.
- Hay al menos un impuesto con una Natura de exención aplicable:
N2.1,N2.2,N3.5,N3.6oN4. - El documento no es de integración/autofattura (
TD16–TD19).
Cuando aplica, el XML incluye <DatiBollo> con BolloVirtuale: SI e ImportoBollo: 2.00. También puedes añadirlo manualmente como una línea con descripción «bollo», precio 2 e impuesto N1 al 0 %.
Facturas rectificativas
Sección titulada «Facturas rectificativas»Para rectificar una factura ya emitida:
- Nota di credito (abono): crea la factura con
is_credit_note: true. B2Brouter asignaTD04automáticamente. - Nota di debito (cargo adicional): informa
type_document: "TD05".
Para vincular la factura original (para que el SDI relacione los documentos), añade una referencia con invoice_references de tipo amend, o informa amended_invoice_number y amended_invoice_date.
Recepción de facturas
Sección titulada «Recepción de facturas»Las facturas de tus proveedores pueden entrar en B2Brouter por diferentes canales de recepción:
- SDI: registra el Codice Destinatario de B2Brouter (
EPKDZJB) en la Agenzia delle Entrate; los proveedores italianos emiten hacia este código. - Peppol o correo electrónico: activa el transporte de recepción correspondiente en la cuenta para recibir proveedores internacionales que emiten por esas vías.
Sea cual sea el canal, la factura entra como factura recibida (ReceivedInvoice). Las consultas: GET /accounts/{id}/received_invoices (listar) y GET /received_invoices/{id} (obtener).
Cuando el proveedor no ha pasado por el SDI (típicamente un proveedor extranjero), la compra debe declararse al SDI como autofattura. Si tienes un transporte de recepción activo, B2Brouter lo hace automáticamente al llegar la factura; si las recibes en otro software, las registras tú (vía API) y se integran igual. Consulta la sección siguiente.
Autofattura y reverse charge
Sección titulada «Autofattura y reverse charge»Cuando compras a un proveedor extranjero (o en operaciones de reverse charge interno), la normativa italiana obliga a autofacturarte: declarar la operación al SDI en tu nombre.
En B2Brouter, la autofattura no se crea como un documento aparte: se genera automáticamente a partir de la factura recibida. El flujo es:
- Asegúrate de que la cuenta tiene el SDI activado (con
auto_generate, que es el valor por defecto). - Consigue la factura del proveedor en la cuenta como factura recibida: si tienes un transporte de recepción (Peppol/correo) activo, entra sola; si la recibes en otro software, regístrala vía API con
POST /accounts/{id}/invoicesytype: "ReceivedInvoice". Indica eltype_operation(servicesogoods) y la Natura del IVA que corresponda (p. ej.N6.xpara reverse charge); el proveedor va dentro del objetocontact. - Al crearla, B2Brouter genera automáticamente un tax report de integración (la autofattura), lo exporta en formato FatturaPA y, si el SDI tiene
auto_send, lo envía. Puedes consultarlo con el endpoint de tax reports.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/json' \ --data '{ "invoice": { "type": "ReceivedInvoice", "number": "RIC-001", "date": "2026-07-22", "type_operation": "services", "contact": { "tin_scheme": "9930", "tin_value": "DE137869841", "name": "Fornitore Estero GmbH", "address": "Berlin str 1", "postalcode": "10115", "city": "Berlin", "country": "de" }, "invoice_lines_attributes": [ { "quantity": 1, "price": 500, "description": "Consulenza estera", "taxes_attributes": [{ "name": "IVA", "percent": 0, "category": "N6.9" }] } ] } }'El TipoDocumento de la integración se calcula automáticamente:
| Situación | Código |
|---|---|
Reverse charge interno (impuestos con Natura N6) | TD16 |
| Compra de servicios a un proveedor no residente | TD17 |
| Compra de bienes intracomunitaria | TD18 |
| Compra de bienes a un proveedor extra-UE | TD19 |
B2Brouter rellena automáticamente el bloque DatiFattureCollegate (referencia a la factura recibida) y marca el documento como autofattura (SoggettoEmittente: CC).
Fattura Semplificata
Sección titulada «Fattura Semplificata»La Fattura Elettronica Semplificata (art. 21-bis del DPR 633/72) es un formato XML reducido para operaciones de bajo importe: el total no puede superar los 400 €. Es legalmente equivalente a una factura ordinaria, pero utiliza una estructura propia (FatturaElettronicaSemplificata, versión FSM10) con menos campos obligatorios —por ejemplo, no exporta datos de pago—. Como cualquier factura italiana, debe presentarse al SDI.
En B2Brouter se crea como una IssuedInvoice con el tipo de documento xml.fattura.semplificata.1.0.2 (en la factura o en el contacto).
Reglas de validación
Sección titulada «Reglas de validación»| Requisito | Valor |
|---|---|
| Total máximo de la factura | 400 € |
| Identificador fiscal del comprador | Codice Fiscale o Partita IVA (obligatorio uno de los dos) |
| Dirección y código postal del comprador | Obligatorios |
| IVA por línea | Exactamente un impuesto por línea |
| Descuentos o cargos globales | No permitidos (usa descuentos a nivel de línea) |
Crear una factura simplificada
Sección titulada «Crear una factura simplificada»curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'content-type: application/json' \ --data '{ "send_after_import": true, "invoice": { "type": "IssuedInvoice", "document_type_code": "xml.fattura.semplificata.1.0.2", "number": "S-2025-001", "date": "2025-09-10", "contact_id": 123456789, "invoice_lines_attributes": [ { "quantity": 2, "price": 50.00, "description": "Servizi di consulenza", "taxes_attributes": [{ "name": "IVA", "percent": 22 }] } ] } }'Tipo de documento (TipoDocumento)
Sección titulada «Tipo de documento (TipoDocumento)»Para el formato simplificado, B2Brouter asigna el TipoDocumento automáticamente; no informes type_document:
TD07— Fattura Semplificata (por defecto).TD08— Nota di Credito Semplificata (cuandois_credit_note: trueo una rectificativa).
Si informas un código válido de la FatturaPA ordinaria (TD01–TD06, TD16–TD27), se emitirá tal cual dentro del XML simplificado y el SDI lo rechazará (error XSD), porque el formato simplificado solo admite TD07, TD08 y TD09. TD09 (Nota di Debito Semplificata) no está soportado actualmente.
Comprobar el estado de la factura
Sección titulada «Comprobar el estado de la factura»Con send_after_import: true, la factura se envía al SDI por el transporte it.sdi y pasa por sending → sent. Si el SDI (o el destinatario) la rechaza, pasa a error con el motivo. Cuando el SDI devuelve el identificador de registro (IdentificativoSdI), queda disponible en to_net_id.
Opción 1: consultar una factura
Sección titulada «Opción 1: consultar una factura»curl --request GET \ --url 'https://api-staging.b2brouter.net/invoices/{INVOICE_ID}?include=lines' \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'Opción 2: consultar varias facturas
Sección titulada «Opción 2: consultar varias facturas»curl --request GET \ --url 'https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices?offset=0&limit=25' \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'Cuando la factura llegue a su estado final, márcala como reconocida para quitarla de la lista activa:
curl --request POST \ --url https://api-staging.b2brouter.net/invoices/{INVOICE_ID}/ack \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'accept: application/json'Recursos adicionales
Sección titulada «Recursos adicionales»B2Brouter
Documentación oficial (Agenzia delle Entrate)