Ir al contenido
Log in

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.

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.

Para encaminar una factura, el SDI necesita saber dónde entregarla. Hay varias vías, y es importante no confundirlas:

ConceptoCampo en B2BrouterQué es
Codice Destinatariorecipient_codeCó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_emailCorreo electrónico certificado, alternativa al Codice Destinatario cuando el destinatario no tiene.
Codice Fiscale / Partita IVAcin_value / tin_valueIdentificación fiscal del destinatario (no es un código de encaminamiento).
CUP / CIGfile_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).

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). El recipient_code tiene 7 caracteres (o 0000000 si el cliente no tiene).
  • B2C (consumidor particular): identificado por el Codice Fiscale (cin_scheme: 9907). Normalmente no tiene Codice Destinatario, así que se usa 0000000 y 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: true e informa el código de 6 caracteres en recipient_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.

  • 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.

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.

Ventana de terminal
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.

Ventana de terminal
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).

Al crear un cliente italiano:

  • Usa tin_value para la Partita IVA con tin_scheme: 9906.
  • Usa cin_value para el Codice Fiscale con cin_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_code debe ser it.sdi.
  • document_type_code debe ser xml.fatturapa.1.2.
  • Si el contacto tiene Codice Destinatario, infórmalo en recipient_code (7 car. privado / 6 Administración). Si no tiene, se usa 0000000. Opcionalmente, informa la PEC del comprador en certified_email.
Ventana de terminal
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}"
}
}'
Ventana de terminal
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_date es opcional para el transporte it.sdi.
  • type_document (en la factura): fija el TipoDocumento de 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 campos identifier, number y date. 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"
}
}
]

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 (TD01TD06, TD16TD27).

Comportamiento:

  • Si no informas type_document, se asigna solo: TD01 por defecto, TD04 para abonos/rectificativas, TD16 cuando hay impuestos con Natura N6, y TD17/TD18/TD19 para 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.

Cuando una operación no lleva IVA (exenta, no imponible, reverse charge…), FatturaPA no usa un porcentaje sino un código Natura (N1N7). En B2Brouter se informa en category dentro de taxes_attributes, con percent: 0:

"taxes_attributes": [
{ "name": "IVA", "percent": 0, "category": "N2.1" }
]
CódigoSignificado
N1Excluidas ex art. 15
N2.1 / N2.2No sujetas (art. 7-bis y otras)
N3.1N3.6No imponibles (exportación, intracomunitaria, San Marino…)
N4Exentas
N5Régimen del margen / IVA no expuesta
N6.1N6.9Inversión del sujeto pasivo (reverse charge) — consulta Autofattura
N7IVA 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.

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ódigoRégimenCódigoRégimen
RF01OrdinarioRF12Agriturismo
RF02Contribuenti minimiRF13Vendite a domicilio
RF04Agricoltura e pescaRF14Rivendita beni usati / oggetti d’arte
RF05Vendita sali e tabacchiRF15Agenzie di vendite all’asta
RF06Commercio fiammiferiRF16IVA per cassa P.A.
RF07EditoriaRF17IVA per cassa
RF08Servizi telefonia pubblicaRF18Altro
RF09Documenti di trasporto/sostaRF19Regime forfettario
RF10Intrattenimenti e giochi
RF11Agenzie viaggi e turismo

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 FatturaPAForma de pago
MP01Efectivo (contanti)
MP02Cheque (assegno)
MP05Transferencia bancaria (bonifico)
MP06Pagaré (vaglia cambiario)
MP08Tarjeta de crédito/débito

La esigibilità indica cuándo es exigible el IVA. Se informa en el campo vat_payability del contacto (por defecto I):

ValorSignificado
IInmediata (por defecto)
DDiferida (esigibilità differita)
SSplit 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).

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, usa amounts_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.6 o N4.
  • El documento no es de integración/autofattura (TD16TD19).

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 %.

Para rectificar una factura ya emitida:

  • Nota di credito (abono): crea la factura con is_credit_note: true. B2Brouter asigna TD04 automá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.

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.

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:

  1. Asegúrate de que la cuenta tiene el SDI activado (con auto_generate, que es el valor por defecto).
  2. 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}/invoices y type: "ReceivedInvoice". Indica el type_operation (services o goods) y la Natura del IVA que corresponda (p. ej. N6.x para reverse charge); el proveedor va dentro del objeto contact.
  3. 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.
Ventana de terminal
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ónCódigo
Reverse charge interno (impuestos con Natura N6)TD16
Compra de servicios a un proveedor no residenteTD17
Compra de bienes intracomunitariaTD18
Compra de bienes a un proveedor extra-UETD19

B2Brouter rellena automáticamente el bloque DatiFattureCollegate (referencia a la factura recibida) y marca el documento como autofattura (SoggettoEmittente: CC).

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).

RequisitoValor
Total máximo de la factura400 €
Identificador fiscal del compradorCodice Fiscale o Partita IVA (obligatorio uno de los dos)
Dirección y código postal del compradorObligatorios
IVA por líneaExactamente un impuesto por línea
Descuentos o cargos globalesNo permitidos (usa descuentos a nivel de línea)
Ventana de terminal
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 }]
}
]
}
}'

Para el formato simplificado, B2Brouter asigna el TipoDocumento automáticamente; no informes type_document:

  • TD07 — Fattura Semplificata (por defecto).
  • TD08 — Nota di Credito Semplificata (cuando is_credit_note: true o una rectificativa).

Si informas un código válido de la FatturaPA ordinaria (TD01TD06, TD16TD27), 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.

Con send_after_import: true, la factura se envía al SDI por el transporte it.sdi y pasa por sendingsent. 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.

Ventana de terminal
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'
Ventana de terminal
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:

Ventana de terminal
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'

B2Brouter

Documentación oficial (Agenzia delle Entrate)