Cómo integrar VeriFactu en tu software (guía con código)
· Equipo Factuneo
Paso a paso para emitir tu primera factura VeriFactu desde tu aplicación: alta del emisor, certificado, emisión por API y webhooks de estado. Con ejemplos en cURL y Node.
El objetivo
Emitir una factura conforme a VeriFactu sin construir tú el encadenado de huellas, el XML, el QR ni la comunicación SOAP con la AEAT. Todo eso lo resuelve la API; tú haces llamadas REST.
1. Consigue tu API key
Al registrarte obtienes una API key (x-api-key) que identifica tu cuenta. Una misma cuenta puede facturar por varios NIFs (emisores).
2. Da de alta un emisor
Un emisor es el obligado tributario que factura (un NIF). Puedes crearlo desde el panel o por API:
curl -X POST https://factuneo.es/api/v1/emisores \
-H "x-api-key: vsk_tu_clave" \
-H "Content-Type: application/json" \
-d '{
"nif": "B12345678",
"nombreRazon": "Mi Empresa SL",
"certMode": "PROPIO"
}'
3. Sube el certificado
VeriFactu se comunica con la AEAT mediante mTLS, así que hace falta un certificado. Tienes dos modos:
- Propio: un certificado por emisor (el del propio obligado).
- Representado: un único certificado de la cuenta (colaborador social o apoderado) que factura por sus clientes.
En modo Propio, subes el P12 en base64 con su contraseña:
curl -X POST https://factuneo.es/api/v1/emisores/EMISOR_ID/certificate \
-H "x-api-key: vsk_tu_clave" \
-H "Content-Type: application/json" \
-d '{ "certificateBase64": "MIIK...", "password": "la-clave-del-p12" }'
4. Emite la factura
Una sola llamada genera el registro, la huella encadenada, el QR y lo remite a la AEAT:
curl -X POST https://factuneo.es/api/v1/invoices \
-H "x-api-key: vsk_tu_clave" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f9a-0001" \
-d '{
"emisorNif": "B12345678",
"numeroSerie": "FAC-2026-0001",
"fechaExpedicion": "2026-06-08",
"tipoFactura": "F1",
"nombreRazonEmisor": "Mi Empresa SL",
"descripcionOperacion": "Servicios de desarrollo",
"baseImponible": 100.00,
"cuotaIva": 21.00,
"importeTotal": 121.00,
"destinatarios": [{ "nombreRazon": "Cliente Ejemplo SL", "nif": "B87654321" }],
"desglose": [{
"claveRegimen": "01",
"calificacionOperacion": "S1",
"tipoImpositivo": 21,
"baseImponible": 100.00,
"cuotaRepercutida": 21.00
}]
}'
La respuesta incluye el identificador, la huella, el QR y el estado de envío. Si además necesitas el Facturae 3.2.2 firmado, se genera en el mismo endpoint —sin coste extra.
Idempotencia
Envía una cabecera Idempotency-Key única por factura. Si repites la llamada (por un reintento de red), no se duplica el registro: recibes el mismo resultado.
5. Escucha los webhooks
En vez de sondear el estado, registra una URL de webhook y recibe los eventos (invoice.accepted, invoice.rejected, invoice.error, invoice.cancelled) en cuanto ocurren:
// Ejemplo de receptor en Node/Express
app.post('/webhooks/factuneo', (req, res) => {
const { id, event, data } = req.body
// Descarta lo ya procesado: el mismo id llega si reenvías el evento.
if (yaProcesado(id)) return res.sendStatus(200)
if (event === 'invoice.accepted') marcarAceptada(data.invoiceId)
if (event === 'invoice.rejected') marcarRechazada(data.invoiceId, data.aeat)
guardarProcesado(id)
res.sendStatus(200)
})
6. Consulta y anula
Puedes consultar el estado de cualquier factura y, si procede, emitir un registro de anulación (VeriFactu no permite borrar: se anula dejando rastro).
Resumen
Con seis pasos tienes VeriFactu integrado: API key → emisor → certificado → emitir → webhook → consultar. Todo el peso normativo y criptográfico queda del lado de la API. Cuando quieras, la documentación completa tiene los ejemplos en cURL, Node, Python, Java y C#.