The French e-invoicing lifecycle — interactive reference
Every invoice exchanged under the French reform carries a cycle de vie — a sequence of statuses fixed by AFNOR XP Z12-012 (CDAR data element MDT-105): 14 codes, 200–213. Four are obligatoires (200, 210, 212, 213 — always transmitted to the DGFiP concentrator), five are recommandés (203, 204, 205, 206, 211), and the remaining five coded statuses are libres (201, 202, 207, 208, 209 — optional between platforms). Anything outside the referential is a custom status that never leaves your own tooling. This page is the full referential: who emits each status, in which phase, the allowed transitions — and the exact API call that emits or observes it with Flowie (Plateforme Agréée n° 0040).
Interactive explorer
Filter by tier, click any status for its full definition and the code to add, or press play to watch an invoice travel the network — each step logs the webhook Flowie fires.
The three tiers — obligatoire, recommandé, libre
The official referential (the « Transmission » column of the DGFiP external specifications, kept by AFNOR XP Z12-012) classifies the 14 coded statuses in three tiers — and everything outside the referential forms a fourth, uncoded family:
| Tier | Statuses | What it means | Transmitted? |
|---|---|---|---|
| Obligatoire (mandatory) | 200 Déposée, 210 Refusée, 212 Encaissée, 213 Rejetée |
Must be emitted whenever the corresponding event occurs. 200 opens every lifecycle; 212 carries the collected amount (MEN) that feeds the VAT-on-collection (CA3) pre-fill; 210/213 cancel the invoice and require a coded motif. |
Yes — always, including to the PPF concentrator (within the 24-hour reporting window). |
| Recommandé | 203 Mise à disposition, 204 Prise en charge, 205 Approuvée, 206 Approuvée partiellement, 211 Paiement transmis |
Officially recommended “pour assurer le bon déroulé des échanges”. Optional — but they are what gives your counterparty (and your own AR/AP team) real-time visibility. A serious integration emits them. | Between platforms, when emitted. |
| Libre (coded) | 201 Émise, 202 Reçue, 207 En litige†, 208 Suspendue, 209 Complétée |
Part of the referential — coded, interoperable, defined semantics — but entirely at each platform’s / party’s discretion. Not every platform supports receiving them. | Between platforms, when emitted & supported. |
| Custom (uncoded) | unbounded | Internal workflow states like bon à payer or exportée en compta. No MDT-105 code, no CDAR — see modelling them with tags. |
Never. |
† 207 En litige is the one contested cell: the v2.3 dossier’s transmission table reads libre, while several industry readings (and some trainings) class it recommandé. Treat it as optional either way; we track every annex revision and will update this page if the classification moves.
200 and 213 — Flowie emits those automatically. Your integration is on the hook for the business decisions only: 210 Refusée when the buyer refuses, 212 Encaissée when the supplier is paid. The cheat-sheet below says exactly which side emits what.
The 14 statuses of the referential (MDT-105)
The referential splits in two phases, carried in the CDAR’s MDT-77 type code: Transmission statuses (305 — produced automatically by the platforms as the invoice moves) and Traitement statuses (23 — business decisions produced by the buyer or the supplier).
| Code | Statut (FR) | English | Tier | Phase | Emitted by | Meaning |
|---|---|---|---|---|---|---|
200 | Déposée | Deposited | Mandatory | Transmission | Seller’s PA | The sending platform attests the invoice is received, checked & compliant — start of every lifecycle. Invoice data reaches the PPF within 24 h of this timestamp. |
201 | Émise par la plateforme | Issued by platform | Libre | Transmission | Seller’s PA | The seller’s PA confirms it transmitted the invoice to the recipient’s PA. |
202 | Reçue par la plateforme | Received by platform | Libre | Transmission | Buyer’s PA | The recipient’s PA confirms receipt from the sender’s PA (not yet visible to the buyer). |
203 | Mise à disposition | Made available | Recommended | Transmission | Buyer’s PA | The invoice is available to the buyer on their platform. |
204 | Prise en charge | Acknowledged | Recommended | Traitement | Buyer | The buyer acknowledges the invoice and starts processing it. |
205 | Approuvée | Approved | Recommended | Traitement | Buyer | The buyer accepts the invoice in full. |
206 | Approuvée partiellement | Partially approved | Recommended | Traitement | Buyer | The buyer accepts the invoice only in part — carries the approved / non-approved amount blocks (MAP/MNA); usually followed by a credit note. |
207 | En litige | In dispute | Libre† | Traitement | Buyer | The buyer disputes all or part of the invoice without refusing it outright. Motif required. Resolves to approval or refusal. |
208 | Suspendue | Suspended | Libre | Traitement | Buyer | Processing is suspended pending supporting documents from the supplier. Motif required. |
209 | Complétée | Completed | Libre | Traitement | Supplier | The supplier delivered the awaited material — resolves 208. Complementary data travels in the status message (MDG-43, code MAJ); the invoice itself is not re-sent. |
210 | Refusée | Refused | Mandatory | Traitement | Buyer | Deliberate business refusal of a valid invoice. Terminal — cancels the invoice; coded motif from the restricted list required. |
211 | Paiement transmis | Payment sent | Recommended | Traitement | Buyer | The buyer confirms the payment was sent (or the supplier confirms a refund). Amount blocks MPA (paid) / RAP (remainder). |
212 | Encaissée | Collected | Mandatory | Traitement | Supplier | The supplier confirms funds received (partial or full). Must carry the collected amount (MDT-207 = MEN, rule BR-FR-CDV-14) — this is the e-reporting payment-data vehicle behind the VAT (CA3) pre-fill for services. Terminal. |
213 | Rejetée | Rejected | Mandatory | Transmission | Either PA | Technical rejection by a platform control (format, SIRET, duplicate…). Terminal — the invoice was never validly exchanged. The norm splits it into rejetée à l’émission and rejetée en réception; coded motif required. |
211 is the buyer saying payment sent; 212 Encaissée is emitted by the supplier (both map to UNTDID 1373 code 47 Paid, which is why they get conflated). And “there is a code 214 Visée” — Visée / Mise en paiement belong to the legacy Chorus Pro B2G flow; the B2B referential stops at 213.
For the crucial difference between 210 Refusée (business refusal by the buyer) and 213 Rejetée (technical rejection by a platform), plus 208 Suspendue (on hold) and their coded motifs (MDT-113/MDT-114) — see the dedicated Refusal, rejection & on-hold reference (or the summary on the France overview).
Status → Flowie API cheat-sheet
One table to bookmark. Automatic means Flowie emits the status for you — you only observe it (webhook lifecycle.updated, or GET /v1/documents/{id}/lifecycle). Everything else is one call to POST /v1/documents/{id}/lifecycle.
| Code | Statut | Your side | What you do |
|---|---|---|---|
200 | Déposée | Supplier | Automatic — emitted when your POST /v1/documents/send passes controls. |
201 | Émise par la plateforme | Supplier | Automatic — observe via webhook document.sent. |
202 | Reçue par la plateforme | Supplier | Automatic — observe via webhook document.delivered. |
203 | Mise à disposition | Buyer | Automatic — your inbound webhook document.received fires; the invoice is in your queue. |
204 | Prise en charge | Buyer | POST …/lifecycle {"status":"under_review"} |
205 | Approuvée | Buyer | POST …/lifecycle {"status":"approved"} |
206 | Approuvée partiellement | Buyer | POST …/lifecycle {"status":"approved", "remainingAmount": …} — the remaining amount signals a partial approval. |
207 | En litige | Buyer | POST …/lifecycle {"status":"disputed", "reason": "…"} |
208 | Suspendue | Buyer | POST …/lifecycle {"status":"disputed", "reasonCode":"suspended", "reason":"…"} — the suspended reason code makes Flowie emit 208 instead of 207. |
209 | Complétée | Supplier | Attach the requested material: POST …/actions {"action":"link","relatedDocumentId":"…"} (or add-note) on a suspended invoice — Flowie emits 209. |
210 | Refusée | Buyer | POST …/lifecycle {"status":"rejected", "reasonCode":"…", "reason":"…"} — reason is forwarded verbatim as MDT-113/MDT-114. |
211 | Paiement transmis | Buyer | POST …/lifecycle {"status":"paid", "paymentDate":"…"} — from the buyer org, this emits 211. |
212 | Encaissée | Supplier | POST …/lifecycle {"status":"paid", "paymentDate":"…", "paymentAmount": …} — from the supplier org, this emits 212. Partial collection: use "partially_paid" + remainingAmount. |
213 | Rejetée | Supplier | Automatic — a platform control failed. Observe webhook document.failed (or compliance.reported.failed), fix, and re-send. |
211; the supplier saying “funds received” is 212 (the mandatory one, since it drives VAT on encaissements). With Flowie you make the same {"status":"paid"} call from either side — the party role on the document decides which code is transmitted.
Skipping statuses — what a minimal legal flow looks like
Because only 4 of the 14 statuses are mandatory, a perfectly legal lifecycle can be as short as 200 → 212 (deposited, then collected) — or 200 → 210 / 200 → 213 when things go wrong. The recommended statuses are not checkpoints: an invoice does not have to pass through 204 to be approved, and a buyer may refuse (210) without ever emitting 207 En litige first. Use the Mandatory filter in the explorer above to see the minimal graph.
Two consequences for your integration:
- Never assume ordering. Your webhook consumer must accept
lifecycle.updatedevents that jump tiers (e.g. straight fromsubmittedtopaid). Idempotent, out-of-order-tolerant handlers are the norm — see the playbook’s reference handler. - Emit generously, consume defensively. Emitting the recommended (and even the libre) statuses costs one API call each and materially improves your counterparty’s (and your own) visibility — but never require them from the other side: a platform is not allowed to fail an invoice because an optional status never arrived.
Canonical scenarios
The five playable scenarios in the explorer, in prose — these are the flows to test before go-live:
| Scenario | Status sequence | Outcome |
|---|---|---|
| Happy path | 200 → 201 → 202 → 203 → 204 → 205 → 211 → 212 | Invoice approved and paid; VAT pre-fill fed by 212. |
| Dispute resolved | 200 … 204 → 207 → 205 → 211 → 212 | Buyer contests (207), parties settle, approval and payment proceed. |
| Suspension | 200 … 204 → 208 → 209 → 205 → 211 → 212 | Buyer requests supporting documents (208); supplier completes (209); flow resumes. |
| Refusal | 200 … 203 → 204 → 210 | Business refusal by the buyer. Invoice cancelled; supplier must issue a corrective invoice (and an avoir if it was already accepted). |
| Platform reject | 200 → 201 → 213 | Technical rejection (format, SIRET, duplicate…). The invoice never legally existed on the network; fix and re-send. |
How statuses travel — the CDAR message
Between platforms, a lifecycle status is not a bare number: it travels as a CDAR (Cross Domain Acknowledgement and Response) message — the UN/CEFACT CrossDomainAcknowledgementAndResponse document, which France pins to the D22B XSD and constrains with the BR-FR-CDV Schematron rules. It is the only lifecycle syntax in the French socle minimal — the UBL ApplicationResponse familiar from Peppol is not an accepted syntax for the French CDV flux. The fields that matter:
| Field | Content | Example |
|---|---|---|
MDT-77 | TypeCode — the phase: 305 = transmission (platform-generated), 23 = traitement (business decision) | 23 |
MDT-105 | ProcessConditionCode — the status code from the 200–213 referential (+ its label in MDT-106) | 210 |
MDT-88 | StatusCode — optional generic UNTDID 1373 equivalent, for international coherence (see mapping below) | 50 |
MDT-113 | ReasonCode — coded motif from the restricted vocabulary of the XP Z12-012 annex (rule BR-FR-CDV-CL-09). Required for 210/213 (and expected for 206/207/208). | (see the official « Tableau des motifs de STATUTS » annex) |
MDT-114 | Reason — optional free text | "Prix unitaire ligne 3 non conforme au devis" |
MDG-43 / MDT-207 | Characteristic blocks qualifying amounts & data: MEN collected (mandatory on 212), MPA/RAP paid & remainder (211), MAP/MNA approved & non-approved (206), MAJ replacement data (209) | MEN = 2359.50 |
MDT-87 + MDG-35 + MDG-40 | Invoice identification: number + issue date + seller party (SIREN) — one CDAR references one invoice, one status | FA-2027-0042 |
Flowie builds, signs and routes CDAR messages for you in both directions: your POST …/lifecycle becomes an outbound CDAR; inbound CDARs from the buyer’s platform become lifecycle.updated webhooks with reasonCode/reason passed through verbatim — we never invent or re-map a motif (the motif code lists circulating on vendor blogs are largely fabricated; trust only the AFNOR annex).
International mapping — UNTDID 1373 & Peppol
Each French code has a generic UNTDID 1373 equivalent (BR-FR-CDV-CL-05), carried in MDT-88:
| FR | → UNTDID 1373 | FR | → UNTDID 1373 | ||
|---|---|---|---|---|---|
200 Déposée | 10 | In preparation | 207 En litige | 46 | Litigious |
201 Émise | 51 | Issued | 208 Suspendue | 39 | Suspended |
202 Reçue | 43 | Received | 209 Complétée | 37 | Complete |
203 Mise à disposition | 48 | Available | 210 Refusée | 50 | Rejected |
204 Prise en charge | 45 | In process | 211 Paiement transmis | 47 | Paid |
205 Approuvée | 1 | Accepted | 212 Encaissée | 47 | Paid |
206 Approuvée part. | 49 | Cond. accepted | 213 Rejetée | 8 | Rejected (tech.) |
Peppol is a different layer. Peppol status flows use UBL ApplicationResponse twice — the Message Level Response (validation outcome) and the Invoice Response (buyer decision, 7-code UNCL4343 subset: AB IP UQ CA RE AP PD). There is no official normative table mapping the French 2xx codes to UNCL4343 as of mid-2026; the informal overlaps (205≈AP, 206≈CA, 210≈RE, 211/212≈PD…) break down for the transmission phase, where 200/213 correspond to Peppol’s MLR / transport-receipt layer rather than to an Invoice Response. When you exchange cross-border through Flowie we translate at the edge and always keep the French codes authoritative for the DGFiP leg.
Custom statuses — your workflow, off the wire
Beyond the five coded libre statuses (201, 202, 207, 208, 209 — which do travel between platforms when supported), anything outside 200–213 is a custom status: useful, unregulated, and strictly local. Typical examples and how to model them with Flowie without polluting the regulated lifecycle:
| Libre status | Typical meaning | Model it as |
|---|---|---|
| En validation interne | Waiting on an internal approver | A tag: POST …/actions {"action":"tag","tag":"workflow/validation-interne"} |
| Bon à payer | Cleared for payment by AP | A tag + optionally assign to the payer |
| Exportée en comptabilité | Pushed to the ledger | A tag, set by your ERP sync after GET …/structured |
| Relance envoyée | Dunning reminder sent | An add-note action with the reminder reference |
| Mise en paiement / Mandatée | Legacy Chorus Pro B2G statuses | Treat as libre in a B2B context — their closest B2B code is 211; see the overview’s warning. |
Tags and notes never generate a CDAR and are never reported to the DGFiP — which is exactly the point. If a state should be visible to your counterparty, use the regulated status; if it’s internal process, keep it libre.
Machine-readable referential (JSON Schema)
Everything on this page is also published as data, so your integration (or your AI agent) can consume the referential instead of scraping it:
| Artifact | URL | What it is |
|---|---|---|
| Dataset | /schemas/fr-lifecycle-statuses.json |
All 14 statuses — tier, phase, emitter, terminality, motif & amount-block rules (MEN/MPA/MAP…), UNTDID 1373 mapping, canonical transitions, and the exact Flowie call or webhook per status. |
| JSON Schema | /schemas/fr-lifecycle-status.schema.json |
Draft 2020-12 schema the dataset validates against — use it to type your own copy, generate models, or validate a vendored snapshot in CI. |
const { statuses } = await (await fetch(
"https://docs.get-flowie.com/schemas/fr-lifecycle-statuses.json")).json();
const mandatory = statuses.filter(s => s.tier === "mandatory");
// → 200 Déposée, 210 Refusée, 212 Encaissée, 213 Rejetée
const next = Object.fromEntries(statuses.map(s => [s.code, s.transitionsTo]));
// next[204] → [205, 206, 207, 208, 210]
The dataset carries a semantic version plus the DGFiP / AFNOR spec versions it was verified against (specVersions); we bump it with every annex revision. The tables above and the interactive diagram are generated from the same facts — if you spot a divergence, that's a bug: tell us.
Test the full lifecycle in the sandbox
The sandbox ships a working replica of this state machine. A five-minute session that exercises every mandatory status:
- Send an invoice with a
flw_test_key — status200is synthesized immediately. - Drive the buyer side:
POST …/lifecycle {"status":"under_review"}then{"status":"approved"}(codes204,205). - Mark it paid from the supplier org (
212) — withsimulateCompliance: "accept"on the org, a syntheticcompliance.reportedwebhook fires, exactly like the real PPF acknowledgement. - Now break things:
simulateCompliance: "reject_00058"replays a PPF rejection end-to-end (compliance.reported.failed), and an illegal transition (e.g.received → paid) returns409 invalid_transitionwith the allowed next states.
Full test matrix — including timeout and flaky simulators for your retry logic — in the integration playbook.
References
- impots.gouv.fr · Facturation électronique — DGFiP official portal (mandate scope, calendar, external specifications ZIP with the XP Z12-012 annexes).
- AFNOR XP Z12-012 — the lifecycle referential itself (statuses, CDAR profile, motif annex). The motif list lives only in the « Tableau des motifs de STATUTS » sheet of the official annex.
- EU Commission · eInvoicing in France — pan-EU factsheet.
- FNFE-MPE — Forum national de la facture électronique.
- France overview — deadlines, required fields, PPF error codes, refus/rejet motifs.
- Integration playbook — ship a French-compliant integration end to end.