diff --git a/guides/chargebee.mdx b/guides/chargebee.mdx index 0b4071c8..0a731b51 100644 --- a/guides/chargebee.mdx +++ b/guides/chargebee.mdx @@ -10,6 +10,7 @@ import ZUGFeRDExample from '/snippets/workflows/chargebee/cb-zugferd.mdx' import XRechnungExample from '/snippets/workflows/chargebee/cb-xrechnung.mdx' import PeppolExample from '/snippets/workflows/chargebee/cb-peppol.mdx' import DKPeppolExample from '/snippets/workflows/chargebee/cb-dk-peppol.mdx' +import FRExample from '/snippets/workflows/chargebee/cb-france.mdx' ## Introduction @@ -369,6 +370,75 @@ For Invopop to update the invoice in Chargebee and trigger Chargebee's own email --- +### πŸ‡«πŸ‡· France + +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. + +**Required apps:** [France](/apps/france), [Peppol](/apps/peppol), [OASIS UBL](/apps/oasis-ubl) + + + 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. + + +{/* TODO: Add the walkthrough video once recorded, matching the other countries. + +*/} + +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. + + + + + Syncs with Chargebee, looks the customer up in the French Annuaire, and branches automatically: registered parties are e-invoiced via Peppol France CIUS and forwarded to the PPF, while unregistered parties are recorded for e-reporting. + + + + + For a full walkthrough including required apps, directory registration, and customer routing, see the [France section of the Chargebee guide](/guides/chargebee#france). + + + + 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. + + + + 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. + + + + 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. + + + + + +#### 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` | + +--- + ## Retriggering Invoices There may be situations where you need to reprocess an invoice. The method depends on whether Invopop has already created a silo entry (invoice) for it. diff --git a/snippets/workflows/chargebee/cb-france.mdx b/snippets/workflows/chargebee/cb-france.mdx new file mode 100644 index 00000000..0b670679 --- /dev/null +++ b/snippets/workflows/chargebee/cb-france.mdx @@ -0,0 +1,235 @@ +--- +title: "Chargebee France send invoice" +description: "Sync from Chargebee and forward to PPF or record for reporting" +countryCode: "fr" +appId: "chargebee" +schema: "bill/invoice" +--- + +```json Example Chargebee France workflow +{ + "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": "Modify Silo Entry", + "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" + } + } + ] +} + +```