France 🇫🇷
Chorus Pro integration and the French B2B e-invoicing mandate, which is now in force.
Overview​
| Aspect | Details |
|---|---|
| B2G Mandate | Required since 2020 (via Chorus Pro) |
| B2B Mandate — receiving | In force since 1 September 2026 for every business covered by the reform, whatever its size |
| B2B Mandate — issuing | Large and mid-sized enterprises since 1 September 2026; small, medium and micro enterprises from 1 September 2027 |
| CIUS | Factur-X (EN16931 hybrid PDF/XML) |
| Primary Scheme | 0009 (SIRET) |
| Government Portal | Chorus Pro |
This obligation is already in force. Since 1 September 2026, every business covered by the reform — of any size, including the smallest — must be able to receive electronic invoices through an approved platform (plateforme agréée).
Only the obligation to issue is phased:
- 1 September 2026 — large enterprises (grandes entreprises) and mid-sized enterprises (entreprises de taille intermédiaire).
- 1 September 2027 — small and medium enterprises, very small businesses and micro-enterprises (PME, TPE, micro-entreprises).
If you are a small or micro business, the 2027 date is about sending. It does not give you until 2027 to be able to receive.
Source: Direction générale des Finances publiques, Facturation électronique : guide pratique de démarrage au 1er septembre 2026 (pages 2, 5, 11 and 21).
Identifier Schemes​
SIRET (0009) — Standard​
The 14-digit establishment identifier:
# Format: 14 digits (SIREN + NIC)
participant = {
"scheme": "0009",
"identifier": "12345678901234",
"name": "Exemple SARL",
"country": "FR"
}
Structure:
- First 9 digits: SIREN (company ID)
- Last 5 digits: NIC (establishment code)
Validation:
def validate_siret(siret: str) -> bool:
"""Validate French SIRET using Luhn algorithm."""
if len(siret) != 14 or not siret.isdigit():
return False
total = 0
for i, digit in enumerate(siret):
d = int(digit)
if i % 2 == 0:
d *= 2
if d > 9:
d -= 9
total += d
return total % 10 == 0
SIREN (0002)​
The 9-digit company identifier (less common):
participant = {
"scheme": "0002",
"identifier": "123456789",
"name": "Exemple SA",
"country": "FR"
}
VAT Number (9957)​
For cross-border B2B:
# Format: FR + 2 digits + 9 digits (SIREN)
participant = {
"scheme": "9957",
"identifier": "FR12123456789",
"name": "Exemple SAS",
"country": "FR"
}
Chorus Pro (B2G)​
Overview​
All B2G invoices must go through Chorus Pro:
Supplier → GoRoute (Peppol) → AIFE/Chorus Pro → Government Entity
Chorus Pro Integration​
GoRoute connects to Chorus Pro via Peppol for seamless delivery:
# Send to French government
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/documents",
headers={"X-API-Key": "your_api_key"},
json={
"sender_scheme": "0009",
"sender_id": "12345678901234",
"receiver_scheme": "0009",
"receiver_id": "13002526500013", # Example ministry
"document": invoice_xml # UBL XML string, not base64
}
)
Required Fields for Chorus Pro​
<Invoice>
<!-- Service code (Code Service) - often required -->
<cbc:BuyerReference>CODE_SERVICE_12345</cbc:BuyerReference>
<!-- Engagement juridique (Commitment number) -->
<cac:OrderReference>
<cbc:ID>EJ-2024-00123</cbc:ID>
</cac:OrderReference>
<!-- SIRET of sender -->
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0009">12345678901234</cbc:EndpointID>
</cac:Party>
</cac:AccountingSupplierParty>
<!-- SIRET of government receiver -->
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0009">13002526500013</cbc:EndpointID>
</cac:Party>
</cac:AccountingCustomerParty>
</Invoice>
Service Codes​
Many French public entities require a "Code Service":
<cbc:BuyerReference>SERVICE_COMPTABILITE</cbc:BuyerReference>
Look up valid codes in the Annuaire Chorus Pro.
Factur-X Format​
Factur-X is France's hybrid e-invoice format (PDF + embedded XML):
Profiles​
The Factur-X standard defines five conformance levels:
| Profile | Use Case |
|---|---|
| Minimum | Basic PDF, minimal data |
| Basic WL | Simple invoices |
| Basic | Standard B2B |
| EN16931 | Full EN16931 compliance |
| Extended | Maximum data |
You do not choose one of these from GoRoute. Every Factur-X file we produce is written at EN16931, and the Extended profile is deliberately not offered. The table is here so you can place a file you have received from someone else.
GoRoute produces Factur-X​
Since 7 September 2026, the PDF GoRoute generates for a French seller's invoice or credit
note is a Factur-X file: a PDF/A-3 carrying the EN 16931 invoice as an embedded
attachment named factur-x.xml, at conformance level EN 16931. It is the same document
Germany calls ZUGFeRD.
GET /api/v1/transactions/{transaction_id}/pdf
You get it from the ordinary PDF download, whether the invoice went over Peppol or was
issued for you to email. Pass hybrid=false for a plain PDF, or use
GET /api/v1/transactions/{transaction_id}/document/content?syntax=cii for the XML on its
own. A hybrid is produced only for documents GoRoute holds as structured invoice data —
POST /api/v1/invoices, a saved draft, a CSV or Excel import, a batch send, a connector —
and not for raw UBL posted to POST /api/v1/documents, which quietly returns the plain PDF.
POST /api/v1/invoices now also takes a document_format field (auto, ubl,
xrechnung, cii, zugferd) and a delivery_channel field (auto, peppol, email).
cii and zugferd are the same value and mean the Factur-X route. The full rules, the
delivery object in the response and the refusals are on
Delivery and formats.
A Factur-X PDF is still not accepted as input​
This has not changed. The send endpoint takes a UBL XML document. A Factur-X PDF is not
accepted, and neither is the XML embedded inside it: that XML is CII
(rsm:CrossIndustryInvoice), which POST /api/v1/documents refuses with
[INVALID_ROOT] … got 'CrossIndustryInvoice'. GoRoute does not convert CII to UBL.
Either convert the extracted CII to UBL before you send it, or send the invoice data to
POST /api/v1/invoices and let GoRoute render the document. Both routes, with code, are in
ZUGFeRD, Factur-X and XRechnung CII.
# invoice_ubl: UBL XML — converted from the Factur-X CII, or produced by your software
response = requests.post(
"https://app.goroute.ai/peppol-api/api/v1/documents",
headers={"X-API-Key": "your_api_key"},
json={
"sender_scheme": "0009",
"sender_id": "12345678901234",
"receiver_scheme": "0009",
"receiver_id": "13002526500013",
"document": invoice_ubl,
"metadata": {"source_format": "factur-x", "profile": "EN16931"}
}
)
The Factur-X production described above was released on 7 September 2026 and was read from
the product source (app/cius/germany/profiles.py, app/services/hybrid_pdf.py) and
cross-checked against the description the test service publishes. The production service
does not publish its description and both services report version 1.0.0, so we cannot tell
them apart by asking. Our release record pins the same build to production; that is a record,
not a probe.
VAT Requirements​
French VAT Format​
# French VAT: FR + 2 key digits + 9-digit SIREN
def validate_french_vat(vat: str) -> bool:
if not vat.startswith("FR"):
return False
if len(vat) != 13:
return False
key = vat[2:4]
siren = vat[4:]
if not siren.isdigit():
return False
return True
VAT Rates​
The Code column is the VAT category, which is a different field from the percentage: the
category says why a rate applies, the percentage says what it is. Every positive French rate
is category S carrying its own percentage.
| Code | Rate | Description |
|---|---|---|
| S | 20% | Standard rate |
| S | 10% | Intermediate reduced |
| S | 5.5% | Reduced (essential goods) |
| S | 2.1% | Super-reduced |
| Z | 0% | Zero rate |
| E | 0% | Exempt |
AA, H and I are rejectedEarlier revisions of this page gave AA for 10%, H for 5.5% and I for 2.1%. None of the
three is a permitted VAT category. EN 16931 allows only AE, B, E, G, K, L, M,
O, S and Z (UNCL5305),
and rules BR-CL-17 and BR-CL-18 reject anything else — the invoice fails validation and is
never delivered. Send each reduced rate as S with its percentage.
Example Invoice​
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>FR-FACT-2024-00123</cbc:ID>
<cbc:IssueDate>2024-01-15</cbc:IssueDate>
<cbc:DueDate>2024-02-15</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<!-- Code Service for Chorus Pro -->
<cbc:BuyerReference>CODE_SERVICE_COMPTABILITE</cbc:BuyerReference>
<!-- French Seller -->
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="0009">12345678901234</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Exemple SARL</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>123 Rue de la République</cbc:StreetName>
<cbc:CityName>Paris</cbc:CityName>
<cbc:PostalZone>75001</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>FR</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>FR12123456789</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Exemple SARL</cbc:RegistrationName>
<cbc:CompanyID schemeID="0009">12345678901234</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
<!-- French Government Buyer -->
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="0009">13002526500013</cbc:EndpointID>
<cac:PartyName>
<cbc:Name>Ministère de l'Économie</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>139 Rue de Bercy</cbc:StreetName>
<cbc:CityName>Paris</cbc:CityName>
<cbc:PostalZone>75012</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>FR</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Ministère de l'Économie</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>FR7630004000031234567890143</cbc:ID>
<cbc:Name>Exemple SARL</cbc:Name>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">20.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">100.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">20.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">100.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">100.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">120.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">120.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">100.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Services de conseil</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
</Invoice>
The B2B Mandate​
Approved platforms (plateformes agréées)​
Article 289 bis of the Code général des impôts requires the issuing, transmission and receipt of electronic invoices to go through an approved platform (plateforme agréée). Putting a platform in place is therefore the practical step behind both dates below: a business needs one to receive before it needs one to issue.
The tax administration's start-up guide describes this one route, and this page describes only what that guide describes.
Reporting Requirements​
New e-reporting obligations:
- E-invoicing: B2B domestic invoices
- E-reporting: International B2B + B2C summary
Timeline​
| Date | Obligation | Who it binds |
|---|---|---|
| 1 September 2026 | Must be able to receive electronic invoices through an approved platform | Every business covered by the reform, whatever its size |
| 1 September 2026 | Must issue electronic invoices through an approved platform | Large enterprises and mid-sized enterprises (grandes entreprises, entreprises de taille intermédiaire) |
| 1 September 2027 | Must issue electronic invoices through an approved platform | Small and medium enterprises, very small businesses and micro-enterprises (PME, TPE, micro-entreprises) |
The start-up tolerance is not a postponement​
For the start-up phase the tax administration has said it will not penalise businesses that run into real, documented difficulty while genuinely working towards compliance. Its own guide sets the limit of that in words this page repeats exactly:
« Cette approche ne constitue ni un report ni une suspension de l'obligation. »
"This approach constitutes neither a postponement nor a suspension of the obligation."
The obligation to receive took effect on 1 September 2026 and remains in force. The tolerance is about how the administration treats a business that is trying and struggling. It does not move any of the three dates above, and it is not an extension.
Sources for this section​
Every date and obligation above is taken from the Direction générale des Finances publiques, Facturation électronique : guide pratique de démarrage au 1er septembre 2026, read on 8 September 2026: the generalised receiving obligation at pages 2 and 5, the issuing obligation for large and mid-sized enterprises at page 11, the 2027 issuing date for smaller businesses together with the restatement of the 2026 receiving obligation at page 21, and the start-up tolerance at page 2.
Resources​
Next Steps​
Further reading​
- The 2026 French mandate
- France overview
- 2026 e-invoicing mandate tracker — every country, one page
- How to choose a Peppol Access Point
- One API for multi-country e-invoicing
Ready to build? The free developer sandbox gives you test credentials and a registered participant, provisioned within 24 hours on business days. Recorded ERP integration walkthroughs are on the tutorials page.