Intégrer l'API de facturation en 1 après-midi
Développer la facturation électronique en interne, c'est entre 3 et 6 mois de travail et un budget de 50 000 à 150 000 EUR : parsing XML CII/UBL, génération PDF/A-3, validation Schematron, connexion aux Plateformes Agréées, gestion des 14 statuts DGFiP... Avec l'API Facturino, vous intégrez tout cela en une après-midi.
Ce guide vous accompagne étape par étape, du premier appel API jusqu'à l'envoi de votre première facture conforme via une Plateforme Agréée.
Étape 1 : obtenir votre clé API
À la création de votre compte Facturino, vous recevez automatiquement une clé de test préfixée fac_test_. Cette clé vous donne accès au sandbox : aucune facture n'est réellement envoyée, aucun email n'est émis, aucune donnée ne transite vers une PA.
Lorsque vous êtes prêt pour la production, générez une clé live préfixée fac_live_ depuis vos paramètres. Les deux environnements sont strictement isolés : une clé test ne peut jamais lire les données de production, et inversement.
// Authentification : header Authorization
const headers = {
'Authorization': 'Bearer fac_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Content-Type': 'application/json'
}; Étape 2 : créer un client
Avant de facturer, il faut un destinataire. Pour pré-remplir les informations légales à partir d'un SIRET (raison sociale, adresse, numéro de TVA intracommunautaire via l'API Sirene de l'INSEE), utilisez d'abord POST /v1/customers/lookup, puis créez le client avec POST /v1/customers (le champ name est requis).
const response = await fetch('https://facturino.com/api/v1/customers', {
method: 'POST',
headers,
body: JSON.stringify({
type: 'company',
name: 'Acme SAS',
siret: '00012345500008',
email: 'comptabilite@acme.fr',
address: {
line1: '15 rue de la Paix',
city: 'Paris',
postalCode: '75002',
country: 'FR'
}
})
});
const customer = await response.json();
// customer.id → "cus_a1b2c3d4e5f6..." Étape 3 : obtenir la décision fiscale
Décrivez l'opération à POST /v1/tax-decisions : Facturino arrête la TVA
française, les montants de la facture et ses axes de transmission. Cette étape précède la
finalisation du document et, lorsqu'un règlement est perçu immédiatement, son encaissement.
Les montants sont des centimes entiers et les quantités des chaînes décimales.
taxSource déclare qui détermine la TVA. Ici facturino : vous
décrivez l'opération et Facturino conclut le taux. Si votre système le détermine déjà,
integration suit exactement les mêmes étapes — voir
Décisions fiscales.
const decision = await fetch('https://facturino.com/api/v1/tax-decisions', {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': 'operation-order-4711' },
body: JSON.stringify({
taxSource: 'facturino',
customerId: customer.id,
effectiveAt: '2026-09-15',
currency: 'eur',
priceMode: 'tax_exclusive',
lines: [{
reference: 'abo-pro',
description: 'Abonnement Pro',
category: 'electronically_supplied_services',
rateCategory: 'standard',
unitAmount: 2900,
quantity: '1'
}]
})
}).then(r => r.json());
if (decision.status !== 'final') {
// Demander les preuves indiquées dans decision.issues. Ne rien finaliser.
throw new Error('Décision fiscale non finale');
}
// decision.id devient la référence commune de la facture et de son règlement.
Facturino n'impose aucun moyen de paiement : carte, virement, prélèvement, chèque,
espèces, portefeuille ou prestataire externe peuvent alimenter le même cycle. Si vous
encaissez avant d'émettre la facture, relisez la décision et comparez
montant, devise et acheteur. Les deux parcours et les reprises VIES sont
documentés dans Décisions fiscales. Un statut
pending_verification ne signifie jamais « montant nul ».
Étape 4 : créer la facture adossée
La facture réutilise la décision : elle ne reçoit ni taux ni code TVA. Un
taxLineRef relie chaque ligne de présentation à la ligne fiscale figée.
const invoice = await fetch('https://facturino.com/api/v1/invoices', {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': 'invoice-order-4711' },
body: JSON.stringify({
customerId: decision.customerId,
taxDecisionId: decision.id,
buyer: {
companyName: 'Acme SAS',
siret: '00012345500008',
address: {
line1: '15 rue de la Paix',
city: 'Paris',
postalCode: '75002',
country: 'FR'
}
},
dates: { issued: '2026-04-07', due: '2026-05-07' },
payment: {
terms: 'Paiement à 30 jours',
termsDays: 30,
method: 'transfer',
latePaymentRate: '10.00',
collectionFee: '40.00'
},
decisionLines: [{ taxLineRef: 'abo-pro', unit: 'month' }],
notes: 'Merci pour votre confiance.'
})
}).then(r => r.json());
// invoice.id → "inv_x9y8z7w6v5u4..."
// invoice.status → "draft" Étape 5 : finaliser la facture
La finalisation est le moment clé. Facturino attribue un numéro séquentiel (transaction atomique, pas de trou de numérotation), valide tous les champs obligatoires et génère automatiquement le Factur-X : un PDF/A-3b contenant le XML CII conforme EN16931 et CIUS-FR.
const finalized = await fetch(
`https://facturino.com/api/v1/invoices/${invoice.id}/finalize`,
{ method: 'POST', headers }
).then(r => r.json());
// finalized.status → "finalized"
// finalized.documentStatus → "finalized"
// finalized.transmissionStatus → "pending" ou "not_applicable"
// finalized.paymentStatus → "unpaid"
// finalized.number → "FAC-2026-0042"
// Le PDF/A-3b + XML CII est généré automatiquement Vous avez encaissé avant d'émettre (paiement en ligne, au comptoir) ? Ne
finalisez pas puis n'enregistrez pas le paiement en deux appels : passez
l'encaissement dans la finalisation. Numéro, finalisation et paiement sont écrits
dans la même transaction, et l'original (PDF et Factur-X) est rendu sur une facture
réglée. Le même objet que POST /v1/invoices/:id/payments, en centimes.
const issued = await fetch(
`https://facturino.com/api/v1/invoices/${invoice.id}/finalize`,
{
method: 'POST',
headers,
body: JSON.stringify({
payment: { amount: 120000, method: 'card', reference: 'ch_3Kj9aLZ', paidAt: '2026-09-15T10:12:00.000Z' }
})
}
).then(r => r.json());
// issued.status → "paid"
// issued.paymentStatus → "paid"
// issued.dates.paidAt → "2026-09-15T10:12:00.000Z"
// Un encaissement supérieur au montant dû est refusé (422) et la facture reste un brouillon. Une fois finalisée, la facture est immuable. Impossible de revenir au statut brouillon. Pour corriger une erreur, il faut émettre un avoir (credit note).
Étape 6 : envoyer via la Plateforme Agréée
N'appelez /send que si la décision porte
invoiceChannel: "einvoicing". Une PA connectée et l'autorisation de dépôt ne rendent
pas une opération éligible : l'API refuse notamment le B2C, l'étranger, la Guyane, Mayotte
et les collectivités d'outre-mer, dont l'obligation relève de l'e-reporting.
if (decision.invoiceChannel === 'einvoicing') {
const sent = await fetch(
`https://facturino.com/api/v1/invoices/${invoice.id}/send`,
{
method: 'POST',
headers: { ...headers, 'Idempotency-Key': `send-${invoice.id}` }
}
).then(r => r.json());
}
// Hors e-invoicing : ne pas déposer. Les axes d'e-reporting restent dus. En production, le dépôt réseau et l'e-reporting automatique sont deux activations explicites distinctes par établissement. Tant que l'e-reporting n'est pas activé, Facturino expose l'obligation mais ne transmet rien en votre nom.
Étape 7 : écouter les changements de statut
Plutôt que de faire du polling, configurez un webhook pour recevoir les événements en temps réel. Facturino signe chaque payload avec HMAC-SHA256 pour garantir l'authenticité.
// Votre endpoint reçoit les événements automatiquement
// POST https://votre-app.com/webhooks/facturino
// Payload reçu :
{
"id": "evt_abc123def456",
"object": "event",
"type": "invoice.available",
"apiVersion": "2026-09-01",
"created": "2026-04-07T15:30:00Z",
"livemode": true,
"data": {
"id": "inv_x9y8z7w6v5u4",
"object": "invoice",
"status": "available",
"previous_status": "transmitted",
"livemode": true
}
} Gestion des erreurs
L'API retourne des erreurs dans un format structuré, avec des informations précises pour faciliter le débogage :
// Exemple d'erreur 422
{
"error": {
"type": "validation_error",
"code": "missing_required_field",
"message": "Le champ 'customerId' est requis.",
"param": "customerId",
"doc_url": "https://facturino.com/docs/api#invoices",
"request_id": "req_abc123",
"hint": "Créez d'abord un client avec POST /v1/customers"
}
} Conventions essentielles de l'API
- Montants : toujours en centimes d'euro (entiers). 10000 = 100,00 EUR
- Taux TVA : en centièmes de pourcent. 2000 = 20,00 %, 550 = 5,50 %
- Pagination : cursor-based avec
starting_after, limit 25 par défaut (max 100) - Idempotence : header
Idempotency-Keypour éviter les doublons sur les requêtes POST - Modifications : PATCH (jamais PUT) pour les mises à jour partielles
- Timestamps : ISO 8601 en UTC
- IDs : préfixés par type —
inv_,cus_,quo_,crn_,pay_
Comparatif : combien coûte la facturation électronique ?
| Approche | Délai | Coût | Maintenance |
|---|---|---|---|
| Développement interne | 3-6 mois | 50 000 - 150 000 EUR | Équipe dédiée permanente |
| Connexion PA directe | 1-3 mois | 20 000 - 50 000 EUR | Suivi des évolutions PA |
| API Facturino | 1 après-midi | 0 - 29 EUR/mois | Suivi des versions API/SDK et des cas fiscaux signalés |
Prochaines étapes
Vous avez intégré les bases en 7 étapes. Pour aller plus loin :
- Webhooks avancés : configurez des endpoints pour chaque type d'événement (43 types disponibles)
- Avoirs : émettez des credit notes avec le même workflow (POST /v1/credit-notes)
- Devis : créez des devis convertibles en factures en un clic (POST /v1/quotes)
- E-reporting : activez-le explicitement par établissement, puis suivez les axes figés par chaque décision
- SDKs : utilisez nos bibliothèques Node.js, Python, PHP ou Go pour simplifier encore l'intégration
Le sandbox est gratuit et sans limite. Testez l'API en toute sécurité avec votre clé fac_test_, puis basculez en production quand vous êtes prêt.
Prêt à passer à la facturation électronique ?
Créez votre compte Facturino gratuitement et commencez à émettre des factures conformes en quelques minutes.