Technique

Données ERP vers Factur-X CII : guide de mapping JSON → XML EN16931

Mis à jour le 16 min de lecture Par FacturX API

Mapper les données d'un ERP (JSON/CSV) vers XML CII EN16931 pour Factur-X. Champs obligatoires, autoliquidation BTP (art. 283, 2 nonies CGI), avoirs, exemples curl et Python.

Comment mapper les données structurées de votre ERP (JSON/CSV/tables SQL) vers un Factur-X CII conforme EN16931 ? Via le champ invoice_data de l’endpoint /convert : vous fournissez un JSON déterministe (numéro, date ISO YYYY-MM-DD, seller/buyer avec vat_id, lignes avec vat_category ∈ S / Z / E / AE / K / G / O, totaux arithmétiquement cohérents), l’API génère un XML CII D22B et l’embarque dans un PDF/A-3. Ce guide couvre le mapping par Business Term (BT-*), les 3 cas chauds (autoliquidation BTP, avoirs, multi-taux TVA), et les erreurs à éviter.

En bref

  • Endpoint : POST /api/v1/convert avec invoice_data=<JSON> multipart field.
  • Modèle racine : invoice_number (BT-1), issue_date ISO YYYY-MM-DD (BT-2), invoice_type UNTDID 1001 (défaut 380), currency ISO 4217.
  • Parties : seller avec vat_id et/ou siret, buyer symétrique. L’API génère les identifiants CII avec les bons schemeID.
  • Lignes : number, description, quantity, unit, unit_price, net_amount, vat_rate, vat_category.
  • Totals : net = Σ nets de lignes − remises documentaires + charges documentaires ; tax = Σ ventilations TVA ; gross = net + tax ; due = gross − prepaid_amount + rounding_amount.
  • Format strict : dates ISO, décimaux avec point (pas virgule), locale ROOT.

Quand utiliser le mode invoice_data

SituationMode recommandé
ERP (Sage, SAP, Odoo, Dolibarr) avec export JSON ou mapping scriptableMode ERP — déterministe
Flux B2B industrialisé (PA, gros volumes)Mode ERP exclusivement — pas d’OCR en production
Numériser un stock de factures fournisseurs PDFMode extraction — voir Convertir PDF → Factur-X
Script ad-hoc sans ERPinvoice_data JSON construit à la main (voir exemples curl ci-dessous)
1 livrable final = 1 facture traitée

Un appel abouti à /validate, /extract ou /repair décompte une facture traitée. Une génération /convert réserve une facture, décomptée si un livrable final est produit et remboursée sinon. Une simulation /convert avec dry_run=true ne consomme pas le quota et ne produit aucun fichier final.

Votre ERP contient déjà toutes les données de la facture. Le numéro, la date, les montants, les identifiants fiscaux, les lignes de détail — tout est là, structuré dans des tables ou des objets métier. Le défi n’est pas de trouver les données. C’est de les mapper vers le modèle sémantique EN16931 attendu par le XML CII, avec les bons codes, les bons formats et les bonnes cardinalités.

Ce guide montre comment structurer les données ERP en JSON pour générer un Factur-X conforme via l’API, en mode invoice_data. Il couvre le modèle de données, les transformations nécessaires, et les cas spéciaux qui posent problème en pratique — autoliquidation BTP, avoirs, multi-taux TVA.

Ce billet approfondit le mapping champ par champ. Le flux d’intégration de référence — exemples curl, champs invoice_data acceptés, sorties output=xml_cii / output=facturx_pdfa3, erreurs et FAQ — est documenté dans le guide d’intégration /convert avec JSON ERP : commencez par lui pour câbler votre premier appel. Pour le contexte général de la conversion PDF vers Factur-X (les deux modes, la validation intégrée, les quotas), voir Convertir une facture PDF en Factur-X 1.08 contrôlé. Pour la cartographie complète des Business Terms EN16931, voir Champs obligatoires EN16931 : cartographie et mapping ERP.

Le modèle de données invoice_data

L’API Convert en mode ERP attend un champ invoice_data contenant un objet JSON. Cet objet est la représentation structurée de la facture — l’API le transforme en XML CII D22B conforme et l’embarque dans le PDF/A-3.

Champs racine

Champ JSONBT EN16931TypeObligatoireDescription
invoice_numberBT-1stringouiNuméro de facture
issue_dateBT-2stringouiDate d’émission ISO YYYY-MM-DD
invoice_typeBT-3stringnon (défaut 380)Type de document UNTDID 1001
currencyBT-5stringouiCode devise ISO 4217

Le contrat invoice_data accepte 380 (facture), 381 (avoir) et 384 (facture corrective). L’existence d’autres codes dans UNTDID 1001 ne signifie pas qu’ils sont acceptés par cet endpoint.

Bloc seller

{
  "seller": {
    "name": "Dupont BTP SAS",
    "vat_id": "FR32123456789",
    "siret": "12345678901234",
    "address": {
      "street": "45 Avenue des Chantiers",
      "city": "Lyon",
      "postal_code": "69003",
      "country": "FR"
    }
  }
}
Champ JSONBT EN16931ObligatoireNotes
nameBT-27ouiRaison sociale
vat_idBT-31conditionnelTVA intracommunautaire (schemeID VA)
siretBT-30conditionnelSIRET en France (schemeID 0002)
address.streetBT-35nonAdresse ligne 1
address.cityBT-37nonVille
address.postal_codeBT-38nonCode postal
address.countryBT-40ouiCode pays ISO 3166-1 alpha-2

La règle Schematron BR-CO-26 exige qu’au moins un identifiant vendeur soit présent parmi BT-29, BT-30 et BT-31. En pratique, fournir vat_id et siret ensemble est la configuration la plus robuste pour les entreprises françaises.

Bloc buyer

La structure est identique au bloc seller. Le minimum requis est le name (BT-44) et le address.country (BT-55). En B2B, ajouter le vat_id (BT-48) est fortement recommandé pour le routage via PA.

Bloc line_items

{
  "line_items": [
    {
      "number": "1",
      "description": "Pose de cloisons sèches — chantier Bellecour",
      "quantity": 40,
      "unit": "HUR",
      "unit_price": 55.00,
      "net_amount": 2200.00,
      "vat_rate": 20,
      "vat_category": "S"
    }
  ]
}
Champ JSONBT EN16931Notes
numberBT-126Identifiant de ligne
descriptionBT-153Nom / description de l’article
quantityBT-129Quantité facturée
unitBT-130Code UN/ECE Rec 20 (C62 = unité, HUR = heure, KGM = kg)
unit_priceBT-146Prix unitaire net HT
net_amountBT-131Montant net de ligne
vat_rateBT-152Taux TVA applicable (ex: 20 pour 20%)
vat_categoryBT-151Code catégorie TVA UNCL 5305

Chaque facture doit contenir au moins une ligne (règle BR-16). Le unit par défaut est C62 (unité) s’il est omis. Les ERP stockent souvent des labels en clair (“heure”, “pièce”) qu’il faut convertir en codes UN/ECE Rec 20.

Bloc totals

{
  "totals": {
    "net": 2200.00,
    "tax": 440.00,
    "gross": 2640.00,
    "due": 2640.00
  }
}
Champ JSONBT EN16931Description
netBT-109Total HT
taxBT-110Total TVA
grossBT-112Total TTC
dueBT-115Montant à payer

Les règles Schematron BR-CO-10, BR-CO-13 et BR-CO-15 vérifient la cohérence arithmétique. La somme des nets de lignes (BT-106) et le total HT (BT-109) peuvent différer en présence de remises ou charges documentaires. Vérifier chaque relation et sa tolérance ; ne pas corriger arbitrairement un centime.

Bloc tax_breakdown (multi-taux)

Quand la facture comporte plusieurs taux de TVA, le bloc tax_breakdown ventile les montants par catégorie :

{
  "tax_breakdown": [
    {
      "category": "S",
      "rate": 20,
      "base": 1800.00,
      "amount": 360.00
    },
    {
      "category": "S",
      "rate": 5.5,
      "base": 400.00,
      "amount": 22.00
    }
  ]
}

Chaque entrée correspond à un bloc ram:ApplicableTradeTax dans le XML CII (BG-23). La règle BR-CO-17 contrôle la relation entre amount, base et rate, avec les arrondis et tolérances du ruleset exécuté. Chaque ligne de facture doit être rattachée au bon taux via son champ vat_category + vat_rate.

Mapping ERP vers invoice_data : les champs qui posent problème

La plupart des champs se mappent directement — le nom du vendeur dans l’ERP devient seller.name, le numéro de facture devient invoice_number. Mais plusieurs transformations sont nécessaires pour passer du modèle ERP au modèle EN16931.

Dates : ISO 8601 en entrée, CII 102 en sortie

En CII, les dates utilisent le format AAAAMMJJ (ex: 20260401) avec l’attribut format="102". Les ERP stockent généralement en ISO 8601 (2026-04-01).

Le contrat invoice_data attend le format ISO : "issue_date": "2026-04-01". Le moteur convertit ensuite cette date vers le format CII 102 dans le XML généré.

Catégories TVA : S, Z, E, AE, K, G, O

Le code catégorie TVA (UNCL 5305) est une source d’erreur fréquente. Les ERP utilisent des labels internes (“Normal”, “Exonéré”, “Intra-UE”) qu’il faut mapper vers les codes normalisés :

CodeSignificationQuand l’utiliser
SStandard ratedTaux normal (20%, 10%, 5.5%, 2.1% en France)
ZZero ratedOpération taxable à taux zéro
EExemptExonération de TVA (article 261 du CGI)
AEReverse chargeAutoliquidation — par exemple sous-traitance BTP relevant de l’art. 283, 2 nonies ; pour les services transfrontaliers, qualifier d’abord le lieu d’imposition et le redevable
KIntra-community supplyLivraison intracommunautaire de biens
GExport outside EUExportation hors UE
ONot subject to VATHors champ TVA

Chaque code active des règles Schematron spécifiques (familles BR-S-*, BR-Z-*, BR-E-*, BR-AE-*, etc.). Utiliser le mauvais code déclenche des erreurs en cascade. Le détail de ces règles est documenté dans le Catalogue des erreurs BR-* EN16931.

Identifiants légaux : SIRET et TVA intracommunautaire

En France, deux identifiants coexistent :

  • BT-30 (identifiant légal) : le SIRET à 14 chiffres, avec schemeID="0002" (répertoire SIRENE, ISO 6523)
  • BT-31 (identifiant TVA) : le numéro de TVA intracommunautaire (FRXX + 9 chiffres), avec schemeID="VA"

Dans le JSON invoice_data, ils correspondent respectivement à siret (SIRET) et vat_id (TVA intra). L’API génère automatiquement les bons schemeID dans le XML CII.

La règle BR-CO-26 exige au moins un identifiant vendeur. Pour l’autoliquidation (code AE), les règles BR-AE exigent un identifiant fiscal vendeur (BT-31, BT-32 ou BT-63) et côté acheteur un identifiant TVA ou un identifiant légal (BT-48 ou BT-47).

Adresses : BT-35, BT-37, BT-40

Seul le code pays (address.country → BT-40) est strictement obligatoire (cardinalité 1..1). La rue (BT-35) et la ville (BT-37) sont optionnelles dans EN16931 (0..1), mais fortement recommandées pour le routage via PA et la conformité pratique.

Cas spéciaux

Autoliquidation (code TVA AE)

L’autoliquidation concerne plusieurs situations, dont certains travaux immobiliers sous-traités relevant de l’article 283, 2 nonies du CGI. Pour les prestations transfrontalières, distinguez la règle générale de territorialité des règles particulières : la DGFiP rattache les achats en France de services relevant de la règle générale auprès d’un prestataire non établi en France à l’article 283, 2. La seule mention « intra-UE » ne détermine pas le régime applicable.

Lorsque l’opération relève de l’autoliquidation, le preneur est redevable de la TVA ; sa déduction dépend des conditions du droit à déduction. Le mapping AE ne décide ni du traitement fiscal ni du droit à déduction.

Dans le JSON invoice_data, quatre éléments sont nécessaires :

  1. vat_category: "AE" sur chaque ligne relevant effectivement de l’autoliquidation
  2. vat_rate: 0 — le taux est zéro puisque la TVA n’est pas facturée
  3. Un motif d’exonération — le champ vat_exemption_reason (BT-120) avec la mention légale
  4. Un identifiant fiscal vendeur et un identifiant acheteur — pour une facture en autoliquidation (AE), les règles BR-AE exigent un identifiant fiscal vendeur (BT-31, BT-32 ou BT-63) et côté acheteur un identifiant TVA ou un identifiant légal (BT-48 ou BT-47)

Le tax_breakdown doit refléter la même configuration :

{
  "tax_breakdown": [
    {
      "category": "AE",
      "rate": 0,
      "base": 5000.00,
      "amount": 0.00
    }
  ],
  "vat_exemption_reason": "Autoliquidation - Sous-traitance BTP, article 283, 2 nonies du CGI"
}

L’absence du motif d’exonération (BT-120 ou BT-121) déclenche une erreur BR-AE. L’absence d’un identifiant fiscal vendeur (BT-31, BT-32 ou BT-63) ou d’un identifiant acheteur (BT-48 ou BT-47) en déclenche une autre. Ces deux erreurs sont parmi les plus fréquentes sur les factures de sous-traitance.

Avoir / note de crédit

Cet exemple utilise invoice_type: "381" pour annuler partiellement une opération positive : ses lignes et totaux sont positifs. Ce n’est pas une règle universelle de signe pour tous les avoirs CII. Le contrat d’entrée invoice_data impose notamment des totaux net, tax et gross non négatifs et des quantités positives ; le seul code 381 ne normalise pas les montants négatifs de votre ERP. Adaptez le mapping à partir des données comptables, puis contrôlez le XML généré.

Les identités, dates et conditions de paiement ci-dessous sont illustratives ; cet exemple de mapping n’est pas une facture complète certifiée pour transmission.

{
  "invoice_number": "AV-2026-007",
  "issue_date": "2026-04-15",
  "invoice_type": "381",
  "currency": "EUR",
  "invoice_reference": "FA-2026-042",
  "invoice_reference_issue_date": "2026-04-10",
  "payment": {
    "terms": "Avoir à imputer sur la facture FA-2026-042"
  },
  "seller": {
    "name": "Dupont BTP SAS",
    "siret": "12345678901234",
    "address": {
      "street": "45 Avenue des Chantiers",
      "city": "Lyon",
      "postal_code": "69003",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Client Construction SA",
    "siret": "98765432109876",
    "address": {
      "street": "8 Rue du Projet",
      "city": "Grenoble",
      "postal_code": "38000",
      "country": "FR"
    }
  },
  "line_items": [
    {
      "number": "1",
      "description": "Annulation partielle de la prestation facturée",
      "quantity": 1,
      "unit": "C62",
      "unit_price": 250.00,
      "net_amount": 250.00,
      "vat_rate": 20,
      "vat_category": "S"
    }
  ],
  "totals": {
    "net": 250.00,
    "tax": 50.00,
    "gross": 300.00,
    "due": 300.00
  },
  "tax_breakdown": [
    {
      "category": "S",
      "rate": 20,
      "base": 250.00,
      "amount": 50.00
    }
  ]
}

invoice_reference porte la référence BT-25 et invoice_reference_issue_date sa date BT-26. Dans le noyau EN16931, le groupe BG-3 est optionnel ; lorsqu’il est présent, BR-55 exige la référence. Pour une cible France, BR-FR-CO-05 encadre les références et dates des avoirs, en entête ou sur les lignes concernées selon le profil. Consulter la publication France RFE et le variant réellement exécuté : la sévérité du rapport et l’acceptation PA sont distinctes.

Dans cet exemple, due est positif : BR-CO-25 demande une date d’échéance ou des conditions de paiement. Le texte d’imputation choisi ici illustre une décision métier, pas une règle universelle de remboursement des avoirs.

Multi-taux TVA

L’exemple arithmétique ci-dessous utilise deux taux déjà déterminés dans le système source (20 % et 5,5 %). Il ne fixe pas le taux applicable à un matériau ou à une prestation : chaque ligne reprend le traitement fiscal de l’opération, puis tax_breakdown ventile les montants par catégorie et taux :

{
  "line_items": [
    {
      "number": "1",
      "description": "Poste A — taux validé dans le système source",
      "quantity": 20,
      "unit": "HUR",
      "unit_price": 45.00,
      "net_amount": 900.00,
      "vat_rate": 20,
      "vat_category": "S"
    },
    {
      "number": "2",
      "description": "Poste B — taux validé dans le système source",
      "quantity": 25,
      "unit": "MTK",
      "unit_price": 32.00,
      "net_amount": 800.00,
      "vat_rate": 5.5,
      "vat_category": "S"
    }
  ],
  "tax_breakdown": [
    { "category": "S", "rate": 20, "base": 900.00, "amount": 180.00 },
    { "category": "S", "rate": 5.5, "base": 800.00, "amount": 44.00 }
  ],
  "totals": {
    "net": 1700.00,
    "tax": 224.00,
    "gross": 1924.00,
    "due": 1924.00
  }
}

La règle BR-CO-17 vérifie la cohérence de chaque entrée du tax_breakdown. La règle BR-CO-15 vérifie que gross = net + tax. Ces contrôles n’ont pas tous les mêmes tolérances : rattachez l’écart au code de règle et au profil réellement exécutés, sans déduire un rejet universel au centime.

Exemple complet : facture de sous-traitance BTP en autoliquidation

Voici un JSON invoice_data réaliste pour une facture de sous-traitance avec autoliquidation, deux lignes de prestation, SIRET et TVA intracommunautaire.

{
  "invoice_number": "FA-2026-158",
  "issue_date": "2026-04-01",
  "invoice_type": "380",
  "currency": "EUR",
  "seller": {
    "name": "Dupont BTP SAS",
    "vat_id": "FR32123456789",
    "siret": "12345678901234",
    "address": {
      "street": "45 Avenue des Chantiers",
      "city": "Lyon",
      "postal_code": "69003",
      "country": "FR"
    }
  },
  "buyer": {
    "name": "Grands Travaux Rhône SA",
    "vat_id": "FR87987654321",
    "siret": "98765432109876",
    "address": {
      "street": "12 Rue de la République",
      "city": "Lyon",
      "postal_code": "69002",
      "country": "FR"
    }
  },
  "line_items": [
    {
      "number": "1",
      "description": "Pose cloisons sèches — Lot 3 chantier Bellecour",
      "quantity": 120,
      "unit": "HUR",
      "unit_price": 48.00,
      "net_amount": 5760.00,
      "vat_rate": 0,
      "vat_category": "AE"
    },
    {
      "number": "2",
      "description": "Fourniture et pose faux plafonds — Lot 3 chantier Bellecour",
      "quantity": 85,
      "unit": "MTK",
      "unit_price": 35.00,
      "net_amount": 2975.00,
      "vat_rate": 0,
      "vat_category": "AE"
    }
  ],
  "tax_breakdown": [
    {
      "category": "AE",
      "rate": 0,
      "base": 8735.00,
      "amount": 0.00
    }
  ],
  "totals": {
    "net": 8735.00,
    "tax": 0.00,
    "gross": 8735.00,
    "due": 8735.00
  },
  "vat_exemption_reason": "Autoliquidation - Sous-traitance BTP, article 283, 2 nonies du CGI"
}

Les montants se vérifient : ligne 1 (120 x 48.00 = 5 760.00) + ligne 2 (85 x 35.00 = 2 975.00) = 8 735.00 = net. TVA à 0 (autoliquidation), donc gross = net.

Appel curl

curl -X POST https://api.facturxapi.com/api/v1/convert \
  -H "Authorization: Bearer votre-cle-api" \
  -F "file=@./facture-btp.pdf" \
  -F 'invoice_data={
    "invoice_number": "FA-2026-158",
    "issue_date": "2026-04-01",
    "invoice_type": "380",
    "currency": "EUR",
    "seller": {
      "name": "Dupont BTP SAS",
      "vat_id": "FR32123456789",
      "siret": "12345678901234",
      "address": {
        "street": "45 Avenue des Chantiers",
        "city": "Lyon",
        "postal_code": "69003",
        "country": "FR"
      }
    },
    "buyer": {
      "name": "Grands Travaux Rhône SA",
      "vat_id": "FR87987654321",
      "siret": "98765432109876",
      "address": {
        "street": "12 Rue de la République",
        "city": "Lyon",
        "postal_code": "69002",
        "country": "FR"
      }
    },
    "line_items": [
      {
        "number": "1",
        "description": "Pose cloisons sèches — Lot 3 chantier Bellecour",
        "quantity": 120,
        "unit": "HUR",
        "unit_price": 48.00,
        "net_amount": 5760.00,
        "vat_rate": 0,
        "vat_category": "AE"
      },
      {
        "number": "2",
        "description": "Fourniture et pose faux plafonds — Lot 3 chantier Bellecour",
        "quantity": 85,
        "unit": "MTK",
        "unit_price": 35.00,
        "net_amount": 2975.00,
        "vat_rate": 0,
        "vat_category": "AE"
      }
    ],
    "tax_breakdown": [
      {
        "category": "AE",
        "rate": 0,
        "base": 8735.00,
        "amount": 0.00
      }
    ],
    "totals": {
      "net": 8735.00,
      "tax": 0.00,
      "gross": 8735.00,
      "due": 8735.00
    },
    "vat_exemption_reason": "Autoliquidation - Sous-traitance BTP, article 283, 2 nonies du CGI"
  }'

Réponse attendue

{
  "success": true,
  "target": {
    "requested": "en16931",
    "executed": "en16931",
    "status": "verified",
    "missing_inputs": [],
    "not_run_reason": null
  },
  "result": {
    "durationMs": 2800,
    "targetProfile": "EN16931",
    "conversionSuccessful": true,
    "packagingPerformed": true,
    "xml": "PD94bWwg...",
    "xmlSize": 5120,
    "pdf": "JVBERi0x...",
    "pdfSize": 115200,
    "extraction": {
      "sourceType": "structured_data",
      "pageCount": 1
    },
    "validation": {
      "valid": true,
      "profile": "EN16931",
      "summary": { "errorCount": 0, "warningCount": 0 }
    },
    "processedInvoicesCharged": 1,
    "remainingInvoices": 999
  }
}

Le result.extraction.sourceType: "structured_data" confirme que les données viennent du JSON invoice_data et non d’une extraction PDF. Le statut target.status: "verified" indique que les contrôles demandés pour cette cible ont été exécutés sans erreur bloquante.

Validation des données avant conversion

L’API valide les données ERP avant de générer le XML CII. Si une incohérence est détectée, elle retourne un code 422 avec un diagnostic précis avant même de toucher au PDF.

Erreurs courantes côté ERP

ErreurCause ERP typiqueDiagnostic API
totals.net incohérent avec les nets de lignes, remises et charges documentairesArrondi, ligne, remise ou charge oubliée dans l’exportarithmetic_mismatch: net
Identifiant fiscal absent avec catégorie AEChamp TVA ou identifiant légal non mappé dans l’export ERPmissing_field: seller tax identifier (required for AE)
vat_rate > 0 avec catégorie AECode TVA ERP mal convertiinvalid_combination: AE with vat_rate > 0
tax_breakdown incohérent avec les lignesVentilation TVA calculée indépendamment des lignestax_breakdown_mismatch
unit invalideLabel en clair au lieu du code UN/ECEinvalid_unit_code

Recommandation : valider côté ERP avant d’envoyer

Plutôt que de découvrir les erreurs via l’API, implémentez les vérifications en amont dans votre pipeline ERP :

  1. Cohérence arithmétique — vérifier les nets de lignes avec leurs remises, charges et quantités de base ; net = somme des nets de lignes − remises documentaires + charges documentaires ; gross = net + tax ; due = gross − acomptes + arrondi (BR-CO-16)
  2. Complétude des identifiants — au moins un identifiant vendeur (vat_id ou siret), code pays présent
  3. Codes normalisés — vat_category parmi S, Z, E, AE, K, G, O ; unit valide UN/ECE Rec 20 ; currency ISO 4217
  4. Cohérence TVA — si vat_category = "AE", alors vat_rate = 0 ; renseigner un motif textuel ou codé, selon BR-AE-10 et le mapping de motif accepté par le contrat d’entrée

Cela réduit les allers-retours avec l’API et accélère le flux de production. Les erreurs de format (dates, décimaux) peuvent être corrigées automatiquement — voir Corriger automatiquement un XML CII invalide.

Erreurs fréquentes lors du mapping ERP

Les codes BR-* les plus souvent déclenchés par un mapping JSON → CII imparfait, avec fiche de correction :

Catalogue complet des 22 fiches.

Et maintenant ?

Générer un Factur-X depuis mon JSON ERP →

set -euo pipefail

response_file="$(mktemp "${TMPDIR:-/tmp}/facturx-response.XXXXXX")"
pdf_tmp="$(mktemp "./facturx-conforme.pdf.tmp.XXXXXX")"
trap 'rm -f "$response_file" "$pdf_tmp"' EXIT

curl --fail-with-body --silent --show-error \
  -X POST https://api.facturxapi.com/api/v1/convert \
  -H "Authorization: Bearer VOTRE_CLE" \
  -F "file=@./facture-support.pdf" \
  -F 'invoice_data={"invoice_number":"FA-2026-042","issue_date":"2026-04-01",...}' \
  --output "$response_file"

jq -e '
  (.target.status == "verified" or .target.status == "incomplete") and
  (.result.packagingPerformed == true) and
  (.result.pdf | type == "string" and length > 0)
' "$response_file" > /dev/null

jq -er '.result.pdf' "$response_file" | base64 --decode > "$pdf_tmp"
test "$(head -c 5 "$pdf_tmp")" = "%PDF-"
mv "$pdf_tmp" facturx-conforme.pdf

if jq -e '.target.status == "incomplete"' "$response_file" > /dev/null; then
  jq -r '.result.validationReadiness.frCtc.advisories // .warnings // []' "$response_file" >&2
  printf '%s\n' 'Fichier généré avec réserves : traitez-les avant transmission.' >&2
fi

La clé Sandbox permet de tester l’API sans carte bancaire. Consultez les quotas et conditions à jour ; Launch prend le relais pour brancher un premier flux récurrent avec /convert, /repair et /extract.

Aller plus loin

#ERP #JSON #CII #factur-x #EN16931 #mapping #autoliquidation #API