← Retour aux articles
outils 14 août 2026 13 min de lecture

API facturation électronique : générer du Factur-X conforme

Intégrer la facture électronique par API : Factur-X, CII et UBL, cycle de vie, webhooks, idempotence et sandbox. Guide pour développeurs et intégrateurs.

Intégration par API de la facturation électronique Factur-X CII UBL

Facturino

Factures électroniques conformes : app, interface et API

L’échéance du 1er septembre 2026 ne concerne pas que les services comptables. Pour tout éditeur de SaaS, place de marché, ERP métier ou application de gestion qui émet des factures au nom de ses utilisateurs, la réforme impose une question technique concrète : comment produire et transmettre des factures électroniques conformes sans réécrire son back-office ?

La réponse passe par une API de facturation électronique. Plutôt que d’implémenter soi-même la génération de XML CII, l’embarquement PDF/A-3, la connexion à une plateforme agréée et le suivi des statuts du cycle de vie, on délègue à un service qui expose ces opérations en REST.

Cet article détaille ce qu’une telle API doit couvrir, le cycle de vie d’une facture vu du code, les garde-fous techniques indispensables (idempotence, webhooks, sandbox, versioning), et donne un exemple d’intégration de bout en bout.

#Pourquoi une API plutôt qu’une interface

Trois situations rendent l’intégration programmatique nécessaire :

SituationBesoin
SaaS B2B facturant ses clientsFacturation automatique à chaque cycle d’abonnement
Place de marché / plateformeFacturation au nom de vendeurs tiers, en volume
ERP ou logiciel métierAjout d’un module conforme sans refonte du produit
Cabinet ou intégrateurIndustrialisation pour un portefeuille de clients

Dans tous ces cas, la saisie manuelle est exclue : la facture est un effet de bord d’un événement métier (une commande validée, un abonnement renouvelé, une prestation terminée).

#Ce qu’une API de facturation électronique doit couvrir

Une API réellement utilisable pour la réforme française doit adresser six domaines. Si l’un manque, la conformité reste incomplète.

DomaineCe qui est attendu
Génération multi-formatFactur-X (PDF/A-3 + XML), CII et UBL, sans ré-implémentation côté client
Cycle de vieBrouillon, finalisation, numérotation, envoi, statuts remontés
Connexion à une plateforme agrééeTransmission réelle sur le réseau, pas seulement un fichier
E-reportingDéclaration des opérations B2C, internationales et des encaissements
IntégritéNumérotation continue, chaînage, piste d’audit fiable
ÉvénementielWebhooks pour les changements de statut asynchrones

#Le point souvent négligé : la piste d’audit fiable

L’article 289 VII du code général des impôts impose de garantir l’authenticité de l’origine, l’intégrité du contenu et la lisibilité de la facture. En pratique, l’API doit exposer :

  • une numérotation séquentielle sans rupture, attribuée à la finalisation (pas à la création) ;
  • un chaînage cryptographique vérifiable entre factures successives ;
  • un journal d’événements horodaté et non modifiable ;
  • un export de la piste d’audit présentable en contrôle fiscal.

Une API qui se contente de générer un XML valide ne couvre pas ces obligations.

#Le cycle de vie d’une facture, vu du code

La logique est proche de celle des API de paiement : un objet mutable tant qu’il est brouillon, puis immuable après finalisation.

POST   /v1/invoices              → brouillon (modifiable, sans numéro)
PATCH  /v1/invoices/:id          → modification du brouillon
POST   /v1/invoices/:id/finalize → numéro attribué, objet figé
POST   /v1/invoices/:id/send     → transmission via la plateforme agréée
GET    /v1/invoices/:id/status   → statut du cycle de vie
GET    /v1/invoices/:id/facturx  → récupération du fichier conforme

#Pourquoi séparer création et finalisation

C’est la distinction structurante de toute API de facturation sérieuse :

ÉtapeÉtatNuméroModifiable
POST /v1/invoicesBrouillonNon attribuéOui
POST .../finalizeÉmiseAttribué définitivementNon
POST .../sendTransmiseInchangéNon

Attribuer un numéro dès la création casserait la séquence continue exigée par l’administration en cas d’abandon d’un brouillon. La finalisation est donc le point de non-retour : après elle, seule l’émission d’un avoir permet de corriger.

#Les statuts remontés par la plateforme agréée

Après l’envoi, le statut évolue de façon asynchrone au fil des accusés remontés par la PA et le destinataire : déposée, reçue, mise à disposition, prise en charge, approuvée, en litige, refusée, encaissée… Ces transitions ne sont pas maîtrisées par l’émetteur — d’où l’importance des webhooks plutôt que du polling.

#Exemple : de zéro à une facture conforme

Voici un parcours complet en six appels, sur un socle REST classique. L’authentification se fait par clé d’API en Bearer, avec des clés distinctes pour le test et la production.

#1. Créer le client

curl -X POST https://facturino.com/api/v1/customers \
  -H "Authorization: Bearer fac_test_..." \
  -H "Idempotency-Key: customer-acme-2026" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ACME SAS",
    "siret": "38412987400034",
    "vat_number": "FR40384129874",
    "email": "compta@acme.fr"
  }'

Le SIREN du client est désormais une mention obligatoire sur la facture : il doit être présent et valide dès la création du client.

#2. Créer la facture en brouillon

curl -X POST https://facturino.com/api/v1/invoices \
  -H "Authorization: Bearer fac_test_..." \
  -H "Idempotency-Key: invoice-order-8421" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_9f3k2m1p",
    "lines": [
      { "description": "Abonnement Pro — août 2026",
        "quantity": 1, "unit_price": 29000, "vat_rate": 20 }
    ],
    "due_date": "2026-09-13"
  }'

Les montants sont exprimés en centimes entiers — jamais en flottants. C’est une convention universelle des API de facturation et de paiement : 29000 = 290,00 €.

#3. Finaliser

curl -X POST https://facturino.com/api/v1/invoices/inv_3p7r2x5q/finalize \
  -H "Authorization: Bearer fac_test_..."

La réponse contient le numéro définitif (FAC2026-00001) et l’empreinte de chaînage. À partir d’ici, l’objet est figé.

#4. Transmettre via la plateforme agréée

curl -X POST https://facturino.com/api/v1/invoices/inv_3p7r2x5q/send \
  -H "Authorization: Bearer fac_test_..."

#5. Suivre le statut

curl https://facturino.com/api/v1/invoices/inv_3p7r2x5q/status \
  -H "Authorization: Bearer fac_test_..."

À réserver au diagnostic : en production, on écoute plutôt les webhooks.

#6. Récupérer le fichier conforme

curl https://facturino.com/api/v1/invoices/inv_3p7r2x5q/facturx \
  -H "Authorization: Bearer fac_test_..."
# → { "object": "file_url", "url": "https://…", "expires_in": 900 }

L’endpoint renvoie une URL signée à durée limitée, pas le binaire : le téléchargement ne passe pas par l’API, ce qui évite de saturer les quotas de requêtes.

Les mêmes ressources existent en /xml (CII ou UBL brut) et /pdf (rendu lisible).

#Les garde-fous techniques

#Idempotence

Sans idempotence, un timeout réseau suivi d’un retry crée une facture en double — problème sérieux quand la numérotation est censée être continue.

Idempotency-Key: invoice-order-8421

Le serveur mémorise la réponse associée à la clé (typiquement 24 h) : rejouer la même requête renvoie exactement la même réponse, sans créer de second objet. Dérivez la clé d’un identifiant métier stable (numéro de commande, id d’abonnement), jamais d’un UUID régénéré à chaque tentative.

#Webhooks

Les statuts du cycle de vie arrivent de façon asynchrone, parfois plusieurs jours après l’envoi. Le polling est coûteux et lent : il faut des webhooks.

Bonne pratiqueRaison
Vérifier la signature de chaque payloadEmpêcher l’injection d’événements falsifiés
Répondre 2xx immédiatement, traiter en asynchroneÉviter les timeouts et les redélivrances inutiles
Traiter les événements de façon idempotenteLes redélivrances sont normales, pas exceptionnelles
Ignorer les événements plus anciens que l’état connuL’ordre d’arrivée n’est pas garanti
Prévoir une relance manuelle des événementsRattraper une indisponibilité de son propre endpoint

#Limites de débit

Les en-têtes standard permettent de piloter la charge sans deviner :

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1709891260

Sur dépassement, l’API répond 429 : implémentez un backoff exponentiel en vous appuyant sur X-RateLimit-Reset plutôt qu’une temporisation fixe.

#Sandbox

Une facture réellement transmise à une plateforme agréée ne peut pas être annulée. Un environnement de test isolé est donc indispensable, avec :

  • des clés dédiées (fac_test_… vs fac_live_…) impossibles à confondre ;
  • la possibilité de simuler des transitions de statut (approuvée, refusée, en litige) sans attendre un partenaire réel ;
  • une remise à zéro du jeu de données entre deux campagnes de tests.

#Versioning

Le contrat d’API doit être daté et figé : une version épinglée côté client (par exemple 2026-03-01, renvoyée dans un en-tête de réponse) garantit qu’une évolution du service ne casse pas une intégration en production. Les changements incompatibles arrivent alors dans une nouvelle version, adoptée explicitement.

#SDKs : ne pas réécrire la plomberie

Une API REST bien conçue s’utilise en curl, mais un SDK officiel évite de réimplémenter la signature des webhooks, la pagination par curseur, la gestion des retries et le typage des objets.

LangageInstallation
Node.jsnpm install @facturino/node
Pythonpip install facturino
PHPcomposer require facturino/facturino-php
Gogo get github.com/facturino/facturino-go

Le même parcours en Node.js tient en quelques lignes :

import Facturino from '@facturino/node'

const facturino = new Facturino(process.env.FACTURINO_API_KEY)

const invoice = await facturino.invoices.create({
  customer_id: 'cus_9f3k2m1p',
  lines: [{ description: 'Abonnement Pro — août 2026',
            quantity: 1, unit_price: 29000, vat_rate: 20 }],
}, { idempotencyKey: 'invoice-order-8421' })

await facturino.invoices.finalize(invoice.id)
await facturino.invoices.send(invoice.id)

Pour démarrer, Facturino publie une documentation développeurs, une référence API interactive, une spécification OpenAPI 3.1 et un dépôt de démos contenant cinq applications complètes exécutant le même scénario SaaS B2B — une par stack (Node, Python, PHP, Go) plus une version sans SDK, en HTTP brut.

#Le modèle BYOPA : ne pas s’enfermer chez une plateforme

Un point d’architecture souvent sous-estimé : la plateforme agréée par laquelle transitent vos factures et l’outil qui les génère ne sont pas nécessairement le même prestataire.

ModèleConséquence
Tout-en-un chez une PAChanger de PA = migrer toute la facturation et l’historique
Solution compatible + PA au choix (BYOPA)Changer de PA = reconfigurer un connecteur

Le modèle BYOPA (bring your own PA) laisse le choix de la plateforme agréée à l’utilisateur final — ce qui compte particulièrement pour un éditeur dont les clients ont déjà, chacun, leur propre PA. Facturino applique ce modèle avec des connecteurs pour Super PDP, Iopole, B2Brouter et Seqino, plus un connecteur générique conforme à la norme AFNOR XP Z12-013 pour toute autre plateforme agréée. Le dépôt manuel (téléchargement du Factur-X puis dépôt sur la PA) reste possible, y compris sur le plan gratuit.

Rappel important : Facturino est une solution compatible (SC), pas une plateforme agréée. La distinction est détaillée dans notre article sur la réception obligatoire au 1er septembre 2026.

#Ne pas oublier l’e-reporting

Les ventes aux particuliers, les opérations avec l’étranger et les données d’encaissement ne passent pas par le circuit de facturation : elles relèvent de l’e-reporting, qui doit lui aussi être automatisé.

POST /v1/ereporting/declarations             → constituer une déclaration
POST /v1/ereporting/declarations/:id/submit  → transmettre à l'administration

Une intégration qui ne couvre que l’émission de factures B2B laisse donc un angle mort — avec une sanction propre de 250 € par transmission manquante, plafonnée à 15 000 € par an.

#Combien de temps pour intégrer ?

Ordres de grandeur pour une équipe disposant déjà d’un modèle de données clients/produits :

ÉtapeCharge indicative
Prise en main, clés de test, premier appel1 à 2 h
Parcours complet client → facture → envoiUne demi-journée
Webhooks + gestion des statuts1 jour
E-reporting0,5 à 1 jour
Recette en sandbox et bascule en production1 à 2 jours

Le poste le plus sous-estimé n’est pas l’appel HTTP : c’est la réconciliation des statuts avec votre modèle métier (une facture « refusée » doit déclencher quoi, côté produit ?) et la gestion des avoirs, seule voie de correction après finalisation.

#FAQ : intégrer la facturation électronique par API

#Faut-il être une plateforme agréée pour émettre par API ?

Non. Vous pouvez utiliser une solution compatible qui génère des factures conformes et les transmet à une plateforme agréée immatriculée par la DGFiP. Seule la transmission sur le réseau requiert le statut de PA.

#Peut-on générer du Factur-X sans API dédiée ?

Techniquement oui — le format est ouvert. En pratique, il faut produire un PDF/A-3 valide, y embarquer un XML CII conforme au profil retenu, gérer la numérotation continue, le chaînage et la piste d’audit, puis maintenir tout cela au rythme des évolutions réglementaires. C’est un projet à part entière, rarement rentable face à une API.

#Quelle différence entre Factur-X, CII et UBL ?

CII et UBL sont deux syntaxes XML normalisées. Factur-X est un format hybride : un PDF/A-3 lisible par un humain, avec un XML CII embarqué. En France, Factur-X est le plus répandu car il ne demande aucun changement d’habitude côté destinataire.

#Comment tester sans envoyer de vraies factures ?

Via un environnement sandbox avec des clés de test distinctes, la simulation des transitions de statut et une remise à zéro du jeu de données. Une facture transmise en production ne peut être corrigée que par un avoir.

#Comment éviter les doublons en cas de retry ?

Avec l’en-tête Idempotency-Key sur les requêtes POST, dérivé d’un identifiant métier stable. Rejouer la même requête renvoie la réponse d’origine sans créer de second objet.

#Faut-il faire du polling pour connaître le statut ?

Non. Les transitions étant asynchrones et parfois différées de plusieurs jours, les webhooks signés sont la bonne approche. Le polling doit rester un outil de diagnostic.

#Récapitulatif

#Les 6 points de contrôle d’une intégration

  1. Séparer brouillon et finalisation — le numéro n’est attribué qu’à la finalisation
  2. Montants en centimes entiers — jamais de flottants
  3. Idempotence sur tous les POST — clé dérivée d’un identifiant métier
  4. Webhooks signés et idempotents — pas de polling en production
  5. Sandbox avant production — clés distinctes, simulation de statuts
  6. E-reporting couvert — B2C, international et encaissements

#Les échéances

DateObligation
1er septembre 2026Réception pour toutes les entreprises ; émission et e-reporting pour les GE et ETI
1er septembre 2027Émission et e-reporting pour les PME, TPE et micro-entreprises

#Conclusion

Intégrer la facturation électronique par API revient à traiter la facture comme un objet de cycle de vie — mutable puis immuable, avec des transitions asynchrones — plutôt que comme un document à générer. Les API de paiement ont popularisé ce modèle : idempotence, webhooks signés, sandbox, versioning daté. Ce sont exactement les mêmes garde-fous qui font la différence entre une intégration qui tient en production et une qui produit des doublons de numérotation au premier incident réseau.

Le choix d’architecture le plus structurant reste le découplage entre l’outil de génération et la plateforme agréée : il conditionne votre capacité à changer de PA — ou à laisser vos clients utiliser la leur — sans reprendre l’intégration.

Pour démarrer, Facturino expose une API REST en /v1, quatre SDKs officiels (Node, Python, PHP, Go), une sandbox complète et un dépôt de démos exécutables. Le plan gratuit inclut 1 000 appels par mois — assez pour prototyper une intégration complète avant l’échéance de septembre.

Sources officielles : impots.gouv.fr — Facturation électronique et plateformes agréées · economie.gouv.fr — Facturation électronique · article 289 VII du code général des impôts (piste d’audit fiable) · Documentation développeurs Facturino

QuickDSN

DSN gratuite et illimitée

Articles similaires
outils

BrutNet : simulateur gratuit de calcul salaire brut/net

Découvrez BrutNet, le calculateur gratuit de salaire brut/net français. Données URSSAF officielles, 8 statuts, comparateur multi-profils, mode expert avec exonérations. 100% gratuit et open source.

15 janv. 2025 — 7 min de lecture
outils

Facturino : logiciel de facturation électronique conforme

Facturino : émettez et recevez vos factures électroniques conformes (Factur-X, UBL, CII). App, interface web et API REST, avec la plateforme agréée de votre choix.

14 août 2026 — 11 min de lecture