Comment générer une facture Peppol conforme avec n8n et SealDoc
Générer une facture Peppol conforme implique plus d’éléments qu’il n’y paraît. Vous avez besoin d’un document XML CII valide, du bon profil EN 16931, d’un conteneur PDF/A-3, d’une pièce jointe XML intégrée, et idéalement d’un horodatage RFC 3161 avant qu’il n’aille dans votre archive. Faire tout cela depuis zéro dans une intégration personnalisée représente des semaines de travail.
Ce tutoriel montre comment assembler le même résultat dans n8n en environ 30 minutes, en utilisant le nœud communautaire n8n-nodes-sealdoc. Aucun code personnalisé. Le flux de travail couvre la génération de factures, le polling des tâches et le stockage des résultats.
Prérequis
Avant de commencer, vous avez besoin de :
- Une instance n8n exécutant la version 1.0 ou ultérieure, en auto-hébergement ou sur n8n Cloud. Le nœud communautaire fonctionne sur les deux.
- Un compte SealDoc sur le plan Starter ou supérieur. Les fonctionnalités de génération de factures et d’horodatage sont disponibles à partir du Starter.
- Une clé API SealDoc. Générez-en une dans le tableau de bord SealDoc sous Paramètres, puis Clés API. Copiez-la immédiatement ; elle n’est affichée qu’une seule fois.
Installez le nœud communautaire sur votre instance n8n :
npm i n8n-nodes-sealdoc
Redémarrez n8n après l’installation. Vous verrez maintenant le nœud SealDoc disponible dans le panneau de nœuds sous la catégorie Community.
Ce que fait le flux de travail
Ce flux de travail prend des données de facture (vendeur, acheteur, lignes, montants) et produit un Factur-X PDF/A-3 entièrement conforme avec XML CII intégré. Les étapes sont :
- Un déclencheur fournit les données de facture en JSON (depuis un webhook, une requête de base de données, une soumission de formulaire ou toute autre source n8n).
- Le nœud SealDoc Invoice.Generate envoie les données structurées à l’API SealDoc et retourne un identifiant de tâche.
- Le nœud SealDoc Job.Get poll jusqu’à ce que la tâche soit terminée et retourne une URL de téléchargement pour le document généré.
- Un nœud final stocke le résultat à l’emplacement d’archive de votre choix.
Étape 1 : configurer le déclencheur
Créez un nouveau flux de travail. Ajoutez un nœud déclencheur Webhook. Définissez la méthode HTTP sur POST. Cela vous donne une URL que vous pouvez appeler avec des données de facture depuis n’importe quel système pouvant effectuer une requête HTTP.
Pour les tests, vous pouvez également utiliser un Execute Workflow Trigger ou un Manual Trigger avec des données statiques. L’important est que le déclencheur produise un objet JSON avec vos champs de facture. Nous référencerons ces champs dans l’étape suivante.
Un exemple minimal des données de facture que votre déclencheur doit fournir :
{
"invoiceNumber": "INV-2026-00042",
"issueDate": "2026-05-06",
"dueDate": "2026-06-05",
"seller": {
"name": "Acme BV",
"vatNumber": "NL123456789B01",
"address": "Herengracht 1, 1000 AA Amsterdam, NL",
"iban": "NL91ABNA0417164300"
},
"buyer": {
"name": "Widget GmbH",
"vatNumber": "DE987654321",
"address": "Hauptstrasse 10, 10115 Berlin, DE"
},
"lines": [
{
"description": "Consulting services May 2026",
"quantity": 10,
"unitPrice": 150.00,
"vatRate": 21
}
],
"currency": "EUR"
}
Étape 2 : ajouter le nœud Invoice.Generate
Ajoutez un nœud SealDoc sur le canevas. Définissez :
- Ressource : Invoice
- Opération : Generate
- Profil : EN 16931 (utilisez EXTENDED si votre acheteur ou mandat requiert des champs supplémentaires)
- Intégrer l’horodatage : activé (cela attache un horodatage RFC 3161 au document de sortie)
- Données d’entrée : mappez depuis la sortie du déclencheur en utilisant les expressions n8n, par exemple
{{ $json.invoiceNumber }}pour le numéro de facture,{{ $json.seller.vatNumber }}pour le numéro de TVA du vendeur, et ainsi de suite pour chaque champ.
Dans la section Identifiants, sélectionnez ou créez un identifiant API SealDoc. Collez votre clé API dans le champ Secret.
Cliquez sur Exécuter le nœud pour tester. Si la clé API est valide et que les données de facture sont complètes, vous recevrez une réponse comme :
{
"jobId": "job_9kxQr2mPLv",
"status": "pending",
"estimatedSeconds": 4
}
La tâche a été mise en file d’attente. L’API SealDoc la traite de manière asynchrone afin qu’un rendu PDF lent ne bloque pas l’exécution de votre flux de travail.
Étape 3 : ajouter le nœud Job.Get avec polling
Ajoutez un deuxième nœud SealDoc. Définissez :
- Ressource : Job
- Opération : Get
- ID de tâche :
{{ $node["SealDoc Invoice Generate"].json.jobId }}
Encapsulez ce nœud dans le nœud Wait de n8n défini sur un intervalle de 3 secondes, avec une boucle qui vérifie si status est égal à completed ou failed. La plupart des factures se terminent en moins de 5 secondes. Définissez le nombre maximum d’itérations à 10 pour éviter une boucle infinie sur une tâche véritablement bloquée.
Lorsque status est completed, la réponse de Job.Get inclut :
downloadUrl: une URL limitée dans le temps (valide 10 minutes) pointant vers le document PDF/A-3 généré.evidencePackUrl: une archive ZIP contenant les entrées originales, le PDF/A-3 de sortie, le XML Factur-X intégré, le jeton d’horodatage RFC 3161 et un fichier de hachage manifeste. C’est ce que vous remettez à un auditeur.facturXProfile: le profil réellement utilisé (confirme EN 16931 ou EXTENDED).timestampedAt: l’horodatage UTC du jeton RFC 3161, qui est le moment de création juridiquement significatif.
Si status est failed, vérifiez le champ failureReason. Les valeurs courantes sont validation_failed (un champ requis était absent de votre entrée), unsupported_currency (SealDoc prend en charge EUR, USD, GBP, CHF, PLN, CZK et une liste croissante) et quota_exceeded (votre limite mensuelle de tâches est atteinte).
Étape 4 : stocker le résultat
Ajoutez le nœud de stockage qui correspond à votre pile. Options courantes :
- Nœud HTTP Request pour PUT le fichier vers votre propre système de gestion documentaire ou bucket MinIO.
- Nœud Google Drive ou Dropbox si vous utilisez le stockage en nuage pour votre archive.
- Nœud FTP/SFTP pour le stockage sur site.
- Move Binary Data plus Write Binary File si n8n est auto-hébergé et que vous souhaitez écrire directement dans un chemin de système de fichiers.
Utilisez le downloadUrl de la réponse Job.Get pour récupérer le fichier binaire, puis passez-le à votre nœud de stockage. Stockez également séparément evidencePackUrl si votre politique de conservation le requiert, ce qui devrait être le cas pour les factures au-dessus d’une certaine valeur ou dans des industries réglementées.
Ce que vous obtenez en sortie
Le fichier généré est un document PDF/A-3B. L’ouvrir dans n’importe quel lecteur PDF affiche une facture rendue. La pièce jointe intégrée factur-x.xml contient le XML CII complet, lisible par les logiciels de comptabilité qui prennent en charge l’import Factur-X ou ZUGFeRD. L’horodatage RFC 3161 est intégré dans le dictionnaire d’informations du document PDF et est vérifiable de manière indépendante.
Si vous faites passer la sortie par un validateur (notre outil Validateur gratuit accepte le fichier directement), vous verrez un résultat positif pour la conformité PDF/A-3B, la validité de schéma EN 16931 et la présence de la pièce jointe Factur-X.
Étapes suivantes
Ce tutoriel couvre le flux de génération principal. L’API SealDoc prend également en charge :
- Recherche Peppol : avant de générer une facture, vérifiez si l’acheteur est joignable sur Peppol via la ressource Peppol dans le nœud SealDoc.
- Validation uniquement : soumettez un fichier Factur-X ou XRechnung existant pour la validation de schéma sans générer un nouveau document.
- Génération par lots : soumettez plusieurs charges utiles de factures dans un seul appel API pour des scénarios à volume élevé.
La documentation complète de l’API se trouve sur notre page développeurs, avec la spécification OpenAPI et des exemples curl prêts à copier pour chaque point de terminaison.