Skip to content

runciter2078/verifactu-microapi

Repository files navigation

Spain e-Invoice Toolkit — VERI*FACTU QR + Facturae 3.2.2 + UBL 2.1

Micro-API stateless para desarrolladores/ERPs en España:

  • /validate: valida NIF/NIE/CIF y coherencias básicas de factura (sumas, IVA, RE).
  • /qr: genera la cadena y las imágenes (PNG/SVG) del código QR VERI*FACTU.
  • /convert: JSON → Facturae 3.2.2 (XML) y JSON → UBL 2.1 Invoice (XML).
  • /check: chequeos mínimos de consistencia SIF (no almacena datos).

La Orden HAC/1177/2024 establece el contenido del QR (URL del servicio de cotejo AEAT + NIF emisor + serie/número + fecha + importe total) y remite a la sede electrónica de AEAT para ubicación/presentación. ([BOE][1]) Los esquemas Facturae 3.2.2 y UBL 2.1 son públicos y validables contra sus XSD oficiales. ([OASIS][2])


1) Cómo se usa (vía RapidAPI)

  1. Suscríbete a la API en el Hub de RapidAPI.

  2. En la consola de pruebas copia los snippets (cURL/JS/Python) que ya incluyen:

    • X-RapidAPI-Key: tu clave de app.
    • X-RapidAPI-Host: el host único de esta API.
  3. Llama a los endpoints usando la Gateway URL que te muestra RapidAPI.

Con RapidAPI Auth es obligatorio enviar X-RapidAPI-Key y X-RapidAPI-Host en cada petición; la pasarela de Rapid gestiona cuotas, límites y analítica. ([RapidAPI][3])

Seguridad del proveedor (tú)

Para bloquear accesos directos que no pasen por RapidAPI, este añade el header X-RapidAPI-Proxy-Secret a cada request. Valídalo en tu backend con la variable RAPIDAPI_PROXY_SECRET y devuelve 403 si no coincide. ([RapidAPI][4])


2) Endpoints

GET /ping

Healthcheck rápido.

200

{ "ok": true }

POST /validate

Valida NIF/NIE/CIF (checksum/patrones) y cuadres: base, vat, re, grand_total (tolerancia ±0,01).

Request (JSON)

{
  "series": "F2025",
  "number": "000123",
  "issue_date": "2025-10-12",
  "currency": "EUR",
  "seller": { "name": "Acme SL", "tax_id": "A58818501", "country": "ES", "address": "C/ Mayor 1" },
  "buyer":  { "name": "Cliente SA", "tax_id": "12345678Z", "country": "ES", "address": "Av. Sol 10" },
  "lines":  [{ "description": "Servicio X", "qty": 2, "unit_price": 100, "vat_rate": 21 }],
  "totals": { "base": 200, "vat": 42, "re": 0, "grand_total": 242 }
}

Response

{
  "ok": true,
  "errors": [],
  "detected": { "seller_type": "CIF", "buyer_type": "NIF" }
}

POST /qr

Devuelve cadena canónica del QR y artefactos PNG/SVG.

Request (JSON)

{
  "seller_tax_id": "A58818501",
  "series": "F2025",
  "number": "000123",
  "issue_date": "2025-10-12",
  "grand_total": 242.00
}

Response (ejemplo)

{
  "qr_string": "https://.../ValidarQR?nif=A58818501&numserie=F2025-000123&fecha=12-10-2025&importe=242.00",
  "png_base64": "iVBORw0KGgoAAA...",
  "svg": "<svg .../>"
}

El contenido mínimo del QR y su URL de cotejo están definidos por norma; AEAT publica la ubicación/presentación y detalles técnicos en su sede electrónica. ([BOE][1])


POST /convert

Convierte a XML en los formatos estándar.

Request

{
  "target": "facturae",   // "facturae" | "ubl"
  "invoice": { ...Invoice... }
}

Response

{ "xml": "<Facturae>...</Facturae>" }

Facturae 3.2.2 (sitio oficial facturae.gob.es) y UBL 2.1 (OASIS). ([OASIS][2])


POST /check

Flags objetivos (no negativa, hashable, etc.). No certifica cumplimiento; es soporte técnico.


3) Snippets

Recuerda reemplazar X-RapidAPI-Host y X-RapidAPI-Key por los que te muestra el Hub.

cURL

# /qr
curl --request POST \
  --url https://<gateway-host>/qr \
  --header 'X-RapidAPI-Host: <host-from-hub>' \
  --header 'X-RapidAPI-Key: <your-key>' \
  --header 'Content-Type: application/json' \
  --data '{
    "seller_tax_id":"A58818501",
    "series":"F2025","number":"000123",
    "issue_date":"2025-10-12","grand_total":242
  }'

Node (axios)

import axios from "axios";
const res = await axios.post("https://<gateway-host>/validate", {
  series: "F2025", number: "000123", issue_date: "2025-10-12", currency: "EUR",
  seller: { name: "Acme SL", tax_id: "A58818501", country: "ES" },
  buyer:  { name: "Cliente SA", tax_id: "12345678Z", country: "ES" },
  lines:  [{ description: "Servicio X", qty: 2, unit_price: 100, vat_rate: 21 }],
  totals: { base: 200, vat: 42, re: 0, grand_total: 242 }
}, {
  headers: {
    "X-RapidAPI-Host": "<host-from-hub>",
    "X-RapidAPI-Key": "<your-key>"
  }
});
console.log(res.data);

Python (requests)

import requests, json
url = "https://<gateway-host>/convert"
payload = {
  "target": "facturae",
  "invoice": { /* ...Invoice... */ }
}
r = requests.post(url, json=payload, headers={
  "X-RapidAPI-Host": "<host-from-hub>",
  "X-RapidAPI-Key": "<your-key>"
})
print(r.json())

PowerShell

$headers = @{
  "X-RapidAPI-Host" = "<host-from-hub>"
  "X-RapidAPI-Key"  = "<your-key>"
  "Content-Type"    = "application/json"
}
$body = @{
  seller_tax_id="A58818501"; series="F2025"; number="000123"
  issue_date="2025-10-12"; grand_total=242
} | ConvertTo-Json -Depth 5

Invoke-RestMethod -Uri "https://<gateway-host>/qr" -Method POST -Headers $headers -Body $body

4) Modelos (resumen)

Party  { name: string; tax_id: string; country: "ES"|".."; address?: string }
Line   { description: string; qty: number; unit_price: number; vat_rate: 0|4|10|21; re_equiv?: number }
Totals { base: number; vat: number; re?: number; grand_total: number }
Invoice{ series: string; number: string; issue_date: "YYYY-MM-DD"; currency: "EUR"|"..."; seller: Party; buyer: Party; lines: Line[]; totals: Totals }

5) Despliegue (opcional, si auto-hosteas)

  • Runtime: Python 3.11 + FastAPI + Uvicorn.

  • ENV:

    • AEAT_QR_BASE_URL → URL de cotejo AEAT (parametrizable).
    • APP_VERSION → versión de la app (ej. 0.1.0).
    • RAPIDAPI_PROXY_SECRET → valor copiado de Firewall Settings en RapidAPI Studio (valida X-RapidAPI-Proxy-Secret). ([RapidAPI][4])
  • Docker: incluye Dockerfile multi-stage; uvicorn expone 0.0.0.0:$PORT.


6) Cumplimiento y referencias

  • QR VERI*FACTU – Contenido mínimo, nivel de corrección y referencia a la sede de AEAT para ubicación/presentación: Orden HAC/1177/2024 (BOE). ([BOE][1])
  • Marco SIF/VERI*FACTU – Requisitos de los sistemas de facturación (RD 1007/2023). ([KPMG Assets][5])
  • Facturae 3.2.2 – Esquemas y documentación oficiales. ([OASIS][2])
  • UBL 2.1 – Especificación OASIS UBL Invoice 2.1. ([Agencia Tributaria][6])
  • RapidAPI – Auth (X-RapidAPI-Key / X-RapidAPI-Host) y Proxy Secret. ([RapidAPI][3])

Nota legal: Esta API es herramienta técnica para generar/validar formatos y coherencias. No es certificación ni asesoría legal. Confirma siempre requisitos vigentes en AEAT/BOE.


7) Roadmap

  • v0.1.0 (MVP): /validate, /qr, /convert (→ Facturae), /check.
  • v0.2.0: JSON → UBL 2.1 (completo) y XML → JSON (Facturae/UBL).
  • v0.3.0: hash de registro SIF (cálculo/verificación básica).

8) Contribuir

PRs y issues bienvenidos:

  1. Crea rama desde main.
  2. Añade tests mínimos (si aplican).
  3. Describe cambios y casos de prueba.

9) Licencia

MIT. Ver LICENSE.