Skip to main content
Invoices to French public entities (the State, local authorities, hospitals, public establishments) have had to go through Chorus Pro, the government’s invoicing portal, since 2020. Under the 2026 reform, Chorus Pro becomes one more platform on the French Directory, listed under its own matricule, so a public entity is simply a customer whose Annuaire line points to it. That is what makes B2G invoicing in Invopop the same as B2B invoicing. A B2G invoice is recorded like any other, its F1 copy and 200 Déposée status reach the PPF unchanged, and the same send workflow handles every customer. Only delivery differs: the invoice goes to Chorus Pro instead of Peppol. Invopop holds the connection with Chorus Pro, so there is nothing to register on the public portal. This guide covers:

Who this guide is for

There are two ways to reach Chorus Pro through Invopop, and which one applies depends on the supplier, not the customer.
Don’t combine the two. A French company that already uses the standalone Chorus Pro app should move its public-sector invoicing to the PA path described here, so that every domestic invoice is recorded and reported the same way.

Prerequisites

  • A registered supplier: follow the registration guide to connect the France app and register the party in the Annuaire. The same registration serves B2B and B2G.
  • The public entity’s identifiers: its SIRET and, where the entity requires them, a service code and a commitment number. The public entity gives you these; see What a public buyer needs.
  • The invoicing guide: this page builds on the Invoicing in France guide and assumes you know how recording, formats and the PPF copy work.

How routing works

You do not mark an invoice as B2G yourself. When the Record outgoing document step records an invoice, it looks the customer up in the Annuaire. A customer whose line is routed to Chorus Pro’s public sphere, under matricule 9999, is a public entity, and the invoice is flagged b2g. The flag is only set while the line is in force, so a party that leaves Chorus Pro stops being B2G. The Is B2G? step then reads that flag and answers true or false, so the workflow can branch on it the same way it branches on Directory lookup: Keep Is B2G? after the record step, which is where the answer comes from. For a document that has not been recorded, the step asks the Annuaire directly. Everything after the branch is shared: both paths Forward document to PPF.
1

Record

The invoice is validated against the French rules, the customer is checked in the Annuaire, and the invoice is flagged b2g when the customer is a public entity. The Chorus Pro rules are applied at this point, so a breach is reported here rather than minutes later by Chorus Pro.
2

Is B2G?

Reads the flag and branches.
3

Send to Chorus Pro

Deposits the invoice with Chorus Pro and waits for its answer. The job stays queued until Chorus Pro has received the invoice and made it available to the public entity. See Following the invoice.
4

Forward document to PPF

Sends the F1 copy and the 200 Déposée status to the PPF, exactly as for a B2B invoice.

Setup

All of the following steps must be carried out from the Invopop Console. The PPF send document (public sector) template is the regular send workflow with the Is B2G? branch inserted after the record step. Use it in place of the regular one: it handles every customer, public or not, so you need only one send workflow.

PPF send document (public sector)

Add to my workspace →
The recommended approach for running jobs is to perform two steps: first upload the document to the silo, then create a job.
The workflow is shared with status documents. The Is B2G? step resolves a status or payment to the invoice it answers, so it follows the same channel as that invoice.

What a public buyer needs

A B2G invoice is a regular fr-ctc-flow2-v1 invoice. Chorus Pro needs a few more things on it to find the public entity and route the invoice to the right department. Ask the public entity which of the service code and commitment number it requires. Chorus Pro publishes each entity’s requirements, and an invoice missing a required one is rejected by Chorus Pro after deposit.
Invopop cannot yet check whether a given public entity requires a service code or a commitment number, because the Annuaire does not carry that information. Collect it from the buyer when you take the order.

Rules checked at record

Chorus Pro adds its own management rules on top of the norm, BR-FR-CPRO-01 to 50, and they apply only to invoices bound for the public sphere. None of them is covered by the standard schematrons, so without a local check the first time you hear of a breach is Chorus Pro’s rejection, which names a rule but not the field. Once an invoice is flagged b2g, the record step enforces the rules below and reports every breach at once, so a single round of fixes is enough. The IBAN rule is the one that catches most people. Chorus Pro counts the IBAN as written, so FR76 3000 6000 0112 3456 7890 189 is 33 characters and is refused. Write it without spaces. Rules that depend on data Invopop does not hold (whether the entity requires a service code or commitment number, 11 to 13), that the norm itself marks as unverifiable, or that turn on the S3 billing mode are not checked locally and remain enforced by Chorus Pro.

Following the invoice

Send to Chorus Pro deposits the invoice and then waits. Chorus Pro first acknowledges the deposit as a whole, then walks the invoice through its own lifecycle, which is richer than the PPF’s accepted or rejected pair. Invopop keeps the codes as Chorus Pro sends them, so the workflow and the France dashboard show the same vocabulary as the Chorus Pro portal. The job completes as soon as Chorus Pro has made the invoice available (203) or any later code arrives. Later statuses keep updating the invoice after the job has finished, and each is visible on the invoice in the France dashboard. Chorus Pro does not always deliver statuses in the order it applied them, so the invoice keeps whichever carries the latest timestamp. A 213 from Chorus Pro names the rule that failed. If it is one of the rules checked at record, the invoice was flagged b2g after the fact; otherwise fix the field the rule names and send a new invoice.
For an invoice you issued, the public entity drives the lifecycle through Chorus Pro. Statuses you build on such an invoice are not forwarded: Chorus Pro rules on the invoices it receives, and Invopop does not answer them. Statuses you send only travel to Chorus Pro for invoices a public entity sent to you, described next.

Receiving from a public entity (G2B)

G2B is the same exchange in reverse: a French public entity issues an invoice to your business. It is new with the 2026 reform. Public bodies previously had no route to invoice the private sector electronically. The path differs from a B2B invoice in where it comes from, not in what you do with it:
  1. The public entity submits the invoice to Chorus Pro, in UBL or Factur-X.
  2. Chorus Pro delivers it to Invopop, addressed to the Annuaire line your party is registered under. That line decides which workspace receives it, so the party must be registered before any public entity can invoice it.
  3. Receive document from Chorus Pro converts it to GOBL and hands it to your receive workflow, which records it against your party with the same controls as an inbound Peppol invoice.
From there it behaves like any other received invoice: it appears in the France dashboard, and you answer with status updates as it is accepted, disputed or paid. Build each status as you would for a B2B invoice and run it through the send workflow. Is B2G? resolves it to the invoice it answers, and Send to Chorus Pro deposits it on the public circuit. The statuses you send back follow the AFNOR norm rather than Chorus Pro’s own vocabulary. Chorus Pro translates its internal codes before they reach you, so a rejection arrives as 210 and its own motifs arrive as their AFNOR equivalents.

Testing in sandbox

A sandbox workspace delivers B2G invoices to Chorus Pro’s qualification environment, and the record step reads the qualification Annuaire to decide whether a customer is a public entity. Both are separate from production, so a public entity you find in the production Annuaire is unknown there, and the invoice routes to Peppol instead. To exercise the Chorus Pro branch in sandbox, use a customer registered as a public entity in the qualification Annuaire. Contact us for test buyer details if you don’t have any.

Example invoices

An invoice from a French company to a French public entity. It uses the same fr-ctc-flow2-v1 add-on as a domestic B2B invoice, with the data Chorus Pro needs on top.Notice:
  • both parties give a SIRET identity, which the add-on tags with iso-scheme-id 0009 and from which it derives the SIREN,
  • the customer carries a private-id identity with the public entity’s service code, which the add-on tags with scheme 0224,
  • ordering.purchases[0].code holds the numéro d’engagement juridique and ordering.contracts[0].code the contract reference, each 50 characters or fewer,
  • the invoice number is 20 characters or fewer and the IBAN is written as 27 characters without spaces, as Chorus Pro requires.

FAQ

Invoicing questions
Two channels depending on the recipient: B2G uses Chorus Pro (CII format); B2B from September 2026 uses the Plateforme Agréée model (UBL, CII, or Factur-X via Peppol). Invopop is an approved PA — install the France PA app for B2B and the Chorus Pro app for B2G.
In Factur-X PDFs, the XML file is embedded within the PDF itself. To extract and view it, use the Attachments section in Adobe Acrobat Reader, or a tool like the SysTools PDF Extractor.
Invopop is an officially approved Plateforme Agréée under the DGFiP mandate. Registration, invoicing, and lifecycle status are available today; e-reporting (Flow 10) is in active development. See the PA hub readiness matrix for the current state.
The base FR tax regime plus the EN 16931 profile. For Peppol delivery, peppol-bis-v3. The forthcoming fr-ctc-flow10-v1 addon covers e-reporting payloads — separate from the e-invoicing flow.
No. Most Peppol countries treat self-billing as a document type of its own, but France models it as a standard invoice with the untdid-document-type extension set to 389. In GOBL you never set the code yourself: add the self-billed tag and the fr-ctc-flow2-v1 add-on applies it automatically. See Self-billing for the full flow.
Transactions exempt under articles 261 to 261 E of the CGI — insurance, medical care, education and the rest of that range — sit outside the e-invoicing mandate, and the PPF rejects them if you deposit one. When an invoice’s whole VAT breakdown is exempt and carries a VATEX-FR-CGI261* code, Invopop records it but sends no F1 and raises no lifecycle status, and the dashboard shows it as Exempt. Keep issuing the invoice to your customer as usual. An invoice that mixes exempt and taxable lines is still sent normally, and so is VATEX-FR-FRANCHISE. See VAT-exempt invoices.
Each invoice or lifecycle status sent through France PA costs 5 pops: 1 pop for the conversion to UBL/CII, 2 pops to send it over Peppol, 1 pop to forward it to the PPF, and 1 pop for the silo entry. See Pops & pricing for how pops work.
Before an invoice is recorded, the PPF record document step looks up both the supplier and the customer SIREN in the Annuaire. What each party must satisfy depends on the workflow’s role:Sandbox invoices skip the Annuaire check entirely.
Don’t block the sale. An exchange where only one party has an effective Annuaire entry is a non-regulated flow: it leaves e-invoicing (flux 2) and is covered by e-reporting (flux 10) instead.In practice:
  • Run a Directory lookup against the customer’s SIREN before you generate the invoice — ideally in a separate validation workflow run against customer data, so you can prompt them to fix their registration ahead of time.
  • If the SIREN has no effective entry, route the invoice through your reporting workflow rather than the PA send workflow.
  • If it slips through, the send workflow degrades rather than failing: the Verify document can be sent step branches and forwards the invoice to the PPF as déposée – non transmise.
A missing entry is common and not necessarily an error. A SIREN visible in the public annuaire-entreprises registry is not the same as an effective entry in the DGFiP Annuaire, which only covers entities in scope of the mandate. It can also be absent because the buyer hasn’t yet appointed a PA, or because their tax records don’t match.
Both, for different reasons. A lookup at order or onboarding time is a data-quality check: it lets you warn the customer and get their SIREN or PA sorted before invoicing. A lookup at invoice time is the one that decides the flow, because registrations are added and withdrawn continuously and a party found at checkout may no longer be routable days later (and vice versa).Treat the early result as advisory, resolve again at generation, and store the resolved electronic address on the transaction — the routing address isn’t always the bare SIREN. See Directory lookup.
You don’t decide it yourself. When the invoice is recorded, Invopop looks the customer up in the Annuaire: a party whose line is routed to Chorus Pro is a public entity, and the invoice is marked B2G. The Is B2G? workflow step reads that answer and branches to Send to Chorus Pro instead of Peppol. See the public sector guide.
Not if your company has a French SIREN and is registered in the Annuaire through Invopop. Invopop holds the connection with Chorus Pro, so B2G invoices use the same send workflow as any other French invoice. Only foreign entities without a French SIREN still go through the standalone Chorus Pro app, which requires Chorus Pro credentials.
The service code (code service or code routage) is a private-id identity on the customer, and the commitment number (numéro d’engagement juridique) is the purchase order reference in ordering.purchases[0].code. Both are supplied by the public entity. The public sector guide lists every field.
Receiving questions
Register the recipient with Invopop as their Plateforme Agréée. Inbound documents (UBL, CII, Factur-X) are converted to GOBL and stored in the Expenses folder. Chorus Pro inbound flow is separate and routes via the Chorus Pro app.
UBL via gobl.peppol; CII and Factur-X via gobl.cii. The original structured XML (or PDF/A-3 with embedded XML) is preserved as a silo entry attachment.
Register the recipient via Invopop as their PA. Inbound UBL/CII/Factur-X documents are routed to the configured Import workflow and become GOBL silo entries. Lifecycle status updates (CDAR) feed back to the issuer through the same channel.
UBL, CII, or Factur-X (PDF with embedded CII XML), all conforming to EN 16931 and the French CTC profile. Invopop preserves the original and exposes the GOBL conversion.
Yes. A single company can be reachable at several destinations by registering different routing identifiers (electronic addresses) in the Annuaire — one per PDP or inbox. Invoices addressed to a given identifier are delivered to the platform registered against it, so you can route some invoices to Invopop and others to a different PDP (for example a travel-and-expense tool) for the same SIREN.The Annuaire supports several address formats that map to increasingly granular destinations within the same company:
  • SIREN — the company as a whole.
  • SIREN_SIRET — a specific establishment.
  • SIREN_SIRET_ROUTINGCODE — a site, department, or workflow within an establishment.
  • SIREN_SUFFIX — a custom routing suffix.
Give each PDP or inbox a distinct identifier and share the matching address with each issuer, so their invoices reach the intended destination. You can look up an electronic address in the Annuaire to confirm where it currently routes.
An invoice arriving from another platform goes through three controls, run in the order the PPF applies them:
  • Syntax — the invoice XML against the Flux 2 schematron for its syntax.
  • Addressing — both parties carry a SIREN registered in the Annuaire, the transport addresses belong to the parties the invoice names, and the invoice is addressed to a party registered in your workspace.
  • Unicity — the invoice is not already recorded for this party, number and year.
An invoice that passes every control is recorded on the receiving side. Only invoices are validated this way; incoming lifecycle statuses are simply recorded.
Each control rejects under its own CDAR motif, carried on the 213 Rejetée status returned to the platform that sent the invoice:
  • REJ_SEMAN — rejet pour erreur sémantique, when the invoice fails the Flux 2 schematron.
  • ADR_ERR — adresse de facturation électronique erronée, when the addressing control fails.
  • REJ_UNI — rejet sur contrôle unicité, when the invoice is already recorded.
More available in our France FAQ section

Participate in our community

Ask and answer questions about invoicing in France →