Logo FactPulse

De la conformité en 3 jours : Comment un éditeur a intégré la facture électronique sans réécrire son logiciel

Guide technique d'intégration — Janvier 2026


TL;DR — Un éditeur de logiciel de gestion a rendu son application conforme à la réforme de la facturation électronique 2026 en 3 jours de développement, sans toucher à son architecture existante.

Mots-clés : intégration Factur-X, SDK facturation électronique, API e-invoicing Python, conformité 2026, Solution Compatible


Le défi : 400+ règles métier à implémenter

La transition vers la facturation électronique (norme EN 16931 / Factur-X) représente un défi majeur pour les éditeurs de logiciels. Il ne s'agit plus de générer un simple PDF, mais de produire un fichier structuré conforme à des centaines de règles de validation — mentions légales françaises (BR-FR), structure XML CII, calculs de TVA normalisés, conformité PDF/A-3 (archivage longue durée), et communication sécurisée avec les plateformes agréées (PA/PDP)...

Deux options s'offraient à cet éditeur :

  1. Développer en interne : 3 à 6 mois d'effort, maintenance continue des normes
  2. Déléguer la complexité : intégrer une API spécialisée

Cet article détaille comment l'intégration de FactPulse a permis de transformer ce projet complexe en un développement Python standard et maintenable.

Étape 1 — Adapter le modèle de données (30 minutes)

La première étape consiste à enrichir le modèle existant avec quelques champs requis par la réglementation française (règles BR-FR).

Seulement 5 champs à ajouter :

  • 3 mentions légales obligatoires (frais de recouvrement, pénalités, escompte)
  • 2 champs JSON pour le suivi des échanges avec l'API

Snippet d'adaptation (Django models) :

# models.py

class Facture(models.Model):
    # ... champs existants (montant_ht, date, etc.) ...

    # Mentions légales obligatoires (BR-FR-05)
    mention_frais_recouvrement = models.CharField(
        max_length=1024, blank=True, default="",
        help_text="Mention obligatoire : Indemnité forfaitaire pour frais de recouvrement"
    )
    mention_penalites_retard = models.CharField(
        max_length=1024, blank=True, default="",
        help_text="Mention obligatoire : Pénalités en cas de retard de paiement"
    )
    mention_escompte = models.CharField(
        max_length=1024, blank=True, default="",
        help_text="Mention obligatoire : Escompte pour paiement anticipé ou son absence"
    )

    # Stockage des retours API pour le suivi
    erreurs_validation_facturx = models.JSONField(
        default=list,
        help_text="Stocke les messages d'erreur lors de la validation du XML"
    )
    reponse_plateforme_agreee = models.JSONField(
        default=dict,
        help_text="Stocke la réponse complète (Flow ID, Tracking ID) lors de la soumission"
    )

Étape 2 — Mapper les données métier (1 heure)

C'est ici que la valeur de l'API se révèle. Le SDK FactPulse est un wrapper HTTP minimaliste qui appelle directement les endpoints API. L'API fait le travail lourd : validation, enrichissement automatique depuis le SIRET, génération PDF/A-3, et soumission aux plateformes.

Format simplifié avec auto-enrichissement — Fournissez seulement le SIRET et l'IBAN. L'API récupère automatiquement la raison sociale, l'adresse, le numéro de TVA intracommunautaire.

Snippet d'initialisation de la facture :

# methods_facturx.py

def build_invoice_payload(facture: Facture) -> dict:
    """Transform internal business object into FactPulse API payload."""

    return {
        "number": facture.numero_facture,
        "invoiceDate": facture.date_emission.isoformat(),
        "paymentDueDate": facture.date_echeance.isoformat(),

        # Format simplifié : SIRET + IBAN suffisent
        # L'API enrichit automatiquement (raison sociale, adresse, TVA)
        "supplier": {
            "siret": facture.fournisseur.siret,
            "iban": facture.fournisseur.iban,
            "routingAddress": facture.fournisseur.siret,  # Adresse électronique
        },
        "recipient": {
            "siret": facture.destinataire.siret,
            "routingAddress": facture.destinataire.siret,
        },

        # Lignes de facture
        "lines": _build_invoice_lines(facture),

        # Mentions légales obligatoires (BR-FR)
        "notes": [
            {"subjectCode": "PMT", "content": facture.mention_frais_recouvrement},
            {"subjectCode": "PMD", "content": facture.mention_penalites_retard},
            {"subjectCode": "AAB", "content": facture.mention_escompte},
        ],
    }

Étape 3 — Détailler les lignes (45 minutes)

Factur-X exige un détail précis de chaque ligne (biens/services). Le mapping est direct : les noms de champs correspondent à l'API.

def _build_invoice_lines(facture):
    """Map internal invoice lines to API format."""
    lines = []
    for ligne in facture.lignes.all():
        lines.append({
            "description": ligne.libelle,
            "quantity": float(ligne.quantite),
            "unitPrice": float(ligne.prix_unitaire),
            "vatRate": float(ligne.taux_tva),  # e.g., 20.0
        })
    return lines

Note : Avec autoEnrich=True (par défaut), l'API calcule automatiquement les totaux HT, TVA et TTC à partir des lignes. Pas besoin de les calculer côté client.

Étape 4 — Générer, valider et soumettre en un seul appel (30 minutes)

L'appel à l'API génère le PDF/A-3 conforme, valide en temps réel toutes les règles métier, et soumet directement à la plateforme. Le SDK gère automatiquement le polling des tâches asynchrones.

import base64
from factpulse_helpers import FactPulseClient, FactPulseError

def generate_and_submit_facturx(facture, pdf_original_bytes):
    """Generate Factur-X PDF and submit to PDP in one call."""

    client = FactPulseClient(
        email="api@votre-editeur.fr",
        password="votre-mot-de-passe",
        client_uid="uuid-de-votre-client",  # Credentials PDP configurés dans le Dashboard
    )

    try:
        payload = build_invoice_payload(facture)

        # Un seul appel : génération + validation + soumission PDP
        result = client.post(
            "processing/invoices/submit-complete-async",
            invoiceData=payload,
            sourcePdf=base64.b64encode(pdf_original_bytes).decode(),
            profile="EN16931",
            destination={"type": "afnor"},
        )

        # Le PDF Factur-X est dans result["content"] (auto-décodé)
        pdf_facturx = result["content"]

        # Sauvegarder la preuve de soumission
        facture.reponse_plateforme_agreee = {
            "success": True,
            "flowId": result.get("afnorResult", {}).get("flowId"),
            "validation": result.get("validation", {}),
        }
        facture.erreurs_validation_facturx = []
        facture.save()

        return pdf_facturx

    except FactPulseError as e:
        # Stocker les erreurs structurées pour l'affichage UI
        facture.erreurs_validation_facturx = e.details or [str(e)]
        facture.save()
        raise ValueError(f"Facture non conforme : {e}")

Ce qui se passe en coulisses :

  1. L'API valide les données selon 400+ règles Schematron
  2. L'API enrichit automatiquement depuis les bases officielles (Chorus Pro, INSEE)
  3. L'API génère le XML CII conforme EN 16931
  4. L'API convertit en PDF/A-3 avec XML embarqué
  5. L'API soumet au PDP et retourne le Flow ID
  6. Le SDK poll automatiquement jusqu'à complétion (si async)

Bilan : 3 jours au lieu de 3 mois

Métrique Sans API Avec FactPulse
Temps d'intégration 3-6 mois 3 jours
Lignes de code ~5 000 (XML, validation) ~100 (mapping métier)
Maintenance des normes Continue Déléguée
Risque de rejet plateforme Élevé Quasi nul

Ce que l'équipe a retenu

  • Un seul appel API — Génération, validation et soumission en une opération
  • Format simplifié — SIRET + IBAN suffisent, l'API enrichit automatiquement
  • Validation synchrone — Les erreurs sont détectées immédiatement, pas 48h plus tard par la plateforme
  • Traçabilité native — Chaque échange est journalisé (erreurs, accusés de réception, Flow ID)
  • Code maintenable — Du Python idiomatique, pas de manipulation XML

Prêt à intégrer ?

FactPulse propose un sandbox gratuit pour tester l'intégration avec vos propres données. Générez vos premières factures Factur-X en quelques minutes.

Essayer gratuitement le sandbox | Documentation API (Scalar)


Pour aller plus loin


Article mis à jour le 18 janvier 2026

Sources : DGFiP (impots.gouv.fr), AFNOR (normes XP Z12-012/013/014), FNFE-MPE (factur-x.org)