Accueil › Portail développeurs › Guide d'intégration bancaire
Menu du document← Accueil
Portail développeurs
  1. Démarrage rapide
  2. Authentification
  3. Référence API REST
  4. Guide des webhooks
  5. Guide des exports
  6. Guide d'intégration ERP
  7. Guide d'intégration bancaire
  8. Documentation Tauraco Collateral
  9. Documentation MCP
  10. Exemples de code
  11. Gestion des erreurs
  12. Environnements sandbox
  13. Versions et changelog
  14. FAQ
  15. Support développeurs
Développeurs

Guide d'intégration bancaire

L'API banque permet à un établissement financier de lire, depuis son propre système d'information, les dossiers de financement que des entreprises lui ont transmis par Tauraco : dossier figé, chronologie, pièces, échéances, réconciliation et sûretés. Elle ne prend aucune décision : offre, déclin, versement, tirage, radiation et mainlevée restent des gestes humains d'un décideur, dans le portail banque.

En ligne depuis le 2026-11-05 sous https://api.tauraco.io/public/v1/bank (répond 401 sans jeton). Les avertissements juridiques sont validés. Aucune institution réelle n'est encore raccordée : le raccordement d'un établissement est un acte contractuel avec Tauraco. La sandbox, construite avec une banque fictive, n'est pas encore lancée.

Prérequis

  1. L'établissement dispose d'un espace financeur dans Tauraco.
  2. Un décideur de l'établissement crée, dans Données et intégrations › Clés d'API de l'établissement, un client de type « banque ». Le secret n'est affiché qu'une fois.
  3. Tauraco accorde à ce client un membre technique avec le rôle LECTEUR (lecture) ou OPERATEUR (compléments et réconciliation), jamais DECIDEUR. La révocation du client suspend ce membre immédiatement.
  4. Le client obtient un jeton client_credentials avec des scopes bank:* et resource=https://api.tauraco.io/public/v1.

Une entreprise reste maîtresse de son dossier : l'établissement ne voit que les demandes qui lui sont adressées, et plus les pièces d'une demande qu'il a déclinée.

Opérations

Toutes sont sous https://api.tauraco.io/public/v1/bank.

OpérationCheminScope
Corbeille des dossiers reçusGET /bank/inboxbank:inbox:read
Dossier (instantané figé, chronologie)GET /bank/requests/{request_id}bank:requests:read
Pièces : liste et contenu en fluxGET /bank/requests/{request_id}/documents, GET /bank/requests/{request_id}/documents/{document_id}/contentbank:documents:read
Demandes de compléments : liste, créationGET et POST /bank/requests/{request_id}/information-requestsbank:requests:read (liste), bank:info-requests:write (création)
Facilités et échéancesGET /bank/facilities, GET /bank/facilities/{facility_id}, GET /bank/repaymentsbank:repayments:read
Rapprochement : création, écarts, résolutionPOST /bank/facilities/{facility_id}/reconciliations, GET /bank/reconciliations/exceptions, POST /bank/reconciliations/{reconciliation_id}/resolvebank:reconciliation:write (création, résolution), bank:repayments:read (écarts)
Sûretés Collateral : liste (alertes résumées), fiche, chronologieGET /bank/collateral, GET /bank/collateral/{guarantee_id}, GET /bank/collateral/{guarantee_id}/eventsbank:collateral:read

La clôture d'une demande de complément par l'établissement n'existe pas en v1 ; le registre de l'actif et la fiche d'alerte ne sont pas exposés. Les montants sont des chaînes décimales en unités majeures ; le dossier figé (snapshot) est servi tel qu'il a été figé à la transmission, ses montants y étant des entiers en unités mineures.

Chaque consultation de dossier et chaque téléchargement de pièce sont journalisés dans l'audit de Tauraco. Une pièce est servie en flux (25 Mo au plus), avec Cache-Control: private, no-store, X-Content-Type-Options: nosniff et X-Content-SHA256.

Une demande retirée par l'entreprise reste lisible, pièces comprises, par un établissement destinataire (lecture historique, comme dans le portail) ; elle reste refusée à un établissement non destinataire ou qui a décliné. Une ressource non adressée à votre établissement répond 404 not_found, indistinct d'une ressource absente.

Ce que l'API ne renvoie pas

  • Aucun montant interne ni aucune offre d'un autre établissement.
  • Aucune note privée des dossiers Collateral.
  • Aucune décision de crédit : l'API ne propose pas d'offre, ne décline pas, ne verse pas.

Avertissement juridique

Toute réponse sur une sûreté porte un champ avertissement_juridique : une donnée enregistrée dans Tauraco n'est pas la preuve juridique d'une sûreté opposable. Le texte de cet avertissement a été validé avant l'ouverture de l'API banque, le 2026-11-05.

Recevoir les événements de financement

Les événements financing.requested, financing.status_changed, financing.funded et contract.signed sont adressés à l'établissement concerné, ainsi que collateral.registered et collateral.released. Ils ne contiennent ni montant ni taux : relisez le dossier par data.links.self (…/public/v1/bank/requests/{id}). Déclarez l'endpoint dans Webhooks de l'établissement (décideur) et vérifiez la signature comme décrit dans le guide des webhooks.

python/recepteur_webhook_banque.pyTélécharger le fichier
"""Recevoir un webhook bancaire (événements ``financing.*``) et relire le dossier.

Receive a bank webhook (``financing.*`` events) and fetch the request.

L'événement est mince (identifiants, statut, horodatages ; aucun montant, aucun taux) :
on vérifie la signature, on dédoublonne par ``webhook-id``, puis on relit le dossier
par ``data.links.self`` (``…/public/v1/bank/requests/{id}``) avec un jeton du client
``bank`` (scopes ``bank:*``). La relecture applique les mêmes contrôles que le portail
banque : dossier adressé à l'institution, destinataire n'ayant pas décliné.

Le jeton n'est envoyé qu'à l'API Tauraco : un lien qui ne commence pas exactement par
``TAURACO_API_BASE + "/bank/requests/"`` est ignoré (un événement forgé ne doit pas
faire partir le jeton vers un autre hôte). Le secret du webhook est obligatoire.

Usage : TAURACO_WEBHOOK_SECRET=… TAURACO_CLIENT_ID=… TAURACO_CLIENT_SECRET=… \\
        python3 recepteur_webhook_banque.py
"""
from __future__ import annotations

import json
import os
import re
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Optional

from client_credentials import API_BASE, TauracoError, get_token, http_transport
from verifier_webhook import AlreadySeen, secret_key, verify_signature

FINANCING_EVENTS = {"financing.requested", "financing.status_changed", "financing.funded", "contract.signed"}
#: Seuls liens suivis : l'API Tauraco configurée, ressource ``/bank/requests/{id}``.
REQUEST_PREFIX = API_BASE.rstrip("/") + "/bank/requests/"
_REQUEST_ID = re.compile(r"[A-Za-z0-9_-]{1,128}")


def request_link(event: dict) -> Optional[str]:
    """Lien de relecture du dossier, ou ``None`` (événement hors financement, lien absent)."""
    if event.get("type") not in FINANCING_EVENTS:
        return None
    links = (event.get("data") or {}).get("links") or {}
    link = links.get("self")
    if not isinstance(link, str) or not link.startswith(REQUEST_PREFIX):
        return None  # autre hôte, autre chemin : jamais de jeton envoyé
    return link if _REQUEST_ID.fullmatch(link[len(REQUEST_PREFIX):]) else None


def fetch_request(link: str) -> dict:
    if request_link({"type": "financing.requested", "data": {"links": {"self": link}}}) != link:
        raise ValueError("lien de relecture hors de l'API Tauraco : refusé")
    token = get_token(os.environ["TAURACO_CLIENT_ID"], os.environ["TAURACO_CLIENT_SECRET"],
                      "bank:requests:read")["access_token"]
    status, _headers, raw = http_transport("GET", link, {"Authorization": f"Bearer {token}",
                                                          "Accept": "application/json"}, None)
    payload = json.loads(raw or b"{}")
    if status != 200:
        raise TauracoError(status, payload)
    return payload


def make_bank_handler(secret: str) -> type[BaseHTTPRequestHandler]:
    """Récepteur lié à ``secret`` ; ``ValueError`` si le secret est vide ou illisible."""
    if secret_key(secret) is None:
        raise ValueError("secret de webhook vide ou illisible (whsec_ + base64 attendu)")
    seen = AlreadySeen()

    class BankReceiver(BaseHTTPRequestHandler):
        def do_POST(self) -> None:  # noqa: N802
            body = self.rfile.read(int(self.headers.get("Content-Length") or 0))
            headers = dict(self.headers.items())
            if not verify_signature(secret, headers, body):
                self.send_response(401)
                self.end_headers()
                return
            self.send_response(204)
            self.end_headers()
            event = json.loads(body)
            if not seen.first_time(event["id"]):
                return  # reprise ou rejeu : déjà traité
            link = request_link(event)
            if link:
                dossier = fetch_request(link)
                print(event["type"], event["data"].get("request_id"), dossier.get("status"))

        def log_message(self, *_args) -> None:
            return

    return BankReceiver


if __name__ == "__main__":
    handler = make_bank_handler(os.environ["TAURACO_WEBHOOK_SECRET"])  # aucune valeur par défaut
    HTTPServer(("127.0.0.1", 8788), handler).serve_forever()

Interopérabilité

  • Sécurité du transport : HTTPS ; mTLS (RFC 9440) documenté mais non mis en œuvre en v1, faute de nom d'hôte dédié.
  • Formats : JSON ; ISO 20022 camt.053 (relevés) développé, expérimental et non validé ; pain.001 (virements) non pris en charge en v1.
  • Cautions et garanties de l'écosystème : hors de l'API banque v1.