> ## Documentation Index
> Fetch the complete documentation index at: https://invopop-link-fix.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Chargebee in France

> Route Chargebee invoices through France's e-invoicing and e-reporting flows

export const chargebeeCbFranceWorkflow = {
  "name": "Chargebee France send invoice",
  "description": "Send French invoice through Peppol network and to the PPF",
  "schema": "bill/invoice",
  "steps": [{
    "id": "30960320-a44d-11f0-b23b-fd08a0f26c87",
    "name": "Import Chargebee document",
    "provider": "chargebee.import"
  }, {
    "id": "66cdc390-485f-11f1-86b7-9745cc4d2380",
    "name": "Download PDF",
    "provider": "chargebee.pdf.download"
  }, {
    "id": "33e23480-10ab-11f0-a09e-7b63571a4ae2",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `processing`{.state .processing}",
    "config": {
      "state": "processing"
    }
  }, {
    "id": "eea78ac0-26f0-11f1-9156-e518ebabd527",
    "name": "Add billing mode",
    "provider": "silo.modify",
    "notes": "S2 (already-paid) ONLY when fully paid (totals.advance == total_with_tax); else S1. S2 also adds payment.terms due_dates (BR-FR-CO-09). Reads .totals.advance (NOT the old .advances bug).",
    "summary": "Modifications configured",
    "config": {
      "jq": ".tax.ext = (.tax.ext // {})\n| .tax.point = \"issue\"\n| if ((.totals.advance // null) != null and (.totals.advance == .totals.total_with_tax)) then\n    .tax.ext[\"fr-ctc-billing-mode\"] = \"S2\"\n    | .payment = (.payment // {})\n    | .payment.terms = (.payment.terms // {\"due_dates\":[{\"date\":.issue_date,\"percent\":\"100%\"}]})\n  else\n    .tax.ext[\"fr-ctc-billing-mode\"] = \"S1\"\n  end",
      "merge_type": "application/jq",
      "scope": "doc"
    }
  }, {
    "id": "4f427d80-a44d-11f0-b23b-fd08a0f26c87",
    "name": "Add VATEX",
    "provider": "silo.modify",
    "summary": "Modifications configured",
    "config": {
      "jq": ".lines |= map(\n  .taxes |= map(\n    (.ext[\"untdid-tax-category\"]? as $cat\n     | if $cat then\n         {\n           key: {\n             \"AE\": \"reverse-charge\",\n             \"E\": \"export\",\n             \"G\": \"export\",\n             \"O\": \"outside-scope\",\n             \"K\": \"intra-community\"\n           }[$cat],\n           vatex: {\n             \"AE\": \"VATEX-EU-AE\",\n             \"G\": \"VATEX-EU-G\",\n             \"O\": \"VATEX-EU-O\",\n             \"K\": \"VATEX-EU-IC\"\n           }[$cat]\n         } as $m\n\n         | if $m.key then .key = $m.key else . end\n         | if $m.vatex then\n             .ext = ((.ext // {}) + {\"cef-vatex\": $m.vatex})\n           else\n             .\n           end\n       else\n         .\n       end\n    )\n  )\n)",
      "merge_type": "application/jq",
      "scope": "doc",
      "sign": false
    }
  }, {
    "id": "7dad54c0-154a-11f0-8028-c1ed648b57b5",
    "name": "Add bank details",
    "provider": "silo.modify",
    "notes": "Normalizes the payment key to SEPA credit transfer format",
    "summary": "Modifications configured",
    "config": {
      "allow_invalid_json": false,
      "data": {
        "doc": {
          "payment": {
            "instructions": {
              "credit_transfer": [{
                "bic": "",
                "iban": ""
              }],
              "key": "credit-transfer"
            }
          }
        }
      },
      "expr": "(doc?.payment?.instructions == nil || doc?.payment?.instructions?.key == \"credit-transfer\")\n&& doc?.payment?.terms?.due_dates != nil",
      "merge_type": "application/merge-patch+json",
      "sign": false
    }
  }, {
    "id": "fb06b190-10aa-11f0-a09e-7b63571a4ae2",
    "name": "Sign envelope",
    "provider": "silo.close"
  }, {
    "id": "de2407b0-5e94-11f1-90fe-f3d836f89160",
    "name": "Lookup in Directory",
    "provider": "gov-fr.directory.lookup",
    "next": [{
      "status": "NA",
      "code": "found",
      "steps": [{
        "id": "3ffd50e0-5e95-11f1-90fe-f3d836f89160",
        "name": "Add flow2 addon",
        "provider": "silo.modify",
        "summary": "Modifications configured",
        "config": {
          "addons": ["fr-ctc-flow2-v1"]
        }
      }, {
        "id": "1f8bf500-5e95-11f1-90fe-f3d836f89160",
        "name": "Generate UBL document",
        "provider": "ubl.generate",
        "summary": "Peppol France CIUS UBL Invoice/CreditNote",
        "config": {
          "attach_invoice_pdf": false,
          "doc_type": "peppol-fr-cius",
          "private": false
        }
      }, {
        "id": "9e22f4a0-485f-11f1-86b7-9745cc4d2380",
        "name": "Record document for e-invoicing",
        "provider": "gov-fr.directory.record"
      }, {
        "id": "285c9450-5e95-11f1-90fe-f3d836f89160",
        "name": "Send Peppol Document",
        "provider": "peppol.send"
      }, {
        "id": "2d6926c0-5e95-11f1-90fe-f3d836f89160",
        "name": "Forward document to PPF",
        "provider": "gov-fr.directory.forward"
      }]
    }, {
      "status": "NA",
      "code": "not-found",
      "steps": [{
        "id": "5cff2420-7470-11f1-9deb-cda1ffc5317f",
        "name": "Add flow10 addon",
        "provider": "silo.modify",
        "summary": "Modifications configured",
        "config": {
          "addons": ["fr-ctc-flow10-v1"]
        }
      }, {
        "id": "3a023fc0-5e95-11f1-90fe-f3d836f89160",
        "name": "Record document for reporting",
        "provider": "gov-fr.reporting.record"
      }, {
        "id": "aaf85b90-6996-11f1-8722-e7a7821bd54f",
        "name": "Verify invoice can be sent",
        "provider": "peppol.has.inboxes",
        "next": [{
          "status": "NA",
          "code": "true",
          "steps": [{
            "id": "afcc78e0-6996-11f1-8722-e7a7821bd54f",
            "name": "Generate UBL document",
            "provider": "ubl.generate",
            "summary": "Peppol BIS Billing UBL Invoice/CreditNote V3",
            "config": {
              "attach_invoice_pdf": false,
              "doc_type": "bis-invoice-v3",
              "private": false
            }
          }, {
            "id": "b798c790-6996-11f1-8722-e7a7821bd54f",
            "name": "Send Peppol document",
            "provider": "peppol.send"
          }]
        }, {
          "status": "NA",
          "code": "false"
        }]
      }]
    }]
  }, {
    "id": "3037a310-10ab-11f0-a09e-7b63571a4ae2",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `sent`{.state .sent}",
    "config": {
      "state": "sent"
    }
  }, {
    "id": "354dbed0-a44d-11f0-b23b-fd08a0f26c87",
    "name": "Update Chargebee",
    "provider": "chargebee",
    "config": {
      "document_select": "xml"
    }
  }],
  "rescue": [{
    "id": "39513240-10ab-11f0-a09e-7b63571a4ae2",
    "name": "Set state",
    "provider": "silo.state",
    "summary": "Set state to `error`{.state .error}",
    "config": {
      "state": "error"
    }
  }, {
    "id": "38fd0b30-a44d-11f0-b23b-fd08a0f26c87",
    "name": "Update Chargebee",
    "provider": "chargebee",
    "config": {
      "document_select": "xml"
    }
  }]
};

export const WorkflowDiagram = ({workflow}) => {
  const stateColors = {
    processing: "yellow",
    sent: "blue",
    received: "blue",
    registered: "green",
    completed: "green",
    error: "red"
  };
  const StateChip = ({state, label}) => <Badge size="sm" color={stateColors[state] || "gray"} icon="square-small" iconType="solid">
      {label.charAt(0).toUpperCase() + label.slice(1)}
    </Badge>;
  const providerIcons = {
    "silo.state": "https://silo.invopop.com/images/status.svg",
    "silo.close": "https://silo.invopop.com/images/check-badge.svg",
    "silo.if": "https://assets.invopop.com/apps/silo/if.svg",
    "silo.folder": "https://silo.invopop.com/images/folder.svg",
    "silo.modify": "https://silo.invopop.com/images/modify.svg",
    "silo.correct": "https://silo.invopop.com/images/replace.svg",
    "silo.sleep": "https://assets.invopop.com/icons/sleep.svg",
    silo: "https://assets.invopop.com/apps/silo/icon.svg",
    "sequence.enumerate": "https://sequence.invopop.com/images/enumerate.svg",
    "transform.job.create": "https://transform.invopop.com/images/jobs.svg",
    webhook: "https://webhook.invopop.com/icon.svg",
    lookup: "https://lookup.invopop.com/icon.png",
    dropbox: "https://dropbox.invopop.com/icon.png",
    pdf: "https://pdf.invopop.com/file-pdf.svg",
    peppol: "https://assets.invopop.com/apps/peppol/icon.svg",
    ubl: "https://assets.invopop.com/apps/ubl/logo.svg",
    cii: "https://assets.invopop.com/apps/cii/logo.svg",
    "gov-fr": "https://assets.invopop.com/flags/fr.svg",
    "chorus-pro": "https://assets.invopop.com/apps/chroruspro/icon.svg",
    "gov-es": "https://assets.invopop.com/apps/gov-es/icon.svg",
    "gov-es.sii": "https://assets.invopop.com/apps/sii/icon.svg",
    "gov-es.ticketbai": "https://assets.invopop.com/apps/ticketbai/icon.svg",
    "gov-es.facturae": "https://assets.invopop.com/apps/facturae/icon.svg",
    verifactu: "https://assets.invopop.com/apps/verifactu/icon.svg",
    "gov-pl": "https://assets.invopop.com/apps/ksef/icon.svg",
    "gov-sa": "https://assets.invopop.com/apps/zatca/icon.svg",
    "gov-ar": "https://assets.invopop.com/apps/arca/icon.svg",
    "at-pt": "https://assets.invopop.com/apps/at-pt/icon.svg",
    "sat-mx": "https://assets.invopop.com/apps/sat-mexico/icon.svg",
    "sw-sapien": "https://assets.invopop.com/apps/sw-sapien/icon.svg",
    "sdi-it": "https://assets.invopop.com/apps/sdi-italy/icon.svg",
    "ticket-it": "https://assets.invopop.com/apps/agenzia-entrate/icon.svg",
    "nfe-br": "https://assets.invopop.com/apps/notas-fiscais-eletronicas-brazil/icon.svg",
    chargebee: "https://assets.invopop.com/apps/chargebee/icon.svg",
    stripe: "https://assets.invopop.com/apps/stripe/icon.svg",
    email: "https://assets.invopop.com/apps/email/icon.svg",
    cron: "https://assets.invopop.com/apps/cron/icon.svg",
    ilyda: "https://assets.invopop.com/apps/ilyda/icon.svg",
    invoicexpress: "https://assets.invopop.com/apps/invoicexpress/icon.svg",
    plemsi: "https://assets.invopop.com/flags/co.svg"
  };
  const iconFor = provider => {
    const parts = (provider || "").split(".");
    for (let i = parts.length; i > 0; i--) {
      const url = providerIcons[parts.slice(0, i).join(".")];
      if (url) return url;
    }
    return null;
  };
  const StepIcon = ({provider}) => {
    const url = iconFor(provider);
    return <span title={provider} className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-gray-950/10 bg-white dark:border-white/10 dark:bg-white/5">
        {url ? <img src={url} alt="" className="h-4 w-4" /> : null}
      </span>;
  };
  const renderSummary = summary => {
    const nodes = [];
    const re = /`([^`]+)`(\{[^}]*\})?/g;
    let last = 0;
    let m;
    let k = 0;
    while ((m = re.exec(summary)) !== null) {
      if (m.index > last) nodes.push(summary.slice(last, m.index));
      const attrs = m[2] || "";
      if (attrs.indexOf(".state") >= 0) {
        const state = (attrs.match(/\.state\s+\.([\w-]+)/) || [])[1] || m[1];
        nodes.push(<StateChip key={k++} state={state} label={m[1]} />);
      } else if (attrs) {
        nodes.push(<span key={k++} className="text-sm font-medium text-gray-700 dark:text-gray-300">
            {m[1]}
          </span>);
      } else {
        nodes.push(<code key={k++} className="text-sm rounded bg-gray-100 px-1 font-mono text-sm dark:bg-white/10">
            {m[1]}
          </code>);
      }
      last = m.index + m[0].length;
    }
    if (last < summary.length) nodes.push(summary.slice(last));
    return nodes;
  };
  const NoteRow = ({text}) => <div className="mt-4 mb-1 font-mono text-sm leading-5 text-gray-400 dark:text-gray-500">{"// " + text}</div>;
  const renderSteps = (steps, counter) => (steps || []).map(step => {
    counter.n += 1;
    const n = counter.n;
    const branches = (step.next || []).filter(b => b.steps && b.steps.length > 0);
    return <div key={step.id || "step-" + n}>
          {step.notes ? <NoteRow text={step.notes} /> : null}
          <div className="mt-2.5 flex items-center">
            <span className="absolute left-0 w-10 text-center font-mono text-sm text-gray-400 select-none dark:text-gray-500">
              {n}
            </span>
            <div className="flex min-w-0 flex-1 items-center gap-2 rounded-xl border border-gray-950/5 bg-white px-2 py-2 dark:border-white/10 dark:bg-gray-900">
              <StepIcon provider={step.provider} />
              <span className="text-sm shrink-0 font-medium text-gray-900 dark:text-gray-100">{step.name}</span>
              {step.summary ? <span className="text-sm min-w-0 truncate text-gray-500 dark:text-gray-400">{renderSummary(step.summary)}</span> : null}
            </div>
          </div>
          {branches.length > 0 ? <div className="ml-5 border-l border-gray-200 -my-1 py-1 pl-6 dark:border-white/10">
              {branches.map((branch, bi) => <div key={branch.code || branch.status || bi}>
                  <div className="mt-4">
                    <span className="rounded-md bg-gray-200/70 px-2 py-1 font-mono text-sm text-gray-600 dark:bg-white/10 dark:text-gray-300">
                      {branch.code || branch.status}
                    </span>
                  </div>
                  {renderSteps(branch.steps, counter)}
                </div>)}
            </div> : null}
        </div>;
  });
  const counter = {
    n: 0
  };
  const wf = workflow || ({});
  return <div className="not-prose relative my-5 rounded-2xl border border-gray-950/5 bg-gray-50 py-3 pr-4 pb-5 pl-12 dark:border-white/10 dark:bg-white/[0.03]">
      {renderSteps(wf.steps, counter)}
      {wf.rescue && wf.rescue.length > 0 ? <div className="mt-6 border-t border-dashed border-gray-300 dark:border-white/10">
          <NoteRow text="If any step fails" />
          {renderSteps(wf.rescue, counter)}
        </div> : null}
    </div>;
};

France runs two parallel flows, and which one an invoice takes depends on whether the customer is registered in the **Annuaire** (the French directory).

* Customers subject to VAT in France are handled through the [e-invoicing flow](/guides/fr-pa-invoicing#sending) for domestic B2B transactions, with [status updates](/guides/fr-pa-status) reported back throughout.
* Customers not subject to VAT in France — international or B2C transactions, and territories excluded from the mandate such as Guyane, Mayotte, New Caledonia and French Polynesia — go through [e-reporting](/guides/fr-pa-reporting) instead.

This guide assumes you have already connected the Chargebee app and completed the general setup — see the [Chargebee overview](/guides/chargebee) first if you haven't.

**Required apps:** [France](/apps/france), [Peppol](/apps/peppol), [OASIS UBL](/apps/oasis-ubl)

<Info>
  Before processing any invoices, you must register your supplier in the Annuaire through Invopop. See the [registration guide](/guides/fr-pa-registration) for the e-invoicing flow and the [e-reporting registration steps](/guides/fr-pa-reporting#registration) for the reporting flow.
</Info>

## Workflow

A single template covers both French flows and picks between them automatically from the result of the **Lookup in Directory** step.

* **found** result means the customer is subject to e-invoicing, so Invopop records the document in the Annuaire, forwards it to the PPF, and sends it over Peppol.
* **not found** result means the transaction falls outside domestic e-invoicing — international B2B, B2C, or a customer in a territory excluded from the mandate — so it is recorded for e-reporting. For those, the **Can Send** action checks whether the customer is reachable on the Peppol network: if it is (a Belgian party, for example), the workflow sends the invoice over Peppol as well.

<Card title="Chargebee France" icon="code-branch" iconType="duotone" href="https://console.invopop.com/redirect/workflows/new?template=chargebee-cb-france" horizontal>
  Add to my workspace →
</Card>

<Tabs>
  <Tab title="Workflow">
    <WorkflowDiagram workflow={chargebeeCbFranceWorkflow} />
  </Tab>

  <Tab title="Code">
    <Note>
      The two paths differ in the addon and format they apply: the e-invoicing path applies the `fr-ctc-flow2-v1` addon and generates a Peppol France CIUS UBL, while the e-reporting path applies `fr-ctc-flow10-v1` and, when the customer is reachable on Peppol, generates a Peppol BIS Billing v3 document.
    </Note>

    <Note>
      The **Add bank details** step includes placeholder `bic` and `iban` fields that you must fill in with your own banking details. It only applies when the invoice carries payment due dates and the payment key is a plain `credit-transfer`, normalizing it to the SEPA format France expects. If you don't need to include payment instructions, you can remove this step.
    </Note>

    <Note>
      The **Add Billing Mode** step sets the French CTC billing mode: `S2` when the invoice is fully paid (an advance equal to the total), otherwise `S1`. The subsequent **Add VATEX** step maps UNTDID tax categories onto the GOBL tax keys and adds the `VATEX` exemption codes required by the French format.
    </Note>

    ```json Example Chargebee France workflow theme={null}
    {
        "name": "Chargebee France send invoice",
        "description": "Send French invoice through Peppol network and to the PPF",
        "schema": "bill/invoice",
        "steps": [
            {
                "id": "30960320-a44d-11f0-b23b-fd08a0f26c87",
                "name": "Import Chargebee document",
                "provider": "chargebee.import"
            },
            {
                "id": "66cdc390-485f-11f1-86b7-9745cc4d2380",
                "name": "Download PDF",
                "provider": "chargebee.pdf.download"
            },
            {
                "id": "33e23480-10ab-11f0-a09e-7b63571a4ae2",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `processing`{.state .processing}",
                "config": {
                    "state": "processing"
                }
            },
            {
                "id": "eea78ac0-26f0-11f1-9156-e518ebabd527",
                "name": "Add billing mode",
                "provider": "silo.modify",
                "notes": "S2 (already-paid) ONLY when fully paid (totals.advance == total_with_tax); else S1. S2 also adds payment.terms due_dates (BR-FR-CO-09). Reads .totals.advance (NOT the old .advances bug).",
                "summary": "Modifications configured",
                "config": {
                    "jq": ".tax.ext = (.tax.ext // {})\n| .tax.point = \"issue\"\n| if ((.totals.advance // null) != null and (.totals.advance == .totals.total_with_tax)) then\n    .tax.ext[\"fr-ctc-billing-mode\"] = \"S2\"\n    | .payment = (.payment // {})\n    | .payment.terms = (.payment.terms // {\"due_dates\":[{\"date\":.issue_date,\"percent\":\"100%\"}]})\n  else\n    .tax.ext[\"fr-ctc-billing-mode\"] = \"S1\"\n  end",
                    "merge_type": "application/jq",
                    "scope": "doc"
                }
            },
            {
                "id": "4f427d80-a44d-11f0-b23b-fd08a0f26c87",
                "name": "Add VATEX",
                "provider": "silo.modify",
                "summary": "Modifications configured",
                "config": {
                    "jq": ".lines |= map(\n  .taxes |= map(\n    (.ext[\"untdid-tax-category\"]? as $cat\n     | if $cat then\n         {\n           key: {\n             \"AE\": \"reverse-charge\",\n             \"E\": \"export\",\n             \"G\": \"export\",\n             \"O\": \"outside-scope\",\n             \"K\": \"intra-community\"\n           }[$cat],\n           vatex: {\n             \"AE\": \"VATEX-EU-AE\",\n             \"G\": \"VATEX-EU-G\",\n             \"O\": \"VATEX-EU-O\",\n             \"K\": \"VATEX-EU-IC\"\n           }[$cat]\n         } as $m\n\n         | if $m.key then .key = $m.key else . end\n         | if $m.vatex then\n             .ext = ((.ext // {}) + {\"cef-vatex\": $m.vatex})\n           else\n             .\n           end\n       else\n         .\n       end\n    )\n  )\n)",
                    "merge_type": "application/jq",
                    "scope": "doc",
                    "sign": false
                }
            },
            {
                "id": "7dad54c0-154a-11f0-8028-c1ed648b57b5",
                "name": "Add bank details",
                "provider": "silo.modify",
                "notes": "Normalizes the payment key to SEPA credit transfer format",
                "summary": "Modifications configured",
                "config": {
                    "allow_invalid_json": false,
                    "data": {
                        "doc": {
                            "payment": {
                                "instructions": {
                                    "credit_transfer": [
                                        {
                                            "bic": "",
                                            "iban": ""
                                        }
                                    ],
                                    "key": "credit-transfer"
                                }
                            }
                        }
                    },
                    "expr": "(doc?.payment?.instructions == nil || doc?.payment?.instructions?.key == \"credit-transfer\")\n&& doc?.payment?.terms?.due_dates != nil",
                    "merge_type": "application/merge-patch+json",
                    "sign": false
                }
            },
            {
                "id": "fb06b190-10aa-11f0-a09e-7b63571a4ae2",
                "name": "Sign envelope",
                "provider": "silo.close"
            },
            {
                "id": "de2407b0-5e94-11f1-90fe-f3d836f89160",
                "name": "Lookup in Directory",
                "provider": "gov-fr.directory.lookup",
                "next": [
                    {
                        "status": "NA",
                        "code": "found",
                        "steps": [
                            {
                                "id": "3ffd50e0-5e95-11f1-90fe-f3d836f89160",
                                "name": "Add flow2 addon",
                                "provider": "silo.modify",
                                "summary": "Modifications configured",
                                "config": {
                                    "addons": [
                                        "fr-ctc-flow2-v1"
                                    ]
                                }
                            },
                            {
                                "id": "1f8bf500-5e95-11f1-90fe-f3d836f89160",
                                "name": "Generate UBL document",
                                "provider": "ubl.generate",
                                "summary": "Peppol France CIUS UBL Invoice/CreditNote",
                                "config": {
                                    "attach_invoice_pdf": false,
                                    "doc_type": "peppol-fr-cius",
                                    "private": false
                                }
                            },
                            {
                                "id": "9e22f4a0-485f-11f1-86b7-9745cc4d2380",
                                "name": "Record document for e-invoicing",
                                "provider": "gov-fr.directory.record"
                            },
                            {
                                "id": "285c9450-5e95-11f1-90fe-f3d836f89160",
                                "name": "Send Peppol Document",
                                "provider": "peppol.send"
                            },
                            {
                                "id": "2d6926c0-5e95-11f1-90fe-f3d836f89160",
                                "name": "Forward document to PPF",
                                "provider": "gov-fr.directory.forward"
                            }
                        ]
                    },
                    {
                        "status": "NA",
                        "code": "not-found",
                        "steps": [
                            {
                                "id": "5cff2420-7470-11f1-9deb-cda1ffc5317f",
                                "name": "Add flow10 addon",
                                "provider": "silo.modify",
                                "summary": "Modifications configured",
                                "config": {
                                    "addons": [
                                        "fr-ctc-flow10-v1"
                                    ]
                                }
                            },
                            {
                                "id": "3a023fc0-5e95-11f1-90fe-f3d836f89160",
                                "name": "Record document for reporting",
                                "provider": "gov-fr.reporting.record"
                            },
                            {
                                "id": "aaf85b90-6996-11f1-8722-e7a7821bd54f",
                                "name": "Verify invoice can be sent",
                                "provider": "peppol.has.inboxes",
                                "next": [
                                    {
                                        "status": "NA",
                                        "code": "true",
                                        "steps": [
                                            {
                                                "id": "afcc78e0-6996-11f1-8722-e7a7821bd54f",
                                                "name": "Generate UBL document",
                                                "provider": "ubl.generate",
                                                "summary": "Peppol BIS Billing UBL Invoice/CreditNote V3",
                                                "config": {
                                                    "attach_invoice_pdf": false,
                                                    "doc_type": "bis-invoice-v3",
                                                    "private": false
                                                }
                                            },
                                            {
                                                "id": "b798c790-6996-11f1-8722-e7a7821bd54f",
                                                "name": "Send Peppol document",
                                                "provider": "peppol.send"
                                            }
                                        ]
                                    },
                                    {
                                        "status": "NA",
                                        "code": "false"
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "id": "3037a310-10ab-11f0-a09e-7b63571a4ae2",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `sent`{.state .sent}",
                "config": {
                    "state": "sent"
                }
            },
            {
                "id": "354dbed0-a44d-11f0-b23b-fd08a0f26c87",
                "name": "Update Chargebee",
                "provider": "chargebee",
                "config": {
                    "document_select": "xml"
                }
            }
        ],
        "rescue": [
            {
                "id": "39513240-10ab-11f0-a09e-7b63571a4ae2",
                "name": "Set state",
                "provider": "silo.state",
                "summary": "Set state to `error`{.state .error}",
                "config": {
                    "state": "error"
                }
            },
            {
                "id": "38fd0b30-a44d-11f0-b23b-fd08a0f26c87",
                "name": "Update Chargebee",
                "provider": "chargebee",
                "config": {
                    "document_select": "xml"
                }
            }
        ]
    }

    ```
  </Tab>
</Tabs>

## Customer routing & identifiers

A single SIREN registered in the Annuaire can have several directory entries, registered under the same or different Plateformes Agréées. Each entry has a unique identifier — mapped to the Peppol inbox — in one of the `SIREN`, `SIREN_SIRET`, `SIREN_SIRET_suffix` or `SIREN_suffix` forms. When no Peppol inbox is set on the customer, Invopop defaults to `0225:SIREN`, ignoring any SIRET present in the customer's identities.

Use the custom fields below to control this. Set the **Peppol inbox** to target a specific directory entry, or provide the customer's **SIREN** and **SIRET** so the directory lookup can resolve them. All three are configured as **Single line text** custom fields (or as metadata, using the hyphenated key):

| Field        | Metadata key                   | Custom field key                  | Example               |
| ------------ | ------------------------------ | --------------------------------- | --------------------- |
| Peppol inbox | `gobl-customer-inbox-peppol`   | `cf_gobl_customer_inbox_peppol`   | `0225:123456789_test` |
| SIREN        | `gobl-customer-identity-SIREN` | `cf_gobl_customer_identity_SIREN` | `123456789`           |
| SIRET        | `gobl-customer-identity-SIRET` | `cf_gobl_customer_identity_SIRET` | `12345678900011`      |

## E-reporting transaction fields

The e-reporting path applies the `fr-ctc-flow10-v1` addon, which defines two invoice tax extensions. By default, the addon sets the billing mode to `M1` — or `M2` when the invoice is fully paid — and the B2C transaction category to `TNT1`. Use the custom fields below to override these defaults:

| Field                    | Metadata key                          | Custom field key                         | Example |
| ------------------------ | ------------------------------------- | ---------------------------------------- | ------- |
| Billing mode             | `gobl-tax-fr-ctc-billing-mode`        | `cf_gobl_tax_fr_ctc_billing_mode`        | `S1`    |
| B2C transaction category | `gobl-tax-fr-ctc-flow10-b2c-category` | `cf_gobl_tax_fr_ctc_flow10_b2c_category` | `TPS1`  |

<Note>
  The metadata keys listed above follow the Chargebee metadata format (hyphens, no `cf_` prefix). If you prefer to use custom fields instead, replace hyphens with underscores and add the `cf_` prefix. See [Custom fields & metadata](/guides/chargebee#custom-fields-metadata) for details.
</Note>

## FAQ

<AccordionGroup>
  <Accordion title="How do I configure my workspace for French invoicing?">
    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.
  </Accordion>

  <Accordion title="How can I view an XML attached to a PDF?">
    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](https://www.systoolsgroup.com/pdf/extractor/).
  </Accordion>

  <Accordion title="Is Invopop ready for the September 2026 mandate?">
    Invopop is an [officially approved Plateforme Agréée](https://www.impots.gouv.fr/je-consulte-la-liste-des-plateformes-agreees) 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](/guides/fr-pa) for the current state.
  </Accordion>

  <Accordion title="What GOBL addons are required for France PA?">
    The base [FR tax regime](https://docs.gobl.org/regimes/fr) 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.
  </Accordion>

  <Accordion title="Is a self-billed invoice a different document type in France?">
    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`](https://docs.gobl.org/addons/fr-ctc-flow2-v1#standard-self-billed) add-on applies it automatically. See [Self-billing](/guides/fr-pa-invoicing#self-billing) for the full flow.
  </Accordion>

  <Accordion title="What should we do if the customer doesn't belong to the Peppol network?">
    In countries where Peppol is the standard but not mandatory, you may still need to issue an e-invoice when the recipient isn't on the network. Both parties can agree on an alternative transfer method, but the invoice must still be EN16931 compliant.

    Recommended approach:

    * Set up a separate workflow that generates the XML without the send-Peppol-document step
    * Or reuse your existing workflow without the customer Peppol ID — the send step is automatically skipped
    * Fetch the generated XML and deliver it through the agreed channel, typically email
  </Accordion>

  <Accordion title="How do I handle B2C invoices in Peppol?">
    B2C invoices typically lack the structured customer information required for Peppol delivery, and most consumers don't have inboxes. Use a conditional workflow:

    1. Add an **If/Else** step that checks for a customer inbox using `count(customer.inboxes, true) > 0`.
    2. On the `false` branch, generate a PDF and email it to the customer, then stop the flow.

    This routes B2B invoices through Peppol while keeping a smooth path for consumers.
  </Accordion>

  <Accordion title="How do I handle 'Receiver Not Found' errors?">
    If a job fails with `KO` and `receiver not found in the peppol network`, treat it like an invalid email address — the recipient simply isn't reachable on Peppol. Add the **Lookup Participant ID** step (ideally in a separate validation workflow run against customer data) so you catch missing IDs before generating the invoice.
  </Accordion>

  <Accordion title="Should I set the `$regime` field when using Peppol?">
    No. The regime is automatically derived from the supplier's settings, which is the recommended approach for Peppol — leave it unset on the document.
  </Accordion>

  <Accordion title="Where do I find Peppol GOBL documentation?">
    See the [`oasis-ubl-v2`](https://docs.gobl.org/addons/oasis-ubl-v2) addon and the [Peppol app reference](/apps/peppol) for required fields, supported document types, and Participant ID schemes.
  </Accordion>
</AccordionGroup>

More available in our [France FAQ](/faq/france) section

***

<Card title="Participate in our community" icon="forumbee" href="https://community.invopop.com" arrow="true" horizontal>
  Ask and answer questions about your Chargebee integration →
</Card>
