Resumen: Esta guía documenta la integración técnica del adaptador "Micro Server" en entornos PHP (Web y CLI). Permite delegar la complejidad criptográfica y de comunicación con la AEAT a un backend intermedio, diseñado para cumplir con la normativa VeriFactu de forma robusta y sencilla.
El motor ha sido diseñado bajo la filosofía "Drop-in": un solo archivo .php sin dependencias de Composer ni frameworks externos, garantizando compatibilidad con hostings compartidos, CMS (WordPress, PrestaShop) y aplicaciones legacy.
El núcleo consta de dos archivos esenciales que deben copiarse a su proyecto:
vf_engine.php (El Motor)
php-curl, presente en el 99% de los servidores PHP.ssl_verify) para manejar certificados en desarrollo local (WAMP/XAMPP) sin romper la seguridad en producción.config.ini (Configuración)
parse_ini_file.Es de vital importancia distinguir entre los certificados de la AEAT y la comunicación SSL de la API:
ssl_verify que verá en su archivo config.ini o a lo largo de este documento hace referencia exclusivamente a si el Micro Server está montado detrás de un dominio con HTTPS (ej. https://api.mipropioerp.com). En entornos de desarrollo local (WAMP/XAMPP), esta función permite ignorar errores de certificados generados por usted mismo para asegurar su API.El sistema gestiona el ciclo de vida de la factura en tres fases: 1. INGESTA: Envío del JSON de la factura al Backend. El backend la guarda inmediatamente (buffer). 2. POLLING: Consulta periódica de la cola de "Pendientes" (facturas ya procesadas por la AEAT) esperando confirmación. 3. ACK: Confirmación de recepción por parte del ERP/Web tras guardar la Huella y la URL del QR.
No encontrará en esta guía una documentación exhaustiva sobre cómo construir el JSON campo a campo. ¡No es necesario!
El Panel de Administración Web del Micro Server (sección Envíos) incluye una herramienta de Generación de Payloads interactiva diseñada específicamente para desarrolladores.
Nota sobre
metadata: El esquema JSON exige un bloquemetadataen la raíz. Aunque actualmente su contenido es ignorado, debe estar presente para pasar la validación del esquema.
El Backend actúa como un buffer inteligente. Su aplicación PHP no habla con la AEAT directamente; habla con este Micro Server.
ingestaJson)Su aplicación genera un array o JSON con los datos de la factura y lo envía.
$res = $vf->ingestaJson($datosFactura);
if ($res['ok']) {
// Factura aceptada en el sistema. ID Tracking: $res['tracking']['cab_num_secuencia']
}
getPendientes)El ERP o un proceso Cron debe preguntar periódicamente al endpoint de pendientes.
$res = $vf->getPendientes("B12345678", 50);
ackIndice)Una vez que su sistema ha recuperado los datos finales (QR y Huella):
1. Guárdelos en su base de datos local asociados a la factura.
2. Envíe un ACK al Backend indicando el indice_log.
3. El Backend marca esa operación como "Entregada" y la saca de la cola.
El sistema implementa lógica avanzada para manejar situaciones complejas:
Las facturas pueden enviarse con fecha de emisión futura o anterior. El backend las custodiará hasta que sean procesadas.
Si envía una factura (mismo NIF, Serie y Número) y esta aún no ha sido procesada por la AEAT (sigue en cola interna): * La nueva versión SOBRESCRIBE a la anterior. * Esto permite corregir errores (ej: olvidar el IVA) si se detectan rápido, sin dejar rastro de la versión errónea en la AEAT.
Si envía una factura que YA fue procesada y aceptada por la AEAT: * Si el sistema detecta cambios, intentará enviarla como una Subsanación (si la configuración lo permite). * En caso contrario, la AEAT devolverá un error indicando que la factura ya existe, forzando a realizar una factura rectificativa (con nueva serie/número).
La ingesta devolverá error (HTTP 4xx/5xx) si detecta: * Errores de sintaxis JSON. * Incoherencias matemáticas graves (Total != Base + Cuota). * Falta de campos obligatorios (NIF, Fecha, Totales).
A diferencia de entornos de escritorio, en PHP la visualización es trivial. El campo url_qr_verifactu devuelto en el Paso 2 es una URL pública de la AEAT.
Simplemente incruste la imagen generada por la AEAT (o use una librería JS como qrcode.js):
<!-- Opción A: Enlace directo (La AEAT genera el PDF/Imagen) -->
<a href="<?php echo $item['url_qr_verifactu']; ?>" target="_blank">Ver QR VeriFactu</a>
<!-- Opción B: Generar QR en el navegador -->
<div id="qrcode"></div>
<script>
new QRCode(document.getElementById("qrcode"), "<?php echo $item['url_qr_verifactu']; ?>");
</script>
config.ini) y Autenticación (API Key)Para garantizar la seguridad en un entorno Multi-Tenant, el Micro Server puede exigir una API Key (Token) para autorizar todas las peticiones y restringir el acceso a la información de los emisores (RBAC).
El motor PHP se encarga automáticamente de inyectar las cabeceras HTTP de seguridad (X-API-Key y X-Verifactu-Emisor) si se configuran correctamente en su archivo config.ini:
[api]
; URL del VeriFactu Micro Server
base_url=http://localhost:8000
; Timeout para cURL
timeout_sec=30
; Token de seguridad (API Key). Si el backend exige autenticación (require_auth=true), este campo es OBLIGATORIO.
token=mi_clave_api_secreta_123
; Verificar SSL (false para desarrollo local inseguro, true para producción)
ssl_verify=true
[demo]
; NIF del emisor asociado a esta instancia. El API Key debe tener permisos sobre este NIF.
nif_emisor=B12345678
Si la opción require_auth=True está activada en el backend, la API exigirá dos elementos de seguridad obligatorios que vf_engine.php envía por defecto:
X-API-Key (Token): Identifica al usuario o integración ERP.X-Verifactu-Emisor (NIF): Declara el NIF sobre el que se va a operar. El servidor comprueba si la API Key facilitada tiene permisos concedidos explícitamente sobre este NIF.Prevención de Suplantación en la Ingesta:
Como medida de máxima seguridad, durante una operación de Ingesta, el servidor abre el JSON enviado y verifica que el campo cabecera.emisor coincida exactamente con el NIF para el que el usuario se ha autenticado. Si un usuario intenta enviar o consultar facturas camuflando un NIF ajeno, la operación se abortará inmediatamente devolviendo un error HTTP 403 Forbidden. Lo mismo ocurrirá si intenta consultar facturas pendientes de otro emisor.
token vacío): El motor PHP intentará realizar las llamadas sin cabeceras. Si el servidor tiene la seguridad activada, rechazará la petición y devolverá en el array de respuesta un error HTTP 401 Unauthorized.mensaje del array de respuesta, indicándole al desarrollador el fallo exacto ("El usuario no tiene permisos sobre el NIF...").ssl_verify=false en config.ini solo durante desarrollo.getPendientes más tarde.mensaje y el array detalles devuelto por el vf_engine para ver el campo exacto del error.checkStatus($nif, $serie, $num)Consulta ligera para saber si una factura concreta ya se procesó, sin traer toda la lista de pendientes. Útil para interfaces "AJAX" que muestran el estado en tiempo real.
getEstadoFactura($nif, $num, $serie)Devuelve la traza completa (logs) de una factura. Útil para depurar por qué una factura ha sido rechazada por la AEAT, mostrando el mensaje de error exacto devuelto por Hacienda.