SIPCO

Documentation de l'API — v1

Facturation électronique • Espace développeur

Objectif

Cette API centralise la réception des factures au format canonique (JSON) pour plusieurs applications et plusieurs clients (multi-tenant). Elle permet ensuite l'envoi vers une plateforme de facturation électronique (ex : B2Brouter), avec traçabilité, idempotence et suivi des statuts.

Cycle de vie d’une facture

  • DRAFT : facture créée, modifiable
  • SENDING : envoi en cours vers la plateforme
  • SENT : transmise à la plateforme
  • ACCEPTED : acceptée par la plateforme / destinataire
  • REJECTED : rejetée (erreur métier ou technique)
  • ERROR : erreur lors de l’envoi (ou validation plateforme)

Chaque transition est historisée dans un journal d’événements (audit).

Base URL

https://test-facturation.sipco.fr

En production, remplacer par l'URL de l'API (ex : https://facturation.sipco.fr).

Authentification

Toutes les routes sous /api/v1 nécessitent une clé API interne transmise dans l’en-tête :

Authorization: Bearer VOTRE_CLE_API

Sans cet en-tête, l’API renvoie 401 Unauthorized.

Exemple rapide

curl -X GET "https://test-facturation.sipco.fr/api/v1/secure/ping" \
  -H "Authorization: Bearer <VOTRE_CLE_API>"

GET /api/health/db

Endpoint de santé (non protégé) validant la connexion à la base.

curl -X GET "https://test-facturation.sipco.fr/api/health/db"

GET /api/v1/secure/ping

Endpoint protégé de test (valide l’auth API Key).

curl -X GET "https://test-facturation.sipco.fr/api/v1/secure/ping" \
-H "Authorization: Bearer <VOTRE_CLE_API>"

GET /api/v1/b2brouter/accounts

Liste les comptes B2Brouter accessibles (utile pour récupérer l’accountId à associer au tenant).

curl -X GET "https://test-facturation.sipco.fr/api/v1/b2brouter/accounts" \
-H "Authorization: Bearer <VOTRE_CLE_API>"

POST /api/v1/tenants

Création d’un tenant (entité cliente). Exemple : sipco.

Body JSON (recommandé)

{
  "name": "SIPCO",
  "slug": "sipco",

  "companyName": "SYSTEME INFORMAT PROGR CONSEIL ORGANISAT (SIPCO)",
  "siren": "324094580",
  "siret": "32409458000051",
  "vatNumber": "FR81324094580",
  "rcsCity": "Rennes",
  "rcsNumber": "324 094 580",

  "street": "12 rue des artisans",
  "city": "Vitré",
  "zipCode": "35500",
  "country": "FR",

  "b2brouterAccountId": <id>
}

Important : l’accountId est requis pour pouvoir envoyer des factures vers B2Brouter.

curl -X POST "https://test-facturation.sipco.fr/api/v1/tenants" \
      -H "Authorization: Bearer <VOTRE_CLE_API>" \
      -H "Content-Type: application/json" \
      -d @tenant.json

Emission de factures

POST /api/v1/tenants/:slug/invoices

Création d’une facture au format canonique (JSON). Statut initial : DRAFT. Un événement INVOICE_CREATED est enregistré.

Déclenche automatiquement le service sendInvoice pour vérifier la conformité des champs et déclenche l'envoie si OK.

Body JSON (exemple “prêt à envoyer”)

{
  "type": "INVOICE",
  "externalRef": "SIPCO-INV-2026-0003",
  "issueDate": "2026-02-06",
  "currency": "EUR",

  "seller": {
    "companyName": "SIPCO",
    "siret": "32409458000051",
    "vatNumber": "FR81324094580",
    "address": { "street": "12 rue des artisans", "city": "Vitré", "zipCode": "35500", "country": "FR" }
  },

  "buyer": {
    "companyName": "CLIENT TEST SARL",
    "siret": "98765432100033",
    "vatNumber": "FR98765432100",
    "email": "contact@client.fr",
    "address": { "street": "10 Avenue du Client", "city": "Paris", "zipCode": "75001", "country": "FR" }
  },

  "lines": [
    { "id": "1", "description": "Abonnement maintenance – Février 2026", "quantity": 1, "unitPriceExclTax": "45.00", "vatRate": 20 }
  ]
}
curl -X POST "https://test-facturation.sipco.fr/api/v1/tenants/sipco/invoices" \
  -H "Authorization: Bearer <VOTRE_CLE_API>" \
  -H "Content-Type: application/json" \
  -d @invoice.json

GET /api/v1/tenants/:slug/invoices

Liste paginée des factures d’un tenant.

Paramètres (query)

limitnumberNombre d’éléments (défaut 50, max 200)
offsetnumberDécalage de pagination
statusstringFiltrer par statut (DRAFT, SENT, ERROR…)
searchstringRecherche sur externalRef (contains)
curl -X GET "https://test-facturation.sipco.fr/api/v1/tenants/sipco/invoices?limit=50&offset=0" \
     -H "Authorization: Bearer <VOTRE_CLE_API>"

GET /api/v1/tenants/:slug/invoices/:id

Détail complet d’une facture (canonique + événements + fichiers).

curl -X GET "https://test-facturation.sipco.fr/api/v1/tenants/sipco/invoices/{invoiceId}" \
     -H "Authorization: Bearer <VOTRE_CLE_API>"

PATCH /api/v1/tenants/:slug/invoices/:id

Mise à jour d’une facture uniquement si DRAFT. Ajoute un événement INVOICE_VALIDATED.

curl -X PATCH "https://test-facturation.sipco.fr/api/v1/tenants/sipco/invoices/{invoiceId}" \
     -H "Authorization: Bearer <VOTRE_CLE_API>" \
     -H "Content-Type: application/json" \
     -d '{ "buyer": { "email": "contact@client.fr" } }'

POST /api/v1/tenants/:slug/invoices/:id/send

Déclenche l’envoi vers B2Brouter. L’API assure l’idempotence pour éviter un double envoi. Si la facture est incomplète, l’API bloque avant B2Brouter.

Headers optionnels

Authorization: Bearer <VOTRE_CLE_API>
        Idempotency-Key: <clé_unique_côté_client>
curl -X POST "https://test-facturation.sipco.fr/api/v1/tenants/sipco/invoices/{invoiceId}/send" \
     -H "Authorization: Bearer <VOTRE_CLE_API>" \
     -H "Idempotency-Key: <clé_unique>"

Si déjà envoyé : 409 INVOICE_ALREADY_SENT. Si déjà en cours : 200 avec already: true.

Champs requis

1) Création / mise à jour (DRAFT)

À la création (POST) ou modification (PATCH), la facture doit respecter le schéma canonique.

  • externalRef (référence externe)
  • issueDate (YYYY-MM-DD) et currency (ISO3, ex: EUR)
  • seller.companyName + seller.address
  • buyer.companyName + buyer.address
  • lines[] (≥ 1) avec description, quantity, unitPriceExclTax

Note : certains identifiants (SIRET/TVA/email) peuvent être absents en DRAFT, mais requis à l’envoi.

2) Pré-requis à l’envoi (SEND)

Avant /send, validation renforcée pour éviter un appel fournisseur inutile.

Buyer (destinataire)
  • buyer.email (email valide) → requis par B2Brouter
  • buyer.siret ou buyer.siren
  • buyer.vatNumber (TVA intracom)
Tenant (émetteur côté B2Brouter)
  • Tenant lié à B2Brouter : tenant.b2brouterAccountId
  • Sinon : TENANT_B2BROUTER_ACCOUNT_MISSING

En cas d’échec : 400 INVOICE_NOT_READY_TO_SEND + liste des champs manquants.

Réception des factures (Incoming)

Centralise les factures reçues depuis une PDP (ex : B2Brouter) pour un tenant donné. Les factures sont synchronisées, stockées et exposées aux applications clientes (ex : Nexus).

POST /api/v1/tenants/:slug/received-invoices/sync

Synchronise les factures reçues : liste + détail JSON + document original + ACK.

POST /api/v1/tenants/:slug/received-invoices/sync
Authorization: Bearer <VOTRE_CLE_API>

GET /api/v1/tenants/:slug/received-invoices

Liste des factures reçues (paginée). Filtres : status, search.

GET /api/v1/tenants/:slug/received-invoices?limit=50&offset=0

GET /api/v1/tenants/:slug/received-invoices/:id

Détail d’une facture reçue (inclut events).

GET /api/v1/tenants/:slug/received-invoices/:id

GET /api/v1/tenants/:slug/received-invoices/:id/original

Proxy sécurisé vers la PDP : renvoie le binaire original sans exposer la clé PDP.

GET /api/v1/tenants/:slug/received-invoices/:id/original

Codes de réponse

CodeSignificationDescription
200OKRequête réussie
201CreatedRessource créée
400Bad RequestValidation / JSON invalide
401UnauthorizedClé API absente ou incorrecte
404Not FoundTenant ou facture introuvable
409ConflictConflit
502Bad GatewayErreur fournisseur (B2Brouter)
500Server ErrorErreur interne