KSeF
El KSeF (Krajowy System e-Faktur - Sistema Nacional de Facturación Electrónica) es el sistema de facturación electrónica obligatorio de Polonia, gestionado por el Ministerio de Hacienda polaco. KSeF garantiza la integridad y autenticidad de las facturas mediante la presentación en formato XML estructurado y la certificación digital.
Estas regulaciones exigen que las empresas que operan en Polonia adopten sistemas capaces de generar, validar y transmitir facturas de forma segura a la plataforma KSeF. La API REST de B2Brouter proporciona una solución técnica que permite a tu empresa cumplir con el KSeF, delegando las complejidades en B2Brouter y permitiéndote centrarte en la lógica de tu negocio.
¿Qué es KSeF?
Sección titulada «¿Qué es KSeF?»KSeF es la plataforma centralizada de facturación electrónica de Polonia que se ha convertido en obligatoria para los contribuyentes del IVA. Garantiza que todas las facturas sean:
- Validadas contra esquemas XML oficiales (estructura FA)
- Certificadas digitalmente mediante certificados cualificados
- Almacenadas de forma segura por la autoridad fiscal polaca
- Verificables a través de un recibo oficial (UPO - Urzędowe Poświadczenie Odbioru)
En la práctica, KSeF requiere:
- Crear un archivo XML de factura estructurado conforme al esquema FA variante 3 - FA(3)
- Autenticarse en la plataforma KSeF mediante un certificado electrónico cualificado vinculado a tu NIP polaco
- Presentar la factura a KSeF para su validación y registro
- Recibir y almacenar el UPO (Recibo Oficial) como prueba de registro
- Incluir el código QR con el número de referencia KSeF en las facturas emitidas
Con B2Brouter puedes abstraer gran parte de las complejidades de este proceso y cumplir con el KSeF. Necesitarás proporcionar tu certificado electrónico cualificado (formato PKCS#12), y B2Brouter se encargará de la autenticación, la presentación y la recuperación del UPO.
B2Brouter genera informes fiscales usando el formato FA(3) (variante de formulario 3, versión de esquema 1-0E), que es el estándar actual para las presentaciones al KSeF.
Configurar KSeF con la API de B2Brouter
Sección titulada «Configurar KSeF con la API de B2Brouter»El primer paso es configurar KSeF para cada cuenta (identificada por el NIP polaco) para la que quieras presentar informes fiscales. Puedes consultar la Guía de Tax Report Settings para una descripción completa del proceso.
Entornos de B2Brouter e integración con KSeF
Sección titulada «Entornos de B2Brouter e integración con KSeF»Empieza con el sandbox para las pruebas iniciales de la API y la validación de payloads — las presentaciones al KSeF se simulan en sandbox, por lo que no se requiere certificado KSeF. Cambia al entorno de staging cuando estés listo para probar con un certificado KSeF real contra el entorno de pruebas o demo de KSeF.
B2Brouter se conecta a diferentes entornos de KSeF según tu configuración:
| Entorno B2Brouter | Entornos KSeF disponibles | Requisitos de certificado |
|---|---|---|
API de producciónapi.b2brouter.net | Solo KSeF producción | Certificado KSeF de producción |
API de stagingapi-staging.b2brouter.net | KSeF Test (por defecto) KSeF Demo (configurable) | Test: Certificado KSeF de prueba o autofirmado Demo: Certificado KSeF de preproducción |
Para desarrollo y pruebas:
- Usa la API de Staging (
api-staging.b2brouter.net) - Por defecto, se conecta al entorno de pruebas de KSeF
- Acepta certificados KSeF de prueba (recomendado)
- También acepta certificados autofirmados para desarrollo rápido y pruebas de integración
- Opcionalmente puedes configurar el entorno demo estableciendo
environment: "demo"al crear el tax report setting- Requiere un certificado KSeF de preproducción
- Para producción, solo funcionarán los certificados KSeF de producción
Requisitos de certificado
Sección titulada «Requisitos de certificado»La autenticación ante KSeF usa certificados digitales en formato PKCS#12 (.p12 o .pfx). El tipo de certificado requerido depende del entorno de KSeF:
Para el entorno de producción:
- Certificado KSeF de producción
- El cliente debe iniciar sesión usando su firma cualificada o perfil de confianza (Profil Zaufany)
- Acceder a la sección KSeF y generar un certificado KSeF dedicado vinculado a su NIP
- El sujeto del certificado debe coincidir con tu NIP polaco o estar autorizado mediante ZAW-FA
- Contraseña/PIN del certificado
Para el entorno demo (preproducción):
- Certificado KSeF de preproducción
- El certificado debe estar en formato PKCS#12 (.p12 o .pfx)
- El sujeto del certificado debe coincidir con tu NIP polaco o estar autorizado mediante ZAW-FA
- Contraseña/PIN del certificado
Para el entorno de pruebas (desarrollo):
- Certificado KSeF de prueba (recomendado) o certificado autofirmado (solo para desarrollo)
- El certificado debe estar en formato PKCS#12 (.p12 o .pfx)
- Para certificados autofirmados: el número de serie del certificado debe coincidir con el número de IVA (NIP)
- Contraseña/PIN del certificado
Ejemplo: Codificar tu certificado
# Encode your certificate to base64 without line breaksbase64 -w 0 your-certificate.p12 > certificate-base64.txtCrear el Tax Report Setting para KSeF
Sección titulada «Crear el Tax Report Setting para KSeF»Necesitas configurar la integración con KSeF para cada empresa para la que quieras presentar facturas estructuradas. Esta configuración define cómo B2Brouter gestiona la generación y presentación de facturas al KSeF en nombre de tu sistema. Debes configurar estos ajustes por empresa antes de presentar cualquier factura.
- Este paso de configuración incorporará al cliente al KSeF y realizará una prueba de conexión.
- Si el certificado o la configuración no son válidos, el endpoint devolverá un error.
Ejemplo de solicitud:
curl --request GET \ --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": "ksef", "type_operation": "services", "credit_note_code": "1", "certificate": "MIIKZAIBAzCCCh4GCSqGSIb3DQEHAaCCCg8Egg...", "certificate_pin": "YourCertificatePassword", "auto_generate": true, "auto_send": true, "enabled": true } }'Parámetros:
code: Debe ser “ksef”type_operation: Tipo de operación predeterminado (“services” o “goods”)credit_note_code: Código de efecto de corrección predeterminado (“1”, “2” o “3”)certificate: Tu certificado PKCS#12 codificado en base64certificate_pin: Contraseña del certificadoauto_generate: Generar automáticamente informes fiscales para las facturasauto_send: Enviar automáticamente los informes fiscales al KSeF
Trabajar con los informes fiscales KSeF
Sección titulada «Trabajar con los informes fiscales KSeF»B2Brouter ofrece dos formas de trabajar con KSeF:
- API de informes fiscales: Para control directo sobre la creación y presentación de informes fiscales (RECOMENDADO).
- API de facturas: Si usas B2Brouter para emitir facturas, los informes fiscales se generan automáticamente.
API de informes fiscales
Sección titulada «API de informes fiscales»La API de informes fiscales te ofrece el máximo control sobre el proceso de presentación al KSeF. Puedes crear informes fiscales proporcionando datos JSON estructurados que B2Brouter convertirá al formato XML FA(3).
La estructura del formato JSON para los informes fiscales de B2Brouter se basa en PEPPOL Continuous Transaction Control (CTC). Esto significa que la API de informes fiscales de B2Brouter es una API universal no solo orientada al KSeF sino diseñada para gestionar el reporte fiscal en todo el mundo.
Importante: Los informes fiscales para KSeF usan tax_report_lines y tax_breakdowns. Cada tax_report_line representa una línea de artículo de factura con su propia cantidad, posición, unit_code, precio e información fiscal.
Crear un informe fiscal
Sección titulada «Crear un informe fiscal»Para crear un informe fiscal de KSeF, llama al endpoint crear informe fiscal.
Ejemplo: Factura básica con IVA
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/001", "description": "Consulting services", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting hours", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Ejemplo: Factura correctiva (KOR)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "KOR", "amend_type": "2", "invoice_date": "2025-11-08", "tax_point_date": "2025-11-07", "invoice_number": "FK/2025/11/001", "description": "Correction of invoice F/2025/11/001", "amended_ksef_number": "1234567890-20251107-ABCD1234-EF", "amended_date": "2025-11-07", "amended_number": "F/2025/11/001", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting hours", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00, "ksef_amended": true }, { "position": 1, "quantity": 10, "unit_code": "PCE", "description": "Consulting hours - new line", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Ejemplo: Factura con IVA exenta — Exportación de bienes (moneda extranjera)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/003", "description": "Sample Exempt VAT Invoice - Export of Goods", "customer_party_name": "EFG Ltd.", "customer_party_tax_id": "1234567890", "customer_party_address": "Flower (St) 1, Seattle, WA 99999", "customer_party_country": "us", "currency": "USD", "exchange_rate": 3.65, "tax_inclusive_amount": 8000, "tax_amount": 0, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 20, "unit_code": "szt.", "description": "lodówka Zimnotech mk1", "price": 400, "tax_code": "0 EX", "tax_exclusive_amount": 8000, "tax_amount": 0, "tax_inclusive_amount": 8000 } ], "tax_breakdowns": [ { "name": "PTU", "category": "E", "percent": 0.0, "taxable_base": 8000, "tax_amount": 0, "comment": "reason why exempt" } ] } }'Ejemplo: Factura con IVA (pago completo recibido en el momento de la emisión) - Zaplacono
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "payment_date": "2025-11-07", "payable_amount": 0, "invoice_number": "F/2025/11/004", "description": "Sample VAT Invoice (full payment has been received at the time of issue)", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "product 1", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Ejemplo: Factura ZAL (pago anticipado)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "ZAL", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "payment_date": "2025-11-07", "payable_amount": 0, "invoice_number": "F/2025/11/005", "description": "Sample ZAL Invoice (full payment has been received at the time of issue)", "customer_party_name": "Example Company Sp. z o.o.", "customer_party_tax_scheme": "9945", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "product 1", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'Ejemplo: Factura ROZ (liquidación de pagos anticipados)
Una factura ROZ liquida el importe restante tras todos los anticipos. Referencia las facturas ZAL previas mediante prepayment_references. Cada referencia corresponde a un elemento FakturaZaliczkowa en el XML FA(3).
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "ROZ", "invoice_date": "2026-08-17", "tax_point_date": "2026-09-17", "invoice_number": "FV2026/08/12", "description": "Settlement invoice", "customer_party_name": "Jan Kowalski", "customer_party_tax_id": "1234567890", "customer_party_address": "ul. Przykładowa 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 306899.80, "tax_amount": 22720.76, "type_operation": "goods", "prepayment_references": [ { "registration_code": "9999999999-20260215-8BEF280C8D35-4D" }, { "number": "FZ2026/03/200" } ], "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "C62", "description": "mieszkanie 50m^2", "price": 280177.59, "tax_code": "8", "tax_exclusive_amount": 280177.59, "tax_amount": 22414.21, "tax_inclusive_amount": 302591.80 }, { "position": 2, "quantity": 1, "unit_code": "C62", "description": "usługi dodatkowe", "price": 4001.55, "tax_code": "23", "tax_exclusive_amount": 4001.55, "tax_amount": 306.55, "tax_inclusive_amount": 4308.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 8.0, "taxable_base": 280177.59, "tax_amount": 22414.21 }, { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 4001.55, "tax_amount": 306.55 } ] } }'prepayment_references— usaregistration_codepara el número KSeF (NrKSeFFaZaliczkowej) onumberpara el número de factura (NrFaZaliczkowej) cuando el ZAL fue emitido fuera del KSeF.
Ejemplo: Factura KOR_ZAL (corrección de pago anticipado)
Una KOR_ZAL corrige una factura ZAL emitida previamente. Usa previous_advance_total para indicar el importe del anticipo original (P_15ZK en el XML FA(3)).
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "KOR_ZAL", "amend_type": "1", "invoice_date": "2026-03-17", "tax_point_date": "2026-02-15", "invoice_number": "FK2026/03/7", "description": "Correction of advance invoice FZ2026/02/150", "amended_ksef_number": "9999999999-20260215-8BEF280C8D35-4D", "amended_date": "2026-02-15", "amended_number": "FZ2026/02/150", "customer_party_name": "Jan Kowalski", "customer_party_tax_id": "1234567890", "customer_party_address": "ul. Przykładowa 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 25000.00, "tax_amount": 4674.80, "previous_advance_total": 20000.00, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "C62", "description": "mieszkanie 50m^2", "price": 300000, "tax_code": "23", "tax_exclusive_amount": 20325.20, "tax_amount": 4674.80, "tax_inclusive_amount": 25000.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 20325.20, "tax_amount": 4674.80 } ] } }'previous_advance_total: 20000.00— el total bruto del ZAL original que se corrige (corresponde aP_15ZK).
Ejemplo: Factura JST (unidad de gobierno local)
Una factura dirigida a una unidad de gobierno local subordinada (JST). El comprador (Podmiot2) es la entidad principal; el destinatario real es un Podmiot3 con rol 8.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2026-03-23", "tax_point_date": "2026-03-23", "invoice_number": "F/2026/JST/001", "description": "Services for local government unit", "customer_party_name": "Gmina Kraków", "customer_party_tax_id": "6762450871", "customer_party_address": "Plac Wszystkich Świętych 3-4", "customer_party_country": "pl", "customer_party_jst": true, "third_party_name": "Szkoła Podstawowa nr 7", "third_party_tax_id": "7654321098", "third_party_tax_scheme": "9945", "currency": "PLN", "tax_inclusive_amount": 1230.00, "tax_amount": 230.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 10, "unit_code": "EA", "description": "Consulting services", "price": 100.00, "tax_code": "23", "tax_exclusive_amount": 1000.00, "tax_amount": 230.00, "tax_inclusive_amount": 1230.00 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 1000.0, "tax_amount": 230.00 } ] } }'customer_party_jst: true— establecePodmiot2/JSTa1en el XML FA(3).third_party_name/third_party_tax_id— el destinatario JST, representado comoPodmiot3con rol8.- Para facturas de miembros de grupo de IVA, usa
customer_party_gv: trueen su lugar (rol10).
Ejemplo: Factura UPR
Para UPR, los campos customer_party_tax_id y customer_party_country son obligatorios.
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "UPR", "ticket": true, "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/006", "description": "Sample UPR Invoice", "customer_party_tax_id": "1234567890", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 12.30, "tax_amount": 2.30, "type_operation": "goods", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "EA", "description": "product 1", "price": 10.00, "tax_code": "23", "tax_exclusive_amount": 10.00, "tax_amount": 2.30, "tax_inclusive_amount": 12.30 } ], "tax_breakdowns": [ { "name": "PTU", "category": "S", "percent": 23.0, "taxable_base": 10.0, "tax_amount": 2.30 } ] } }'Ejemplo: Factura con inversión del sujeto pasivo nacional
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/007", "description": "Construction services - reverse charge", "customer_party_name": "Example Construction Sp. z o.o.", "customer_party_tax_id": "1234567890", "customer_party_address": "Address 1", "customer_party_country": "pl", "currency": "PLN", "tax_inclusive_amount": 5000.00, "tax_amount": 0.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 1, "unit_code": "EA", "description": "Construction services per contract X", "price": 5000.00, "tax_code": "oo", "tax_exclusive_amount": 5000.00, "tax_amount": 0.00, "tax_inclusive_amount": 5000.00 } ], "tax_breakdowns": [ { "name": "VAT", "category": "AE", "percent": 0.0, "taxable_base": 5000.0, "tax_amount": 0.0, "scope": "domestic" } ] } }'Ejemplo: Inversión del sujeto pasivo transfronteriza (Servicios)
curl --request POST \ --url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_reports \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Content-Type: application/json' \ --data '{ "tax_report": { "type": "KSeF", "invoice_type_code": "VAT", "invoice_date": "2025-11-07", "tax_point_date": "2025-11-07", "invoice_number": "F/2025/11/008", "description": "Consulting services - cross-border", "customer_party_name": "Example Company GmbH", "customer_party_tax_id": "DE123456789", "customer_party_address": "Berlin Street 1, 10115 Berlin", "customer_party_country": "de", "currency": "EUR", "exchange_rate": 4.30, "tax_inclusive_amount": 3000.00, "tax_amount": 0.00, "type_operation": "services", "tax_report_lines": [ { "position": 1, "quantity": 20, "unit_code": "HUR", "description": "IT consulting services", "price": 150.00, "tax_code": "np I", "tax_exclusive_amount": 3000.00, "tax_amount": 0.00, "tax_inclusive_amount": 3000.00 } ], "tax_breakdowns": [ { "name": "VAT", "category": "AE", "percent": 0.0, "taxable_base": 3000.0, "tax_amount": 0.0 } ] } }'Estructura de la respuesta
Sección titulada «Estructura de la respuesta»La respuesta incluirá el informe fiscal con estado “sending”:
{ "tax_report": { "id": 12345, "type": "KSeF", "state": "sending", "fingerprint": "a3f2c1b9e8d7...", "identifier": "https://ksef-test.mf.gov.pl/client-app/invoice/5792000046/2025-11-07/a3f2c1b9e8d7...", "qr": "iVBORw0KGgoAAAANSUhEUgAA...", ... }}Importante: A diferencia de los modelos de validación tradicionales, B2Brouter puede generar el fingerprint, el identifier (URL del código QR) y el qr (imagen del código QR) inmediatamente al crear el informe fiscal, sin esperar la confirmación de KSeF. Esto es posible porque estos campos se calculan a partir de datos que ya tenemos:
fingerprint: Hash SHA-256 del documento XML FA(3)identifier: URL construida a partir de: NIP del proveedor + fecha de la factura + fingerprint (formato Base64URL)qr: Imagen del código QR que codifica la URL delidentifier
Etiqueta del código QR:
- Mientras el informe fiscal está en estado
sending(antes de la confirmación de KSeF), la etiqueta del código QR debe mostrar “OFFLINE” - Una vez que el informe fiscal alcanza el estado
registeredy recibes elto_net_id(número de referencia KSeF), debes mostrar el número KSeF debajo del código QR
Buena práctica: Aunque los datos del código QR están disponibles inmediatamente, se recomienda esperar hasta que el informe fiscal alcance el estado registered antes de imprimir/enviar facturas a los clientes. Esto garantiza que la factura ha sido aceptada correctamente por KSeF y evita posibles problemas si la presentación falla.
Verificar el estado del informe fiscal
Sección titulada «Verificar el estado del informe fiscal»La presentación a KSeF es asíncrona. Debes monitorizar el estado del informe fiscal:
Opción 1: Usando Webhooks (Recomendado)
Configura un webhook de informe fiscal para recibir notificaciones cuando el estado cambia a un estado final: registered o error.
Opción 2: Polling
Consulta el endpoint de obtención de informe fiscal hasta que el estado sea final:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}'Comprender la respuesta en estado registrado
Sección titulada «Comprender la respuesta en estado registrado»Cuando el informe fiscal alcanza el estado registered, la respuesta incluye el número de referencia oficial de KSeF:
{ "tax_report": { "id": 12345, "type": "KSeF", "state": "registered", "to_net_id": "1234567890-20251107-ABCD1234-EF", "fingerprint": "a3f2c1b9e8d7...", "identifier": "https://ksef-test.mf.gov.pl/client-app/invoice/1234567890/2025-11-07/a3f2c1b9e8d7...", "qr": "iVBORw0KGgoAAAANSUhEUgAA...", ... }}| Campo | Disponible | Descripción |
|---|---|---|
to_net_id | Tras la confirmación de KSeF | Número de referencia KSeF - El identificador único asignado por KSeF. Muestra este número debajo del código QR en las facturas impresas/PDF. |
fingerprint | Inmediatamente al crear | Hash SHA-256 del documento XML FA(3) presentado. Usado para verificación de integridad del documento y generación del código QR. |
identifier | Inmediatamente al crear | URL del código QR - La URL completa a la que apunta el código QR. Construida a partir de: NIP del proveedor + fecha de la factura + fingerprint. |
qr | Inmediatamente al crear | Imagen del código QR - Imagen PNG codificada en base64 del código QR. Puede incrustarse en facturas inmediatamente, incluso antes de la confirmación de KSeF. |
Descargar el UPO (Recibo Oficial)
Sección titulada «Descargar el UPO (Recibo Oficial)»Una vez que el informe fiscal alcanza el estado registered, puedes descargar el UPO usando el endpoint de descarga de respuesta:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID}/download_response \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Accept: application/xml'Descargar el XML FA(3)
Sección titulada «Descargar el XML FA(3)»También puedes descargar el XML FA(3) completo que fue enviado a KSeF:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID}/download \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}' \ --header 'Accept: application/xml'Alternativamente, el campo xml_base64 en la respuesta del informe fiscal contiene el XML codificado en base64.
Gestión de errores
Sección titulada «Gestión de errores»Si el informe fiscal alcanza el estado error, verifica los detalles del informe fiscal para obtener información del error:
curl --request GET \ --url https://api-staging.b2brouter.net/tax_reports/{TAX_REPORT_ID} \ --header 'X-B2B-API-Key: {YOUR_API_KEY}' \ --header 'X-B2B-API-Version: {YOUR_API_VERSION}'Equivalencia entre los campos del informe fiscal de B2Brouter y los nodos XML FA(3) de KSeF
Sección titulada «Equivalencia entre los campos del informe fiscal de B2Brouter y los nodos XML FA(3) de KSeF»La estructura del formato JSON para los informes fiscales de B2Brouter se basa en PEPPOL Continuous Transaction Control (CTC). Los campos usados en el payload JSON tienen nombres diferentes a los de la representación XML FA(3). Esto se debe a que la API de informes fiscales de B2Brouter es una API universal diseñada para gestionar el reporte fiscal en todo el mundo, no solo para KSeF.
Campos principales de la factura
Sección titulada «Campos principales de la factura»| Campo B2Brouter | Nodo XML FA(3) de KSeF |
|---|---|
| type | Debe ser “KSeF” |
| invoice_type_code | Fa > RodzajFaktury |
| invoice_date | Fa > P_1 |
| invoice_number | Fa > P_2 |
| tax_point_date | Fa > P_6 |
| customer_party_name | Podmiot2 > DaneIdentyfikacyjne > Nazwa |
| customer_party_tax_id | Podmiot2 > DaneIdentyfikacyjne > NIP (PL) o NrVatUE (UE) o NrID (no UE) |
| customer_party_country | Podmiot2 > DaneIdentyfikacyjne > KodUE o KodKraju |
| supplier_party_name | Podmiot1 > DaneIdentyfikacyjne > Nazwa |
| supplier_party_tax_id | Podmiot1 > DaneIdentyfikacyjne > NIP |
| supplier_party_country | Podmiot1 > PrefiksPodatnika |
| description | Stopka > Informacje > StopkaFaktury |
| currency | Fa > KodWaluty |
| exchange_rate | Fa > KursWalutyZ |
| payment_date | Fa > Platnosc > TerminPlatnosci > Termin (no pagado) o Fa > Platnosc > DataZaplaty (pagado) |
| payable_amount | Cuando se establece a 0 con payment_date, marca la factura como pagada (Zaplacono=1) |
| payment_means_type_code | Fa > Platnosc > FormaPlatnosci |
| payment_account_identifier | Fa > Platnosc > RachunekBankowy > NrRB |
| payment_service_provider_identifier | Fa > Platnosc > RachunekBankowy > SWIFT |
| amended_ksef_number | Fa > DaneFaKorygowanej > NrKSeFFaKorygowanej |
| tax_inclusive_amount | Fa > P_15 (importe total) |
| customer_party_jst | Podmiot2 > JST (1 cuando true, 2 cuando false) |
| customer_party_gv | Podmiot2 > GV (1 cuando true, 2 cuando false) |
| third_party_name | Podmiot3 > DaneIdentyfikacyjne > Nazwa |
| third_party_tax_id | Podmiot3 > DaneIdentyfikacyjne > NIP (PL), NrVatUE (UE), o NrID (no UE) |
| purchase_order_date | Fa > WarunkiTransakcji > Zamowienia > DataZamowienia |
| despatch_advice_reference | Fa > WZ |
| supplier_contact_email | Podmiot1 > DaneKontaktowe > Email |
| supplier_contact_phone | Podmiot1 > DaneKontaktowe > Telefon |
| supplier_party_regon | Stopka > Rejestry > REGON |
| supplier_party_krs | Stopka > Rejestry > KRS |
| supplier_party_bdo | Stopka > Rejestry > BDO |
| previous_advance_total | Fa > P_15ZK (solo KOR_ZAL) |
| prepayment_references | Fa > FakturaZaliczkowa (solo ROZ/KOR_ROZ) |
Líneas del informe fiscal (FaWiersz)
Sección titulada «Líneas del informe fiscal (FaWiersz)»| Campo B2Brouter | Nodo XML FA(3) de KSeF |
|---|---|
| position | FaWiersz > NrWierszaFa |
| description | FaWiersz > P_7 |
| unit_code | FaWiersz > P_8A |
| quantity | FaWiersz > P_8B |
| price | FaWiersz > P_9A |
| discount_amount | FaWiersz > P_10 |
| tax_code | FaWiersz > P_12 |
| tax_exclusive_amount | FaWiersz > P_11 |
| tax_amount | FaWiersz > P_11Vat |
| ksef_amended | FaWiersz > StanPrzed (marca la línea corregida) |
Desgloses fiscales
Sección titulada «Desgloses fiscales»| Campo B2Brouter | Nodo XML FA(3) de KSeF |
|---|---|
| name | Nombre del esquema fiscal (p. ej., “PTU”, “VAT”) |
| category | Categoría fiscal: “S” (estándar), “E” (exento), “AE” (inversión del sujeto pasivo) |
| percent | Porcentaje del tipo impositivo |
| taxable_base | P_13_x (base imponible por grupo de tipo) |
| tax_amount | P_14_x (importe fiscal por grupo de tipo) |
| comment | Adnotacje > Zwolnienie > P_19A (motivo de exención, cuando la categoría es “E”) |
| exemption_code | Anulación de P_12 — acepta zw |
| no_subject_code | Anulación de P_12 — acepta np I, np II |
| non_exemption_code | Anulación de P_12 — acepta 0 KR, 0 WDT, 0 EX, oo |
Los tres campos *_code son opcionales. Cuando no están establecidos, B2Brouter deriva el código P_12 a partir de category, percent, scope y type_operation. Establece uno de ellos para fijar el código explícitamente.
Descripción general de la estructura FA(3)
Sección titulada «Descripción general de la estructura FA(3)»<tns:Faktura xmlns:tns="http://crd.gov.pl/wzor/2025/06/25/13775/"> <tns:Naglowek> <tns:KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</tns:KodFormularza> <tns:WariantFormularza>3</tns:WariantFormularza> <tns:DataWytworzeniaFa><!-- Timestamp --></tns:DataWytworzeniaFa> <tns:SystemInfo>B2Brouter</tns:SystemInfo> </tns:Naglowek>
<tns:Podmiot1><!-- Proveedor (Vendedor) --></tns:Podmiot1> <tns:Podmiot2><!-- Cliente (Comprador) --></tns:Podmiot2>
<tns:Fa> <!-- Detalles de la factura: moneda, fechas, importes fiscales --> <!-- Totales de desglose fiscal: P_13_x, P_14_x, P_15 --> <!-- Adnotacje (anotaciones/indicadores) --> <!-- RodzajFaktury (tipo de factura) -->
<tns:FaWiersz><!-- Línea de factura 1 --></tns:FaWiersz> <tns:FaWiersz><!-- Línea de factura 2 --></tns:FaWiersz>
<tns:Platnosc><!-- Datos de pago (opcional) --></tns:Platnosc> <tns:WarunkiTransakcji><!-- Condiciones de la transacción (opcional) --></tns:WarunkiTransakcji> </tns:Fa>
<tns:Stopka><!-- Pie/notas (opcional) --></tns:Stopka></tns:Faktura>Descripciones de códigos para campos específicos de KSeF
Sección titulada «Descripciones de códigos para campos específicos de KSeF»Códigos de tipo de factura
Sección titulada «Códigos de tipo de factura»Parámetro: invoice_type_code
| Código | Descripción | Usado para |
|---|---|---|
| VAT | Factura básica | Facturas ordinarias |
| KOR | Factura correctiva | Correcciones |
| ZAL | Factura de pago anticipado (Art. 106f sec. 4) | Pagos anticipados |
| ROZ | Factura según Art. 106f sec. 3 | Liquidaciones |
| UPR | Factura simplificada (Art. 106e sec. 5 punto 3) | Simplificadas |
| KOR_ZAL | Factura correctiva de pago anticipado | Correcciones |
| KOR_ROZ | Factura correctiva de ROZ | Correcciones |
Códigos de efecto de nota de crédito
Sección titulada «Códigos de efecto de nota de crédito»Tipo de efecto de la corrección en los registros del IVA. Se usa para facturas correctivas (KOR, KOR_ZAL, KOR_ROZ).
Parámetro: credit_note_code (en Tax Report Setting)
| Código | Descripción |
|---|---|
| 1 | Corrección con efecto en la fecha de reconocimiento de la factura original |
| 2 | Corrección con efecto en la fecha de emisión de la factura correctiva |
| 3 | Corrección con efecto en una fecha diferente (o fechas diferentes para distintos artículos) |
Códigos fiscales
Sección titulada «Códigos fiscales»Tipos impositivos del IVA y categorías usados en Polonia. Se usa a nivel de línea.
Parámetro: tax_code (en tax_report_lines)
| Código | Descripción |
|---|---|
| 23 | Tipo estándar del IVA 23% |
| 22 | Tipo estándar del IVA 22% |
| 8 | Tipo reducido del IVA 8% |
| 7 | Tipo reducido del IVA 7% |
| 5 | Tipo reducido del IVA 5% |
| 4 | Tipo reducido del IVA 4% |
| 3 | Tipo reducido del IVA 3% |
| 0 WDT | Suministro intracomunitario 0% (Wewnątrzwspólnotowa Dostawa Towarów) |
| 0 EX | Exportación 0% |
| 0 KR | Tipo cero nacional 0% |
| zw | Exento del IVA (zwolniona) |
| oo | Inversión del sujeto pasivo nacional (odwrotne obciążenie) |
| np I | No sujeto al IVA - servicios transfronterizos (nie podlega) |
| np II | No sujeto al IVA - servicios nacionales |
Códigos de medios de pago
Sección titulada «Códigos de medios de pago»Parámetro: payment_means_type_code
| Código | Descripción |
|---|---|
| 1 | Efectivo |
| 2 | Tarjeta |
| 3 | Bono |
| 4 | Móvil |
| 5 | Cheque |
| 6 | Transferencia bancaria |
| 7 | Otro |
Tipos de operación
Sección titulada «Tipos de operación»Parámetro: type_operation (en Tax Report Setting)
| Código | Descripción |
|---|---|
| services | Servicios |
| goods | Bienes |