Go to file
admin ecc8ce475d Add FNMT valid certificates URL to documentation 2026-04-17 13:08:22 +02:00
api Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00
documentacion Add FNMT valid certificates URL to documentation 2026-04-17 13:08:22 +02:00
internal Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00
verifactu Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00
.gitignore base: project structure and configuration 2026-04-08 14:30:50 +02:00
AGENTS.md base: project structure and configuration 2026-04-08 14:30:50 +02:00
ERRORES.md docs: add error codes documentation 2026-04-08 14:30:58 +02:00
README.md update 2026-04-08 15:43:37 +02:00
config.yml Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00
go.mod Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00
go.sum base: project structure and configuration 2026-04-08 14:30:50 +02:00
main.go Implement VeriFactu API with certificate management, invoice submission and local fallback 2026-04-17 13:03:06 +02:00

README.md

VeriFactu Middle API

API intermediaria para el protocolo VeriFactu de la AEAT.


Instalación

go build .

Configuración

Editar config.yml:

server:
  port: 6789

verifactu:
  environment: test

certificates:
  storage_path: ./certs/

crypto:
  keys_path: ./keys/
  name: "VeriFactu API"
  email: "admin@example.com"

Las claves RSA se generan automáticamente en ./keys/ si no existen.


Autenticación

1. Obtener clave pública

GET /api/v1/auth/public-key

Devuelve la clave pública RSA para cifrar la contraseña del certificado.

2. Registrar certificado

POST /api/v1/auth/register

{
  "cert_name": "mi-certificado",
  "cert_path": "archivo.p12",
  "password_encrypted": "BASE64_RSA_ENCRYPTED_PASSWORD"
}

Respuesta:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

3. Usar token

En todas las peticiones siguientes:

Authorization: Bearer <token>

Estructura de datos

Enviar factura (POST /api/v1/facturas)

{
  "tipo": "alta",
  "factura": {
    "emisor_nif": "A12345678",
    "num_serie": "2024-001",
    "fecha_expedicion": "13-09-2024",
    "tipo_factura": "F1",
    "descripcion": "Descripción",
    "destinatario": {
      "nombre": "CLIENTE SL",
      "nif": "B98765432"
    },
    "iva": [
      {"base": 100.00, "cuota": 21.00, "tipo": 21.00}
    ],
    "importe_total": 121.00
  },
  "sistema": {
    "nombre": "Software",
    "nif_proveedor": "A12345678",
    "version": "1.0.0"
  }
}

Anular factura (POST /api/v1/facturas/anular)

{
  "factura": {
    "emisor_nif": "A12345678",
    "num_serie": "2024-001",
    "fecha_expedicion": "13-09-2024"
  },
  "sistema": {
    "nombre": "Software",
    "nif_proveedor": "A12345678",
    "version": "1.0.0"
  }
}

Campos obligatorios

Campo Tipo Descripción
tipo string alta o anulacion
emisor_nif string NIF emisor (9 caracteres)
num_serie string Número de serie
fecha_expedicion string Fecha (dd-mm-yyyy)
tipo_factura string F1, F2, R1-R5
iva[] array Al menos un registro
importe_total number > 0
sistema.* object Datos del software

Respuestas

Éxito

{
  "success": true,
  "csv": "ABC123...",
  "estado": "Correcto"
}

Error de validación

{
  "success": false,
  "error": "validation_failed",
  "details": [{"field": "emisor_nif", "message": "invalid NIF format"}]
}

Error AEAT

{
  "success": false,
  "error": "aeat_error",
  "codigo": "1000",
  "mensaje": "Descripción"
}

Ver ERRORES.md para códigos de error completos.


Límites

-Máximo 1.000 registros por solicitud (actualmente 1)

  • Entorno actual: pruebas (sandbox)