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
- L'établissement dispose d'un espace financeur dans Tauraco.
- 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.
- Tauraco accorde à ce client un membre technique avec le rôle
LECTEUR(lecture) ouOPERATEUR(compléments et réconciliation), jamaisDECIDEUR. La révocation du client suspend ce membre immédiatement. - Le client obtient un jeton
client_credentialsavec des scopesbank:*etresource=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ération | Chemin | Scope |
|---|---|---|
| Corbeille des dossiers reçus | GET /bank/inbox | bank:inbox:read |
| Dossier (instantané figé, chronologie) | GET /bank/requests/{request_id} | bank:requests:read |
| Pièces : liste et contenu en flux | GET /bank/requests/{request_id}/documents, GET /bank/requests/{request_id}/documents/{document_id}/content | bank:documents:read |
| Demandes de compléments : liste, création | GET et POST /bank/requests/{request_id}/information-requests | bank:requests:read (liste), bank:info-requests:write (création) |
| Facilités et échéances | GET /bank/facilities, GET /bank/facilities/{facility_id}, GET /bank/repayments | bank:repayments:read |
| Rapprochement : création, écarts, résolution | POST /bank/facilities/{facility_id}/reconciliations, GET /bank/reconciliations/exceptions, POST /bank/reconciliations/{reconciliation_id}/resolve | bank:reconciliation:write (création, résolution), bank:repayments:read (écarts) |
| Sûretés Collateral : liste (alertes résumées), fiche, chronologie | GET /bank/collateral, GET /bank/collateral/{guarantee_id}, GET /bank/collateral/{guarantee_id}/events | bank: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.
"""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.