Aller au contenu
Log in

Envoyer des factures à Chorus Pro

En France, toutes les factures adressées à des clients du secteur public doivent être soumises électroniquement via Chorus Pro, le portail officiel de facturation électronique B2G de l’État (Décret n° 2016-1478). Depuis avril 2020, cela s’applique à toute administration centrale, régionale ou locale — que tu sois une entreprise française ou un fournisseur international.

Ce guide te montre comment utiliser l’API B2Brouter pour :

  1. Configurer ton compte d’entreprise (staging et production).
  2. Rechercher des entités publiques par SIRET dans l’annuaire B2Brouter.
  3. Créer des contacts clients et des unités organisationnelles.
  4. Générer, envoyer et suivre tes factures via Chorus Pro.
  5. Télécharger le fichier XML exact soumis et accuser réception.
  • Entreprise française avec un numéro de TVA/SIRET valide.
  • Environnement de test (staging)
    • Inscris-toi sur app-staging.b2brouter.net pour essayer l’API.
    • Une fois inscrit, ouvre un ticket de support en staging pour demander ta clé API et tes permissions.
  • Intégration en production et abonnement eDocExchange
  1. Connecte-toi à ton compte B2Brouter.
  2. Va dans l’onglet Développeurs.
  3. Sélectionne Clés API.
  4. Clique sur l’icône presse-papiers pour récupérer ton jeton API.

Pour facturer via Chorus Pro, l’entreprise émettrice comme le client (l’entité publique) doivent tous deux être identifiés avec un SIRET (cin_scheme="0009"), jamais avec un SIREN :

  • Entreprise émettrice : si le pays de l’entreprise est fr, cin_value doit contenir un SIRET non vide et cin_scheme doit valoir 9 ("0009"). Si le SIRET est vide, ou si cin_scheme est différent de 9, la facture n’est pas envoyée.
  • Client : le destinataire doit lui aussi être identifié avec un SIRET. Sans cela, la création du contact échoue avec l’erreur « Chorus needs the SIRET identifier of the client ».

Cohérence hiérarchique : même si la facturation se fait toujours de SIRET à SIRET, le compte ou le contact ne devrait pas être « plat » au niveau SIRET. Garde la même hiérarchie que dans le circuit DGFiP : un parent SIREN avec le SIRET modélisé comme une unité organisationnelle (UO) (parent_id + cin_scheme="0009") sous ce parent (voir Structure du compte). Si ton entreprise a déjà un compte B2Brouter avec un parent SIREN, crée le SIRET émetteur comme une UO sous ce parent plutôt qu’un compte autonome séparé.

Fenêtre de terminal
curl --request GET \
--url 'https://api-staging.b2brouter.net/accounts?offset=0&limit=25' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'accept: application/json'

2. Créer un compte d’entreprise (si nécessaire)

Section intitulée « 2. Créer un compte d’entreprise (si nécessaire) »

Fournis cin_scheme: "0009" et cin_value avec le SIRET de l’établissement émetteur (14 chiffres). C’est requis pour Chorus Pro : sans SIRET, ou avec un cin_scheme autre que 9, la soumission de la facture échoue.

Si ton entreprise a déjà un compte B2Brouter au niveau parent SIREN (par exemple pour la DGFiP), ne crée pas de nouveau compte autonome avec ce SIRET : crée-le comme une UO avec parent_id pointant vers le parent, en suivant les mêmes étapes que Créer des unités organisationnelles dans le guide DGFiP. L’exemple ci-dessous concerne une entreprise qui n’a pas encore de compte B2Brouter.

Fenêtre de terminal
curl --request POST \
--url https://api-staging.b2brouter.net/accounts \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"account": {
"country": "fr",
"rounding_method": "half_up",
"tin_value": "FR46458880332",
"tin_scheme": 9957,
"cin_scheme": "0009",
"cin_value": "45888033200017",
"name": "Exemplar SAS",
"address": "10 Rue Imaginaire",
"city": "Paris",
"postalcode": "75001",
"province": "Île-de-France",
"email": "john.doe@example.com"
}
}'

Tu peux vérifier si le destinataire existe dans notre annuaire public :

Fenêtre de terminal
curl --request GET \
--url https://api-staging.b2brouter.net/directory/fr/0009/13001533200013 \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'Content-Type: application/json'

Cette recherche renvoie déjà les unités organisationnelles existantes de l’entité (codes de service) depuis l’annuaire Chorus Pro. Tu n’as pas besoin de les créer toi-même comme contact : utilise le cin1_scheme/cin1_value déjà renvoyé par l’annuaire.

Lors de la création d’un client français :

  • Utilise cin_value pour le numéro SIRET-CODE. C’est requis : sans SIRET, Chorus Pro rejette la facture avec l’erreur « Chorus needs the SIRET identifier of the client ».
  • Utilise cin_scheme pour identifier la liste de codes des schémas. SIRET-CODE est 0009 ; un SIREN (0002) n’est pas accepté.
  • transport_type_code doit être fr.chorus.
  • document_type_code doit être xml.ubl.invoice.chorus.
Fenêtre de terminal
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: {YOUR_API_VERSION}' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"contact": {
"language": "en",
"is_client": true,
"is_provider": true,
"terms": "custom",
"public_sector": true,
"name": "UNIVERSITE D AIX MARSEILLE",
"address": "58 BD CHARLES LIVON",
"city": "MARSEILLE 7",
"postalcode": "13007",
"country": "fr",
"currency": "EUR",
"transport_type_code": "fr.chorus",
"document_type_code": "xml.ubl.invoice.chorus",
"cin_value": "13001533200013",
"cin_scheme": "0009"
}
}'

Pour facturer un service ou département spécifique, crée un sous-contact sous l’entité principale en utilisant parent_id et inclus le « code service » Chorus Pro (cin1_scheme / cin1_value).

Fenêtre de terminal
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: {YOUR_API_VERSION}' \
--header 'Content-Type: application/json' \
--data '{
"contact": {
"parent_id": 1313228381,
"name": "Factures marché FCM ROP cadre A2",
"address": "58 BD CHARLES LIVON",
"city": "MARSEILLE 7",
"postalcode": "13007",
"country": "fr",
"cin1_scheme": "8017",
"cin1_value": "ESR_MISSION_FACTURES_DEPLACEMENTS"
}
}'

Lors de la facturation d’un client français, assure-toi de fournir tous les champs requis, notamment :

  • number, date et due_date
  • Au moins une invoice_lines_attributes avec taxes_attributes
  • contact_id ou un objet contact complet
  • ponumber pour identifier la référence de commande
  • buyer_reference avec le cin1_value (Code Service) pour identifier le service destinataire
Fenêtre de terminal
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: {YOUR_API_VERSION}' \
--header 'content-type: application/json' \
--data '{
"send_after_import": true,
"invoice": {
"type": "IssuedInvoice",
"contact_id": 1313228399,
"bank_account": {
"type": "iban",
"iban": "FR7630006000011234567890189"
},
"terms": "custom",
"invoice_lines_attributes": [
{
"unit": 5,
"quantity": 135,
"price": 25,
"description": "Cocktail Dinatoire",
"taxes_attributes": [
{ "name": "TVA", "category": "S", "percent": 10 }
],
"article_code": "14",
"position": 1
}
],
"number": "00002",
"date": "2025-06-18",
"due_date": "2025-07-18",
"currency": "EUR",
"ponumber": "0123456",
"buyer_reference": "ESR_MISSION_FACTURES_DEPLACEMENTS"
}
}'
Fenêtre de terminal
curl --request GET \
--url 'https://api-staging.b2brouter.net/invoices/{INVOICE_ID}?include=lines' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'accept: application/json'
Fenêtre de terminal
curl --request GET \
--url 'https://api-staging.b2brouter.net/accounts/{ACCOUNT_ID}/invoices?offset=0&limit=25&state_updated_at_from=2025-06-12' \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'accept: application/json'

Mises à jour de statut en temps réel avec les Webhooks

Section intitulée « Mises à jour de statut en temps réel avec les Webhooks »

Plutôt que de faire du polling, abonne-toi aux notifications push via des webhooks. Chaque fois qu’une facture change de statut, B2Brouter enverra une requête HTTP POST à ton endpoint.

Invoice Status WebHooks - API Reference

Après l’envoi, la réponse de GET /invoices/{id} inclut un champ download_legal_url. Utilise-le pour récupérer le fichier XML exact soumis à Chorus Pro :

Fenêtre de terminal
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: {YOUR_API_VERSION}' \
--header 'Accept: application/xml'

Comme alternative en une étape, tu peux appeler directement GET /invoices/{id}/as/legal, sans d’abord récupérer download_legal_url depuis le payload de la facture. Il renvoie le document légal archivé tel que stocké et ne génère pas de transaction facturable — voir Télécharger des factures et Transaction : View_as.

Fenêtre de terminal
curl --request POST \
--url https://api-staging.b2brouter.net/invoices/{INVOICE_ID}/ack \
--header 'X-B2B-API-Key: {YOUR_API_KEY}' \
--header 'X-B2B-API-Version: {YOUR_API_VERSION}' \
--header 'accept: application/json'

Pour plus d’aide :