docs: reorganize documentation and add prerequisites guide

- Move ERRORES.md to documentacion/
- Add PREREQUISITES.md with system requirements and setup steps
- Update documentacion/README.md as documentation index
- Simplify root README.md as project summary
This commit is contained in:
lite 2026-05-17 16:27:18 -04:00
parent 4225af5b05
commit 74487015df
5 changed files with 283 additions and 271 deletions

View File

@ -1,15 +0,0 @@
# Códigos de Error
## Errores de Validación (propios de la API)
| Código | Descripción |
|--------|-------------|
| `VALIDATION_REQUIRED` | Campo obligatorio vacío |
| `VALIDATION_INVALID_NIF` | Formato NIF inválido |
| `VALIDATION_INVALID_DATE` | Formato de fecha inválido |
| `VALIDATION_INVALID_TYPE` | Tipo de factura inválido |
| `VALIDATION_INVALID_AMOUNT` | Importe inválido |
## Errores AEAT
Ver `Documentacion de Verifactu/08_errores_y_respuestas.md` para la lista completa de códigos de la AEAT.

209
README.md
View File

@ -1,187 +1,48 @@
# VeriFactu Middle API
# VeriFactu MidAPI
API intermediaria para el protocolo VeriFactu de la AEAT.
API intermediaria para enviar facturas a la AEAT a través del protocolo VeriFactu.
Recibe facturas en JSON, calcula el hash encadenado, genera el XML SOAP y lo envía a la AEAT. Si la AEAT no está disponible, guarda la factura localmente (fallback).
---
## Instalación
## Documentación
```bash
go build .
```
| | |
|---|---|
| [Requisitos y setup](documentacion/PREREQUISITES.md) | Go, Python, OpenSSL, certificado, configuración |
| [API Reference](documentacion/api.md) | Endpoints, requests, responses |
| [Protocolo VeriFactu](documentacion/verifactu.md) | Operaciones, hash, URLs AEAT, XML |
| [Formato de datos](documentacion/formato_datos.md) | NIF, fechas, tipos factura, IVA, ejemplo JSON |
| [Formatos de entrada](documentacion/formatos.md) | native, dolibarr, y cómo añadir nuevos |
| [Arquitectura](documentacion/arqui.md) | Capas, flujo de datos, cifrado |
| [Seguridad](documentacion/seguridad.md) | Certificados, RSA, HTTPS |
| [Certificados](documentacion/certificado_pruebas.md) | Obtener y configurar certificado FNMT |
| [Tokens](documentacion/tokens.md) | Sistema de autenticación por tokens |
| [Configuración](documentacion/config.md) | config.yml, variables de entorno |
| [Testing](documentacion/testing.md) | Tests, depuración |
| [Errores](documentacion/ERRORES.md) | Códigos de error |
---
## Configuración
## Endpoints
Editar `config.yml`:
```yaml
server:
port: 6789
verifactu:
production: false # true para producción
certificates:
storage_path: ./data/certs/
cert_file: ./data/certs/personal.p12
cert_password: TU_CONTRASEÑA
crypto:
keys_path: ./keys/
name: "VeriFactu API"
email: "admin@example.com"
```
Las claves RSA se generan automáticamente en `./keys/` si no existen.
| Método | Ruta | Descripción |
|--------|------|-------------|
| `GET` | `/api/v1/health` | Health check |
| `GET` | `/api/v1/auth/public-key` | Clave pública RSA |
| `POST` | `/api/v1/auth/register` | Registrar certificado .p12 |
| `GET` | `/api/v1/formats` | Lista formatos disponibles |
| `POST` | `/api/v1/facturas` | Alta de factura (formato auto-detectado) |
| `POST` | `/api/v1/facturas/anular` | Anular factura |
---
## 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**
```json
{
"cert_name": "mi-certificado",
"cert_path": "archivo.p12",
"password_encrypted": "BASE64_RSA_ENCRYPTED_PASSWORD"
}
```
Respuesta:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```
### 3. Usar token
En todas las peticiones siguientes:
```
Authorization: Bearer <token>
```
---
## Estructura de datos
### Enviar factura (POST /api/v1/facturas)
```json
{
"tipo": "alta",
"factura": {
"emisor_nif": "A12345678",
"emisor_nombre": "NOMBRE REGISTRADO EN AEAT",
"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": "NOMBRE REGISTRADO EN AEAT PARA EL NIF PROVEEDOR",
"nif_proveedor": "A12345678",
"version": "1.0.0"
}
}
```
### Anular factura (POST /api/v1/facturas/anular)
```json
{
"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` |
| `factura.emisor_nif` | string | NIF emisor (9 caracteres) |
| `factura.emisor_nombre` | string | Nombre del emisor exactamente como figura en el censo AEAT |
| `factura.num_serie` | string | Número de serie |
| `factura.fecha_expedicion` | string | Fecha (`dd-mm-yyyy`) |
| `factura.tipo_factura` | string | `F1`, `F2`, `R1`-`R5` |
| `factura.destinatario` | object | Obligatorio para F1, F3 y rectificativas |
| `factura.iva[]` | array | Al menos un registro |
| `factura.importe_total` | number | > 0 |
| `sistema.nombre` | string | Nombre del proveedor del software exactamente como figura en el censo AEAT para su NIF |
| `sistema.nif_proveedor` | string | NIF del proveedor del software |
| `sistema.version` | string | Versión del software |
---
## Respuestas
### Éxito
```json
{
"success": true,
"csv": "ABC123...",
"estado": "Correcto"
}
```
### Error de validación
```json
{
"success": false,
"error": "validation_failed",
"details": [{"field": "emisor_nif", "message": "invalid NIF format"}]
}
```
### Error AEAT
```json
{
"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)
## Estado
- [x] Alta de facturas con hash encadenado
- [x] Fallback local
- [x] Registro y validación de certificados
- [ ] Anulación con AEAT
- [ ] Consultas
- [ ] Subsanación

55
documentacion/ERRORES.md Normal file
View File

@ -0,0 +1,55 @@
# Códigos de Error
## Errores de autenticación
| Código | Descripción |
|--------|-------------|
| `missing_fields` | Faltan campos obligatorios en el registro |
| `invalid_json` | El cuerpo de la petición no es JSON válido |
| `invalid_password_encrypted` | La contraseña cifrada no es Base64 válido |
| `decrypt_failed` | No se pudo descifrar la contraseña con la clave privada RSA |
| `file_not_found` | El archivo de certificado no existe |
| `invalid_password_or_format` | Contraseña incorrecta o formato de certificado inválido |
| `certificate_not_yet_valid` | El certificado aún no es válido |
| `certificate_expired` | El certificado ha expirado |
| `certificate_expiring_soon` | El certificado caduca en menos de 30 días (warning) |
| `temp_storage_failed` | Error guardando el certificado temporal |
| `storage_failed` | Error moviendo el certificado a almacenamiento permanente |
| `token_generation_failed` | Error generando el token de sesión |
## Errores de validación de facturas
La API devuelve `validation_failed` con detalles por campo:
```json
{
"success": false,
"error": "validation_failed: factura.emisor_nif: invalid NIF format; ..."
}
```
| Campo | Error |
|-------|-------|
| `tipo` | Debe ser `alta` o `anulacion` |
| `factura.emisor_nif` | Vacío o formato inválido (esperado: 9 caracteres, regex `^[A-Z0-9]\d{7}[A-Z]$`) |
| `factura.num_serie` | Vacío |
| `factura.fecha_expedicion` | Vacío o formato inválido (esperado: `dd-mm-yyyy`) |
| `factura.tipo_factura` | Vacío o no es `F1`, `F2`, `R1`-`R5` |
| `factura.iva[]` | Sin registros, o base/cuota/tipo negativos |
| `factura.importe_total` | Menor o igual a 0 |
| `sistema.nombre` | Vacío |
| `sistema.nif_proveedor` | Vacío |
| `sistema.version` | Vacío |
## Errores de procesamiento
| Código | Descripción |
|--------|-------------|
| `hash_storage_error` | Error leyendo el último hash almacenado |
| `hash_save_error` | Error guardando el hash de la factura actual |
| `aeat_error: <detalle>` | Error comunicando con la AEAT |
| `aeat_fault: <detalle>` | Fault SOAP devuelto por la AEAT |
## Errores AEAT
La AEAT devuelve códigos de error en el campo `CodigoErrorRegistro` de la respuesta SOAP. Consulta la documentación oficial de la AEAT para la lista completa.

View File

@ -0,0 +1,167 @@
# Prerequisites
## System Requirements
### Go
- **Version:** 1.26 or higher
- **Download:** https://go.dev/dl/
- **Verify installation:**
```bash
go version
```
### Python 3
Required for test scripts and certificate conversion utilities.
- **Version:** 3.8 or higher
- **Verify installation:**
```bash
python --version
```
### OpenSSL (optional but recommended)
Used as an alternative to the Python conversion script for `.p12` to `.pem` certificates.
- **Linux:** `sudo apt install openssl` / `sudo pacman -S openssl`
- **macOS:** `brew install openssl`
- **Windows:** https://slproweb.com/products/Win32OpenSSL.html
- **Verify installation:**
```bash
openssl version
```
## Project Setup
### 1. Clone the repository
```bash
git clone <repository-url>
cd VerifactuMidAPI
```
### 2. Install Go dependencies
```bash
go mod download
```
### 3. Create required directories
```bash
mkdir -p data/certs data keys
```
| Directory | Purpose |
|---|---|
| `data/certs/` | Stored `.p12` certificates |
| `data/` | Hash chain records (JSON files per emitter) |
| `keys/` | Auto-generated RSA key pair for password encryption |
### 4. Configure the application
Copy or edit `config.yml`:
```yaml
server:
port: 6789
verifactu:
production: false
certificates:
storage_path: ./data/certs/
cert_file: ./data/certs/personal.p12
cert_password: YOUR_PASSWORD
crypto:
keys_path: ./keys/
name: "VeriFactu API"
email: "admin@example.com"
```
> **Important:** Change `cert_password` and `email` to your own values.
### 5. Obtain a digital certificate
VeriFactu requires a **qualified electronic certificate** (eIDAS compliant) in `.p12` or `.pfx` format.
- **FNMT Persona Fisica** (free): https://www.fnmt.es
- Must be valid and registered with AEAT for the testing environment
- Place it at `./data/certs/personal.p12` (or update `cert_file` in config)
---
## Build & Run
### Development (auto-reload with source)
```bash
go run .
```
### Production build
```bash
go build -o verifactu-api .
./verifactu-api
```
The server starts on `http://localhost:6789` (or the port configured in `config.yml`).
---
## Verify the installation
### 1. Health check
```bash
curl http://localhost:6789/api/v1/health
# Expected: {"status":"ok"}
```
### 2. Get public key
```bash
curl http://localhost:6789/api/v1/auth/public-key
# Expected: {"public_key":"<base64>"}
```
---
## Troubleshooting
### `go: command not found`
Go is not installed or not in your `PATH`. Add it:
```bash
# Linux/macOS
export PATH=$PATH:/usr/local/go/bin
# Windows: add C:\Program Files\Go\bin to system PATH
```
### `config.yml not found`
The API falls back to defaults but logs a warning. Create the file as described in step 4.
### `certificate expired` / `invalid_password_or_format`
- Verify the certificate dates with:
```bash
openssl pkcs12 -in ./data/certs/personal.p12 -info -nokeys
```
- Ensure the password in `config.yml` matches the certificate.
### `403 Forbidden` from AEAT
The certificate is not authorized in the AEAT testing environment. Contact AEAT or verify your FNMT certificate is enabled for VeriFactu.
### Hardcoded Windows paths
`verifactu/client.go` and `internal/cert/validator.go` contain hardcoded Windows paths (`C:\Users\jmest\...`). Update them to your environment or use the `cert_file` config option instead.

View File

@ -1,91 +1,35 @@
# VeriFactu MidAPI
# Documentación
API intermediaria para la comunicación con el sistema de facturación VeriFactu de la AEAT (Agencia Estatal de Administración Tributaria) de España.
Índice de documentación técnica de VeriFactu MidAPI.
## Propósito
## Guías
Esta API actúa como intermediaria entre aplicaciones empresariales y el sistema VeriFactu de Hacienda, permitiendo:
| Documento | Descripción |
|-----------|-------------|
| [PREREQUISITES.md](PREREQUISITES.md) | Requisitos del sistema, setup paso a paso, build, run y troubleshooting |
| [ERRORES.md](ERRORES.md) | Códigos de error de la API y de la AEAT |
- **Alta de facturas**: Registro de facturas emitidas en el sistema de Hacienda
- **Anulación de facturas**: Cancelación de facturas previamente registradas
- **Gestión de certificados**: Registro y validación de certificados digitales cualificados
- **Sistema de tokens**: Autenticación mediante tokens para operaciones con facturas
## Referencia técnica
## Características
| Documento | Descripción |
|-----------|-------------|
| [api.md](api.md) | Referencia completa de endpoints, requests y responses |
| [verifactu.md](verifactu.md) | Protocolo VeriFactu: operaciones, hash encadenado, URLs AEAT, formato XML |
| [formato_datos.md](formato_datos.md) | Formatos de datos: NIF, fechas, tipos de factura, IVA, ejemplo JSON |
| [formatos.md](formatos.md) | Formatos de entrada soportados: native, dolibarr, y cómo añadir nuevos |
| [arqui.md](arqui.md) | Arquitectura del proyecto, capas y flujo de datos |
- Implementación en **Go 1.26+**
- Sin dependencias externas
- **Endpoints REST** para integración
- Criptografía **RSA** para cifrado de contraseñas
- certificados almacenados temporalmente para validación, luego de forma permanente
- Tokens de acceso similares a APIs como OpenAI
## Seguridad y certificados
## Estructura del Proyecto
| Documento | Descripción |
|-----------|-------------|
| [seguridad.md](seguridad.md) | Certificados digitales, cifrado RSA, HTTPS, rate limiting |
| [certificado_pruebas.md](certificado_pruebas.md) | Obtención y configuración de certificados FNMT para pruebas |
| [tokens.md](tokens.md) | Sistema de tokens: flujo, almacenamiento, seguridad |
```
VerifactuMidAPI/
├── api/ → Handlers HTTP, rutas
├── internal/ → Lógica de negocio
│ ├── cert/ → Gestión de certificados
│ ├── config/ → Configuración
│ └── crypto/ → Criptografía RSA
├── verifactu/ → Cliente SOAP para AEAT
├── documentacion/ → Documentación técnica
└── test/ → Pruebas
```
## Configuración y testing
## Inicio Rápido
```bash
# Compilar
go build -o verifactu-api.exe ./main.go
# Ejecutar
./verifactu-api.exe
```
## Configuración
Editar `config.yml`:
```yaml
server:
port: 6789
verifactu:
production: false # true para producción
certificates:
storage_path: ./data/certs/
crypto:
keys_path: ./keys/
```
## Estado
- [x] Alta de facturas
- [x] Fallback local (cuando AEAT no disponible)
- [x] Tokens para certificados
- [x] Registro de certificados
- [x] Cifrado RSA de contraseñas
- [x] Anulación de facturas (básico, sin comunicación AEAT)
- [ ] Consultas
- [ ] Subsanación
- [ ] Conexión real con AEAT (necesita certificado FNMT registrado)
## Pruebas
```bash
# Tests de certificados (en test/)
python test/run_tests.py
# Test de factura
python test/test_invoice.py
```
## Notas
- AEAT devuelve 403 Forbidden (necesita certificado cliente)
- Fallback local guarda facturas cuando AEAT no disponible
- Certificado se convierte usando Python cryptography
| Documento | Descripción |
|-----------|-------------|
| [config.md](config.md) | Fichero config.yml, variables de entorno, estructura de directorios |
| [testing.md](testing.md) | Tests de certificados, tests de facturas, depuración |