Documentación técnica: SDK Java y API REST para Verifactu

Arquitectura modular, ejemplos de código y guía técnica completa para integrar Verifactu en tu sistema, ya sea vía API REST o vía librería Java. Esta documentación es la capa técnica de Facturware - Verifactu API.

Implementación de la especificación Verifactu de la AEAT

Solución enterprise modular multi-tenancy que permite integrar Verifactu en cualquier sistema rápidamente. Evita tener que implementar manualmente la lógica fiscal exigida por la AEAT lo cual puede llevar meses de desarrollo.

El sistema cubre todo el ciclo de vida de una factura:

Mapear factura → Elegir tipo → Validar → Generar hash → Firmar → Enviar AEAT
→ Obtener QR → Recibir estado → Subsanar o rectificar si procede

Permite trabajar con todos los tipos de factura definidos por la AEAT:

El flujo consiste en:

Dispone de una API de alto nivel con 6 métodos principales enfocados a todos los casos de uso posibles para operaciones con Verifactu:

Estos metodos estan perfectamente documentados, asi como los diferentes tipos de datos que suelen estar agrupados en ENUM con todas las variantes, se proveen ejemplos de uso basicos hasta los mas complejos. Normalmente un ERP se limitara a Crear, Anular, Rectificar y alguna vez Subsana. Aun que existen diferentes casos contemplados por el software por ejemplo: Importaciones (con parametros y regimenes especiales), Cafeteria que emite tickets F2 y posteriormente los transforma a F3, etc...

Arquitectura Modular

megafactur-core   → Comunicacion SOAP AEAT + Operaciones bajo nivel (firma, hash, QR) | Librería Java pura (sin frameworks)
	↑
megafactur-engine → API Java + persistencia + metodos operaciones alto nivel (Crear, Anular, Subsanar etc...) | Librería JOOQ + Flyway + HikariCP
	↑
megafactur-server → API REST + dashboard | Microservicio Quarkus

Cada módulo es independiente y puede utilizarse de forma aislada según el caso de uso. El módulo server permite integración con cualquier tecnologia mediante REST.

Modulo Server (REST API + Dashboard)

Servidor autónomo basado en Quarkus que expone una API REST completa para operar con VERIFACTU.

Características

Para integraciones con cualquier proyecto que pueda implementar un cliente REST.

Endpoints principales

| Método | Endpoint | Descripción |
|--------|----------|-------------|
| `POST` | `/api/v1/{nif}/invoices` | Crear y registrar una nueva factura (F1, F2, F3, R1-R5) |
| `POST` | `/api/v1/{nif}/invoices/cancel` | Anular una factura |
| `POST` | `/api/v1/{nif}/invoices/correct` | Subsanar el registro enviado de una factura |
| `POST` | `/api/v1/{nif}/invoices/rectify` | Emitir factura rectificativa referenciando las originales |
| `POST` | `/api/v1/{nif}/invoices/convert-tickets` | Convertir uno o varios tickets F2 en una factura F3 con datos del cliente |
| `POST` | `/api/v1/{nif}/invoices/merge-breakdowns` | Obtener la fusión de desgloses de una o varias facturas |
| `POST` | `/api/v1/{nif}/invoices/check` | Validar los datos de una factura antes de enviarla |
| `GET`  | `/api/v1/{nif}/invoices/{invoiceNumber}/status` | Consultar estado de la factura (local + AEAT) |
| `GET`  | `/api/v1/{nif}/invoices/{invoiceNumber}/qr` | Obtener código QR de validación (imagen PNG) |
| `POST` | `/api/v1/{nif}/invoices/{invoiceNumber}/retry` | Reintento manual (solo TECHNICAL_ERROR y NOT_PROCESSED) |

Diagrama integracion SERVER

modulo engine

Integracion peticion REST

El modulo implementa API FIRST, así que sencillamente descargando la especificación OPENAPI: http://localhost:8080/q/openapi Con Openapi generator y un cliente REST dependiendo de la tecnología se podrían generar modelos e interfaces fácilmente.

curl -X POST http://localhost:8080/api/v1/B72877814/invoices \
  -H "X-API-Key: tu-clave-secreta-1" \
  -H "Content-Type: application/json" \
  -d '{
    "invoiceNumber": "FACT-2024-001",
    "issueDate": "2024-01-15",
    "invoiceType": "F1",
    "totalAmount": 1210.00,
    "taxAmount": 210.00,
    "issuerTaxId": "B72877814",
    "issuerName": "Empresa Demo S.L.",
    "operationDescription": "Servicios de consultoría",
    "breakdowns": [
      {
        "claveRegimen": "01",
        "calificacionOperacion": "S1",
        "taxRate": 21.0,
        "baseAmount": 1000.00,
        "taxAmount": 210.00
      }
    ]
  }'

Ejemplo despliegue artefacto

Diseño como microservicio Quarkus que puede integrase en sistema complejo, o sencillamente desplegar como artefacto java,

your-app/
├── megafactur-server.jar
├── companies/
│   ├── B72877814/
│   │   ├── config.yml
│   │   └── certificate.p12
│   └── A12345674/
│       ├── config.yml
│       └── certificate.p12
└── application.properties     # sobreescritura opcional

Dispone de documentacion Swagger muy intuitiva

modulo engine

Existen ejemplos coherentes para cada operación, se dispone de schemas para que se pueda visualizar fácilmente los tipos de datos que se pueden mandar, posibilidades, combinaciones...

Dashboard

modulo engine

Este modulo tiene ademas un dashboard para visualizar todos los tenants, y para cada uno de ellos realizar operaciones de facturacion Las operaciones están bien definidas de manera que incluso los flujos y casos mas raros son intuitivos y sencillos de realizar

Modulo Engine (Libreria Java)

Librería de alto nivel diseñada para integrarse directamente en aplicaciones Java.

Características técnicas

Configuración flexible:

• Mediante fichero (YAML) • O programáticamente (builder) Debido a su diseño es compatible con cualquier Framework java EJB, Spring, Quarkus … ya que hace uso de librerias sin CDI por lo que sencillamente se importa como una librería,

Operaciones principales

Diagrama integracion ENGINE

modulo engine

Ejemplo integracion en proyecto JAVA

Importar artefacto maven:
<dependency>
    <groupId>com.horus.megafactur</groupId>
    <artifactId>megafactur-engine</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>
Configuración mediante YAML:
apiKey: ${COMPANY_API_KEY}   # API key por empresa (opcional, sobreescribe las globales)

database:
  url: jdbc:postgresql://localhost:5432/megafactur_tenant1
  username: ${DB_USER}
  password: ${DB_PASSWORD}
  maxPoolSize: 10

certificate:
  path: ${CERT_PATH}
  password: ${CERT_PASS}

company:
  nif: B72877814
  name: Empresa Demo S.L.

production: false
verifactuMode: true
autoMigrate: true
Instanciar ENGINE y mandar factura:
try (MegafacturEngine engine = MegafacturEngine.create(config)) {
    engine.start();  // Crea automáticamente: BD → Flyway → JOOQ → Facades → Scheduler

    // Crear una factura
    InvoiceData factura = new InvoiceData();
    factura.setInvoiceNumber("FACT-2024-001");
    factura.setIssueDate(LocalDate.of(2024, 1, 15));
    factura.setInvoiceTypeEnum(InvoiceType.F1);
    factura.setTotalAmount(1210.00);
    factura.setTaxAmount(210.00);
    factura.setIssuerTaxId("B72877814");
    factura.setIssuerName("Empresa Demo S.L.");

    InvoiceResult resultado = engine.invoices().createInvoice(factura);
    System.out.println("Hash: " + resultado.getHash());
    System.out.println("Tamaño QR: " + resultado.getQrCode().length + " bytes");

    // Forzar despacho a la AEAT
    DispatchResult despacho = engine.dispatch().forceDispatch();
    System.out.println(despacho.getMessage());

}  // Cierre automático: detiene el scheduler y cierra el pool de conexiones

Realmente en 3 líneas de código se puede mandar la factura a la AEAT, ya que simplemente debes de mapear la factura a formato InvoiceData lo cual podría estar en una función de mapeo a parte.

Dispone de documentación Java muy intuitiva:

Todos los métodos están documentados

modulo engine

Así como todos los campos relevantes, no hay datos mágicos todo es un ENUM bien definido

modulo engine

Modulo Core (AEAT)

Implementación de bajo nivel que gestiona la comunicación con la AEAT, firma XadES, calculo Hash y especificacion Verifactu a bajo nivel.

Incluye

Modelos factura formato verifactu:

• Este proyecto en su totalidad rechaza el uso indiscriminado del patrón DTO por lo que el modulo core es el unico source of truth, todos los modelos estan aqui. • De este modo se ahorran muchisimos mappers inecesarios, fricciones y posibles bugs tan comunes al mapear.

Guía Técnica

Flujo completo

1. Crear factura
2. Validar datos
3. Generar hash
4. Firmar XML
5. Enviar a AEAT
6. Recibir respuesta
7. Gestionar estado

Rectificación

engine.invoices().rectifyInvoice(...)

Resultado operacion

Después de ejecutar una operación tendremos inmediatamente el QR en base 64 para incluir en la factura junto con la URL de validación:

{
  "recordId": 42,
  "hash": "A1B2C3D4E5F6...",
  "validationUrl": "...",
  "qrBase64": "...",
  "state": "PENDING_DISPATCH"
}

Esto sera preciso añadirlo a la factura. Cuando mediante accion manual llamando al metodo de forzar envio, o el scheduler del engine envie la factura a la AEAT tendremos el resultado de la operación:

{
  "valid": true,
  "hashValid": true,
  "linkValid": true,
  "invoiceNumber": "invoiceNumber",
  "expectedHash": "expectedHash",
  "errorDetail": "errorDetail",
  "actualHash": "actualHash"
}
De aquí se puede extraer el estado AEAT de la operación para incluirlo en el sistema: ACEPTADO, CORRECTO, ACEPTADO CON ERRORES

Errores comunes

Error 1189 → falta destinatario  (Factura tipo F1 sin destinatario)
Solución → añadir destinatario y reenviar

Has llegado al final de la guía técnica

← Volver al inicio

Contacto

Para asistencia con integraciones y mas información.

Contacto