[BETA] France e-Invoicing Guide (DGFiP)
[BETA] Comply with France e-Invoicing Reform by using B2Brouter
The French e-invoicing reform establishes the obligation for all businesses established in France to issue, transmit, and receive electronic invoices for their domestic B2B transactions. This reform is being rolled out in phases, starting September 2026 for large enterprises and progressively extending to all businesses by September 2027.
The reform mandates that businesses use a certified Plateforme de Dématérialisation Partenaire (PDP) or the government's Portail Public de Facturation (PPF) to transmit invoices and report transaction data (e-reporting) to the tax authority, the Direction Générale des Finances Publiques (DGFiP).
These regulations require businesses to adopt systems capable of securely generating, transmitting, and receiving electronic invoices, as well as reporting tax data. B2Brouter is a technical solution that allows your business to be fully compliant -- whether you use the REST API, the web interface, or both -- offloading the complexities to B2Brouter so you can focus on your business logic.
What is the PPF?
The Portail Public de Facturation (PPF) is the central government platform that orchestrates the French e-invoicing ecosystem. It acts as both a directory service (the Annuaire) and a clearance hub for invoice transmission. All domestic B2B invoices between French companies must pass through the PPF, either directly or via a certified PDP.
The PPF is operated by the Agence pour l'Informatique Financière de l'État (AIFE) on behalf of the DGFiP.
The PDP model
Businesses can choose to connect to the PPF either directly or through a Plateforme de Dématérialisation Partenaire (PDP) -- a certified private intermediary. B2Brouter is a certified PDP, which means:
- B2Brouter handles all communications with the PPF on your behalf (invoice transmission, lifecycle management, and directory registration).
- You do not need to manage SFTP connections, electronic certificates, or direct interactions with the PPF.
- B2Brouter is registered in the PPF's Annuaire as a certified platform with its own matricule (platform identifier).
How it works
The French e-invoicing flow involves several data exchanges (flux) between platforms and the PPF:
- Flux 1 (Invoice deposit): The supplier's PDP sends the invoice to the PPF, which routes it to the buyer's PDP.
- Flux 6 (Lifecycle statuses): Both the buyer's PDP and the PPF exchange Cross-Domain Acknowledgement and Response (CDAR) messages to track the invoice lifecycle (deposited, received, approved, refused, paid, etc.).
- Flux 10 (e-Reporting): For transactions not covered by the e-invoicing obligation, the supplier reports transaction data to the PPF. Flux 10 covers two distinct cases:
- B2C transactions: Sales to non-VAT-registered individuals in France. Since there is no buyer PDP to receive the invoice, the supplier must report the transaction data directly to the PPF so the tax authority has visibility on these operations.
- Cross-border transactions: Sales to or purchases from companies established outside France (both intra-EU and extra-EU). These transactions are outside the scope of the domestic e-invoicing obligation but must still be reported to the DGFiP for VAT control purposes.
B2Brouter currently supports Flux 1 (domestic B2B e-invoicing) and Flux 6 (lifecycle management). Flux 10 (e-Reporting) for both B2C and cross-border transactions will be available soon.
Setting up and working with B2Brouter
The onboarding process for France involves the following steps:
- Create your Company Account in B2Brouter.
- Enable Tax Report Settings for DGFiP, which automatically registers your company in the PPF's Annuaire and creates a Peppol transport for receiving invoices.
- Create contacts for your French customers.
- Create and send invoices.
- Track the invoice lifecycle using webhooks or polling.
All these steps can be performed via the B2Brouter API or through the web UI. The automatic actions related to France tax compliance (tax report generation, PPF transmission, CDAR lifecycle management) are triggered regardless of whether the invoice was created via the API or the web interface.
Integration use cases
There are two main use cases for integrating with B2Brouter for France e-invoicing:
eDocExchange -- For companies or groups of companies that integrate their management software with B2Brouter. In this scenario, the onboarding process (account creation, Tax Report Settings configuration) is typically performed once per company through the web UI. The day-to-day operations (issuing invoices, tracking their lifecycle) happen almost exclusively through the API.
eDocSync -- For SaaS platforms that use B2Brouter to provide e-invoicing and tax reporting compliance to their own clients. In this scenario, the main platform company is usually onboarded through the web UI, but subsequent account creation and Tax Report Settings configuration for each of their clients is done programmatically through the API. This guide covers the API workflow in detail for this use case.
In both cases, the France-specific compliance features (Annuaire registration, Flux 1/6/10 transmission, CDAR lifecycle) work identically regardless of how the onboarding or invoice creation was performed.
Prerequisites
- French company with a valid SIREN or SIRET number.
- Testing environment (staging)
- Register at app-staging.b2brouter.net to try out the API.
- Once registered, open a Support Ticket in staging to request your API key and permissions.
- Production integration & eDocExchange subscription
- To go live, register at app.b2brouter.net.
- Subscribe to an eDocExchange Product or contact our Sales team at https://www.b2brouter.net/global/contact/ to discuss plans, sign your contract, and receive dedicated integration support.
If you need more details on registration and integration, consult the User Guide and Dev Guide.
Staging environment: DGFiP test identifiers
Important: The France e-invoicing feature is currently in Beta and available only in the staging environment. The following constraint applies to all staging testing, whether performed via the API or the web UI.
B2Brouter's staging environment is connected to the DGFiP's QAS (qualification) environment. The DGFiP does not allow real SIREN or SIRET numbers in their test environment. Instead, each certified PDP is assigned a dedicated set of fictitious test identifiers that must be used for all staging operations.
This means that before you can test the France e-invoicing flow in staging, you must:
- Contact B2Brouter's Service Delivery team to request a set of test identifiers. These are SIREN and SIRET numbers specifically assigned to B2Brouter by the DGFiP for testing purposes.
- Use only the provided test identifiers when creating company accounts and contacts in the staging environment. Any account created with a real or unassigned SIREN/SIRET will not be able to send tax reports to the DGFiP test environment or receive meaningful feedback (CDARs).
Once you have received your test identifiers, the staging testing process is as follows:
- Create your company account using one of the assigned test SIREN/SIRET identifiers.
- Configure the DGFiP Tax Report Setting (this will publish the test identifier in the Annuaire and create the Peppol 0225 transport).
- Create contacts using other assigned test identifiers for the recipient companies.
- Start end-to-end testing: sending invoices, receiving invoices, and managing lifecycle status updates.
To request your test identifiers, contact our Service Delivery team or open a Support Ticket in the staging environment.
Step 1: Retrieve or Create your Company Account
If you haven't yet created a B2Brouter account for your company, use the Create Account endpoint. If you already have an account, retrieve its id with the List Accounts endpoint and skip the creation step.
When creating a French company account, use the following identifiers:
cin_scheme:0002for SIREN or0009for SIRET.cin_value: The SIREN (9 digits) or SIRET (14 digits) of your company.country:fr.
Example request:
curl --request POST \
--url https://api-staging.b2brouter.net/accounts \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Content-Type: application/json' \
--data '{
"account": {
"country": "fr",
"name": "Exemplar SAS",
"address": "10 Rue Imaginaire",
"city": "Paris",
"postalcode": "75001",
"province": "Île-de-France",
"email": "[email protected]",
"tin_value": "FR46458880332",
"tin_scheme": 9957,
"cin_scheme": "0009",
"cin_value": "45888033200015",
"rounding_method": "half_up"
}
}'
Sample response:
{
"account": {
"id": 83428,
"name": "Exemplar SAS",
"tin_value": "FR46458880332",
"tin_scheme": 9957,
"cin_scheme": "0009",
"cin_value": "45888033200015",
"address": "10 Rue Imaginaire",
"city": "Paris",
"postalcode": "75001",
"province": "Île-de-France",
"country": "fr",
"currency": "EUR",
"email": "[email protected]",
"rounding_method": "half_up",
"archived": false,
"created_at": "2026-06-10T09:54:38.000Z",
"updated_at": "2026-06-10T09:54:38.000Z"
}
}
Step 2: Enable Tax Report Settings for DGFiP
This is the key onboarding step. When you create a Tax Report Setting with code: "dgfip", B2Brouter automatically:
- Registers your company in the PPF's Annuaire (directory) as a taxpayer associated with B2Brouter as PDP. This makes your company discoverable by other platforms in the French e-invoicing ecosystem.
- Creates a Peppol transport with scheme
0225for your company, enabling you to receive electronic invoices from other Peppol participants.
Both the Annuaire registration and the Peppol transport creation happen automatically as part of the activation process, whether you create the Tax Report Setting via the API or the web UI.
The start_date field determines when tax reporting will begin and must be today or a future date. From this date onwards:
- Your company will be active in the PPF's Annuaire.
- Invoices issued from B2Brouter will generate tax reports and be transmitted to the PPF.
- You will be able to receive electronic invoices via Peppol.
Example request:
curl --request POST \
--url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/tax_report_settings \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Content-Type: application/json' \
--data '{
"tax_report_setting": {
"code": "dgfip",
"start_date": "2026-09-01",
"type_operation": "services",
"email": "[email protected]"
}
}'
Sample response:
{
"tax_report_setting": {
"code": "dgfip",
"start_date": "2026-09-01",
"auto_generate": true,
"auto_send": true,
"enabled": true,
"type_operation": "services",
"email": "[email protected]",
"locked": false,
"created_at": "2026-06-10T10:15:22.000Z",
"updated_at": "2026-06-10T10:15:22.000Z"
}
}
DGFiP Tax Report Settings fields
| Field | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | Must be "dgfip". |
| start_date | date | Yes | The date from which tax reporting will begin. Must be today or a future date. |
| type_operation | string | No | Default type of operation for your invoices: "services", "goods", or "mixed". Determines the process code used in the PPF flux. |
| string | No | Contact email for tax-related notifications. | |
| auto_generate | boolean | No | Automatically generate tax reports when invoices are issued. Defaults to true and cannot be set to false for DGFiP (legal obligation). |
| auto_send | boolean | No | Automatically send tax reports to the PPF after generation. Defaults to true. |
| enabled | boolean | No | Whether the setting is active. Defaults to true. The Annuaire registration only occurs when the setting is created with enabled: true. |
Important: The
auto_generatefield is automatically set totruefor DGFiP and cannot be changed. Similarly,auto_senddefaults totrue. This ensures that every issued invoice generates a tax report and that the report is immediately transmitted to the PPF, as required by the regulation.
Important: If the Annuaire registration fails (e.g., due to an invalid SIREN/SIRET or a temporary service outage), the Tax Report Setting creation will be rolled back and an error will be returned. You must correct the issue and retry the creation.
What happens during activation
When the Tax Report Setting is created with enabled: true, B2Brouter performs the following actions behind the scenes:
-
Annuaire registration: B2Brouter publishes your company's identifier (SIREN or SIREN_SIRET, depending on your
cin_scheme) to the PPF's Annuaire, associating it with B2Brouter's PDP matricule. If your company was previously registered with another PDP, B2Brouter will close the existing directory line and create a new one. -
Peppol 0225 transport: B2Brouter creates a Peppol transport endpoint for your company using the
0225scheme (French Annuaire identifier). This enables your company to receive electronic invoices from any Peppol-connected platform in the French ecosystem.
Tax Report Settings - API Reference
Step 3: Verify recipient information
Before sending an invoice, you can check if the recipient exists in the B2Brouter Directory. For French B2B recipients, this allows you to verify their SIREN/SIRET and determine their preferred delivery channel.
Example request:
curl --request GET \
--url 'https://api-staging.b2brouter.net/directory/fr/0009/45888033200015' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13'
GET Lookup Directory - API Reference
Step 4: Create a Contact
When creating a French B2B customer contact, use the following fields:
cin_scheme:0002for SIREN or0009for SIRET.cin_value: The SIREN or SIRET of your customer.country:fr.
Note that you do not need to specify transport_type_code or document_type_code for French B2B contacts. B2Brouter will automatically determine the correct transport and document type based on the contact's country and the applicable regulations.
Example request:
curl --request POST \
--url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/contacts \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Content-Type: application/json' \
--data '{
"contact": {
"name": "Client Exemple SARL",
"address": "25 Avenue de la République",
"city": "Lyon",
"postalcode": "69001",
"country": "fr",
"currency": "EUR",
"language": "fr",
"is_client": true,
"cin_scheme": "0009",
"cin_value": "73282932000074"
}
}'
Sample response:
{
"contact": {
"id": 1313228381,
"name": "Client Exemple SARL",
"address": "25 Avenue de la République",
"city": "Lyon",
"postalcode": "69001",
"country": "fr",
"currency": "EUR",
"language": "fr",
"is_client": true,
"cin_scheme": "0009",
"cin_value": "73282932000074",
"created_at": "2026-06-18T07:19:32Z",
"updated_at": "2026-06-18T07:19:32Z"
}
}
Issuing Invoices
Once your company is onboarded and the Tax Report Setting for DGFiP is enabled, you can issue invoices as you normally would. The system handles all France-specific requirements automatically, regardless of whether the invoice is created via the API or the web UI.
Create and send an Invoice
To create and send an invoice in one step, use the "Create an issued invoice" call with the flag send_after_import: true. When the invoice is created, B2Brouter will automatically:
- Generate the DGFiP tax report from the invoice data.
- Produce the UBL 2.1 XML compliant with the French customization.
- Transmit the invoice to the PPF via Flux 1.
France-specific invoice fields
When creating an invoice for a French B2B customer, the following fields are relevant:
- Payment information is mandatory for French e-invoices. Use the
extra_infofield to provide:#PMD#<remittance_information>#PMD#: Remittance reference or payment details.#PMT#<payment_information>#PMT#: Payment means (e.g., bank transfer details).#AAB#<payment_terms>#AAB#: Payment terms description.
currency: Must be specified. TypicallyEURfor domestic French transactions.- Invoice number: Maximum 20 characters, only alphanumeric characters, spaces, and
-+_/are allowed.
Example request:
curl --request POST \
--url https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Content-Type: application/json' \
--data '{
"send_after_import": true,
"invoice": {
"type": "IssuedInvoice",
"contact_id": 1313228381,
"number": "FA-2026-0048",
"date": "2026-09-15",
"due_date": "2026-10-15",
"currency": "EUR",
"payment_method": 4,
"extra_info": "#PMD#FA-2026-0048#PMD# #PMT#30: Credit Transfer, IBAN FR76 3000 6000 0112 3456 7890 189, BIC AGRIFRPP#PMT# #AAB#Net 30 days from invoice date#AAB#",
"invoice_lines_attributes": [
{
"quantity": 10.0,
"description": "Consulting services - Software architecture review",
"price": 150.0,
"unit": 9,
"taxes_attributes": [
{
"name": "TVA",
"percent": 20.0,
"category": "S"
}
]
},
{
"quantity": 5.0,
"description": "Training sessions - API integration",
"price": 200.0,
"unit": 9,
"taxes_attributes": [
{
"name": "TVA",
"percent": 20.0,
"category": "S"
}
]
}
]
}
}'
Sample response:
{
"invoice": {
"id": 4919734,
"type": "IssuedInvoice",
"number": "FA-2026-0048",
"from_net": "api",
"account": {
"id": 83428,
"name": "Exemplar SAS"
},
"company": {
"id": 100446,
"name": "Exemplar SAS",
"tin_value": "FR46458880332",
"address": "10 Rue Imaginaire",
"postalcode": "75001",
"city": "Paris",
"province": "Île-de-France",
"country": "fr"
},
"contact": {
"id": 1313228381,
"name": "Client Exemple SARL",
"address": "25 Avenue de la République",
"postalcode": "69001",
"city": "Lyon",
"country": "fr"
},
"state": "sending",
"date": "2026-09-15",
"due_date": "2026-10-15",
"subtotal": 2500.0,
"taxes": [
{
"name": "TVA 20,00%",
"percent": 20.0,
"base": 2500.0,
"amount": 500.0
}
],
"total": 3000.0,
"currency": "EUR",
"payable_amount": 3000.0,
"tax_report_ids": [
42
],
"created_at": "2026-09-15T09:54:42Z",
"updated_at": "2026-09-15T09:54:45Z",
"state_updated_at": "2026-09-15T09:54:45Z"
}
}
In the response, the tax_report_ids array contains the ID of the tax report associated with the invoice. You can use this ID to track the tax report's lifecycle independently (see Check the state of a Tax Report).
Process codes
The process code determines the PPF flux cadre used for the invoice. B2Brouter assigns the process code automatically based on the type_operation configured in the Tax Report Setting and the invoice characteristics.
| Process Code | Type of Operation | Description |
|---|---|---|
| S1 | Services | Standard invoice for services |
| B1 | Goods | Standard invoice for goods |
| M1 | Mixed | Standard invoice for mixed operations |
| S2 | Services | Paid invoice for services |
| B2 | Goods | Paid invoice for goods |
| S4 | Services | Invoice with payments on account for services |
| B4 | Goods | Invoice with payments on account for goods |
| M4 | Mixed | Invoice with payments on account for mixed |
| S7 | Services | Correction of a registered invoice (services) |
| B7 | Goods | Correction of a registered invoice (goods) |
Credit notes
To issue a credit note, create an invoice with is_amend: true and reference the original invoice. B2Brouter will generate the appropriate Flux 1 credit note (UBL CreditNote with type code 381) and include the billing reference to the amended invoice.
Invoice Lifecycle
The lifecycle of a French e-invoice involves multiple status transitions as the invoice moves through the PPF and reaches the buyer. B2Brouter tracks these transitions and updates the invoice state accordingly.
Invoice states
After creating and sending an invoice, the following states are possible:
| State | Description |
|---|---|
| sending | The invoice has been created and is queued for transmission to the PPF. |
| sent | The invoice XML has been successfully uploaded to the PPF (Flux 1 deposit confirmed). |
| registered | The PPF has validated and accepted the invoice (CDV Flux 1 positive validation). |
| accepted | The buyer has approved the invoice. |
| refused | The buyer has rejected the invoice. |
| allegedly_paid | The buyer has reported the invoice as paid. |
| error | An error occurred during transmission or PPF validation (CDV Flux 1 negative validation). |
Tracking invoice states
You have two options to track the lifecycle of your invoices:
Webhooks (recommended)
Subscribe to invoice state change webhooks. B2Brouter will send an HTTP POST to your endpoint each time the invoice reaches a new state. This is the most efficient approach as it eliminates the need for polling.
Invoice Status WebHooks - API Reference
Polling
Query the status of each invoice using its internal ID with the "Get an invoice" API. You can also list all invoices filtered by state_updated_at_from to only retrieve invoices that have changed since your last check.
Example request:
curl --request GET \
--url 'https://api-staging.b2brouter.net/invoices/{INVOICE_ID}' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Accept: application/json'
Download the original Invoice XML
After an invoice has been sent, the GET /invoices/{id} response includes a download_legal_url field. Use that URL to fetch the exact UBL XML file that was submitted to the PPF:
curl --request GET \
--url 'https://api-staging.b2brouter.net{download_legal_url}' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Accept: application/xml'
Check the state of a Tax Report
The tax report generated from your invoice tracks the technical lifecycle of the submission to the PPF. The state field of the tax report will always be processing immediately after invoice creation, because both the XML generation and the transmission to the PPF are asynchronous background processes.
You must check the lifecycle of the tax report. You have two options:
-
Webhooks (recommended): Subscribe to the tax report webhook. B2Brouter will issue a POST call to your system each time the tax report reaches a final state: registered, error, or annulled.
-
Polling: Query the state of the tax report by calling the get tax report endpoint with the tax report ID (available in the
tax_report_idsfield of the invoice response) until the state is registered, error, or annulled.
Tax Report API
Coming soon: A dedicated Tax Report API for DGFiP will be available in a future release. This API will allow you to create, manage, and submit tax reports independently of the invoice workflow -- similar to the Verifactu Tax Report API. It will support both JSON payloads and UBL XML import.
In the current release, tax reports for France are generated automatically from invoices when the DGFiP Tax Report Setting is enabled with
auto_generate: true.
e-Reporting (Flux 10)
Coming soon: Flux 10 e-Reporting will be available soon. It will work through the standard Invoice API -- tax reports will be generated automatically from invoices, just like Flux 1.
Flux 10 covers transactions that fall outside the scope of the domestic B2B e-invoicing obligation but must still be reported to the DGFiP. There are two distinct cases:
B2C transactions
Sales to non-VAT-registered individuals in France. Since there is no buyer PDP to receive the invoice, the transaction data must be reported directly to the PPF. B2Brouter will generate the e-Reporting tax report automatically from IssuedSimplifiedInvoice documents.
Cross-border transactions
Sales to or purchases from companies established outside France (both intra-EU and extra-EU). These transactions are outside the scope of the domestic e-invoicing obligation but must still be reported to the DGFiP for VAT control purposes. B2Brouter will generate the e-Reporting tax report automatically from regular IssuedInvoice and ReceivedInvoice documents when the counterparty is not a French company.
Receiving Invoices
As a French company registered in the PPF's Annuaire with a Peppol 0225 transport, you can receive electronic invoices from other French companies. Incoming invoices are automatically processed by B2Brouter and made available through the API.
Invoice lifecycle for received invoices
When you receive an invoice, you must communicate its status back to the PPF and to the sender. B2Brouter handles this automatically through CDAR (Cross-Domain Acknowledgement and Response) messages whenever you update the invoice state.
The following actions on received invoices trigger CDAR notifications:
| Invoice Action | CDAR Status Code | Description |
|---|---|---|
| Deposited | 200 (Déposée) | The invoice has been deposited and registered in the PPF. |
| Received | 202 (Reçue) | The invoice has been received by the buyer. |
| Approved | 205 (Approuvée) | The buyer has approved the invoice for payment. |
| Refused | 210 (Refusée) | The buyer has rejected the invoice. |
| Paid | 212 (Encaissée) | The buyer has reported the invoice as paid. |
| Rejected | 213 (Rejetée) | The PPF has rejected the invoice at reception. |
Listing received invoices
Use the "List received invoices" endpoint to retrieve invoices received from your customers and suppliers.
Example request:
curl --request GET \
--url 'https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices?type=ReceivedInvoice&offset=0&limit=25' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: v2025-10-13' \
--header 'Accept: application/json'
For further help:
- API Reference
- Tax Report Settings Guide
- Chorus Pro Guide (B2G) -- for invoicing French public-sector entities
- Support
- Contact us
Updated about 3 hours ago