Cómo generar una factura electrónica conforme con n8n y SealDoc
Generar una factura electrónica conforme implica más piezas de lo que parece. Necesitas una factura XML válida, el perfil EN 16931 correcto, un contenedor PDF/A-3 con ese XML incrustado e, idealmente, un sello de tiempo RFC 3161 antes de que entre en tu archivo. Construir todo eso en una integración propia supone semanas de trabajo.
Este tutorial monta el mismo resultado en n8n con el nodo de comunidad n8n-nodes-sealdoc. Sin código propio. El flujo genera la factura, obtiene el XML y el PDF/A-3, y guarda ambos.
Requisitos previos
- Una instancia de n8n autoalojada con los nodos de comunidad habilitados.
- Un espacio de trabajo de SealDoc con acceso a la API: el plan gratuito Developer o cualquier plan de pago. Consulta los precios.
- Una clave API de SealDoc. Créala en la app de SealDoc, en Integration → API Keys. Cópiala enseguida: solo se muestra una vez.
- Los datos de tu empresa. El vendedor de la factura es tu propia empresa, y su número de IVA tiene que coincidir con el número de IVA de tu espacio de trabajo de SealDoc.
Instala el nodo en n8n desde Settings → Community nodes → Install, con el nombre de paquete n8n-nodes-sealdoc. Si prefieres instalar los nodos a mano, ejecuta esto en tu carpeta de nodos de n8n (normalmente ~/.n8n/nodes) y reinicia n8n:
npm i n8n-nodes-sealdoc
Después crea la credencial: Credentials → New → SealDoc API, y pega tu clave en el campo API Key. Deja Base URL en https://api.sealdoc.eu.
Qué hace el flujo
- Un disparador proporciona los datos de la factura como JSON: un webhook, una fila de base de datos, el envío de un formulario o cualquier otra fuente de n8n.
- SealDoc · Invoice · Generate construye la factura electrónica, la valida y la sella en un PDF/A-3. Todo ocurre dentro de la llamada: el nodo devuelve un trabajo terminado.
- SealDoc · Invoice · Get XML devuelve el XML de la factura electrónica como fichero.
- Un nodo HTTP Request descarga el PDF/A-3.
- Un nodo de almacenamiento guarda los dos ficheros en tu archivo.
Paso 1: configurar el disparador
Crea un flujo nuevo y añade un disparador Webhook con el método HTTP POST. Así obtienes una URL a la que cualquier sistema puede llamar con datos de factura. Para hacer pruebas, un Manual Trigger con datos fijos funciona igual de bien.
Un ejemplo mínimo de lo que puede proporcionar el disparador:
{
"invoiceNumber": "INV-2026-00042",
"invoiceDate": "2026-05-06",
"dueDate": "2026-06-05",
"buyer": {
"name": "Widget BV",
"vatNumber": "NL987654321B01",
"address": "Keizersgracht 10",
"postalCode": "1015 CN",
"city": "Amsterdam",
"country": "NL"
},
"line": {
"description": "Consulting services May 2026",
"quantity": 10,
"unitPriceExclVat": 150.00
}
}
El vendedor no aparece en este payload. Es tu propia empresa, así que lo configuras una sola vez en el nodo.
Paso 2: añadir Invoice · Generate
Añade un nodo SealDoc, cámbiale el nombre a Generate invoice y configura:
- Resource: Invoice. Operation: Generate.
- Invoice Number Source: Own Number. Invoice Number:
{{ $json.invoiceNumber }}. ¿Prefieres que SealDoc numere tus facturas? Elige entonces SealDoc Numbering Series. - Invoice Date:
{{ $json.invoiceDate }}. Due Date:{{ $json.dueDate }}. - Currency: EUR.
- VAT Rate:
0.21. El tipo se expresa como fracción, así que el 21 % es 0.21. Deja VAT Category en “derive from the rate” y VAT Label vacío: con un tipo general, SealDoc escribe por sí mismo la mención del IVA. - Seller: tu empresa, con Name, VAT Number, Address, Postal Code, City y Country (código de dos letras).
- Buyer Source: Buyer Details. Buyer: asigna cada campo desde el disparador, por ejemplo
{{ $json.buyer.name }}y{{ $json.buyer.postalCode }}. Los clientes que hayas guardado en SealDoc se pueden usar directamente con Buyer Profile. - Lines: añade una línea con Description
{{ $json.line.description }}, Quantity{{ $json.line.quantity }}, Unit Hour y Unit Price (Excl. VAT){{ $json.line.unitPriceExclVat }}. - Profile: Basic (Factur-X 1.0). El nodo también ofrece XRechnung DE, que necesita una Buyer Reference (el Leitweg-ID) y un contacto del vendedor, y Peppol BIS 3.0 (UBL 2.1), que necesita los identificadores de endpoint Peppol de ambas partes.
- RFC 3161 Timestamp: activado, que es el valor por defecto.
Selecciona tu credencial SealDoc API y ejecuta el nodo. La respuesta tiene este aspecto:
{
"jobId": "3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10",
"status": "completed",
"statusUrl": "/api/jobs/3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10"
}
completed significa que la factura está generada, validada frente a EN 16931 y sellada. No hay nada que sondear. Si alguna vez una respuesta dice queued o processing, un nodo SealDoc · Job · Get con el mismo jobId te indica cuándo ha terminado.
Paso 3: obtener el XML
Añade un segundo nodo SealDoc: Resource Invoice, Operation Get XML, Job ID {{ $('Generate invoice').item.json.jobId }}. El nodo devuelve el XML de la factura electrónica como fichero binario en el campo data: factur-x.xml para el perfil Basic, xrechnung.xml para XRechnung y peppol-ubl.xml para Peppol BIS.
Paso 4: descargar el PDF/A-3
Añade un nodo HTTP Request:
- Method: GET
- URL:
https://api.sealdoc.eu/api/download/{{ $('Generate invoice').item.json.jobId }} - Authentication: Generic Credential Type y después Header Auth, con el nombre
X-Api-Keyy tu clave API como valor. - Response Format: File.
El resultado es el PDF/A-3 sellado con el XML incrustado.
Paso 5: guardar el resultado
Añade el nodo de almacenamiento que encaje con tu stack: Google Drive, Dropbox, un bucket compatible con S3, SFTP a tu propio servidor o Write Binary File en el propio host de n8n.
Desde el plan Starter, cada trabajo tiene además un Legal Evidence Pack: GET /api/jobs/{id}/evidence-pack, con la misma cabecera X-Api-Key. SealDoc lo ensambla justo después del trabajo; si lo pides en los primeros instantes, la API responde 409 con una cabecera Retry-After, así que basta con un nodo Wait breve antes de la petición.
Cuando algo sale mal
Los errores llegan de inmediato, como una respuesta con un code:
- 400 para una entrada no válida, por ejemplo
seller_required,currency_requiredoinvalid_vat_rate. - 402
plan_feature_requiredcuando tu plan no incluye la función. - 403
seller_vat_mismatchcuando el número de IVA del vendedor no coincide con el de tu espacio de trabajo. - 409
quota_reachedcuando has agotado tu límite mensual. - 422
einvoice_invalidcuando la factura no supera la validación.
Por defecto, el nodo SealDoc detiene el flujo cuando se produce un error. Configura el ajuste On Error del nodo para que continúe con una salida de error y dirige esa salida a Slack o al correo electrónico, para que una persona vea qué hay que corregir.
Lo que obtienes
Un PDF/A-3 que cualquier visor de PDF abre como una factura legible, con el XML incrustado para el software contable que importa Factur-X o ZUGFeRD. El token de sello de tiempo RFC 3161 se guarda con el trabajo y se puede descargar por separado (GET /api/jobs/{id}/timestamp). Suelta el PDF en nuestro validador gratuito para ver tú mismo el veredicto y cada hallazgo.
Próximos pasos
- Valida facturas existentes: SealDoc · Validator · Check valida un fichero Factur-X o ZUGFeRD que ya tengas, sin generar nada.
- Genera otros documentos: SealDoc · Document · Generate convierte Markdown o HTML en un PDF/A-3 sellado en una sola llamada.
- Consulta lo que has emitido: SealDoc · Invoice · Get Summary devuelve el número de factura, el perfil, el idioma y los totales de IVA de una factura generada.
La referencia completa de la API, con una especificación OpenAPI y ejemplos curl, está enlazada desde nuestra página para desarrolladores.