Accueil › Portail développeurs › Guide d'intégration ERP
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 ERP

Trois manières de relier Tauraco à un logiciel de gestion ou de comptabilité, de la plus simple à la plus intégrée :

  1. Fichiers : exports CSV, XLSX ou FEC, ponctuels ou planifiés (voir le guide des exports), déposés au besoin sur un serveur SFTP.
  2. API publique : votre logiciel lit et écrit dans Tauraco avec un jeton client_credentials (exemple de synchronisation ci-dessous).
  3. Connecteurs : Tauraco pousse les pièces vers votre logiciel, avec un mapping comptable déclaré et des rejets motivés.

État au 2026-11-05 : les connecteurs sont ouverts en production depuis le 2026-11-05 ; ils ont été développés et testés contre des serveurs simulés seulement, jamais contre l'environnement réel d'un éditeur. Règle de communication : tant qu'un connecteur n'a pas été construit et testé sur un environnement réel de l'éditeur, Tauraco annonce un « format compatible », jamais une « intégration native ».

Maturité des connecteurs

ConnecteurMaturité prévueCe qu'il fait
CSV / XLSX génériquedisponibleprofils d'export (colonnes, séparateurs, formats de date)
REST génériquedisponibleenvoi JSON authentifié vers un endpoint que vous désignez, mêmes protections que les webhooks
SFTP sortantdisponibledépôt de fichiers sur votre serveur ; empreinte d'hôte known_hosts obligatoire, hôte et répertoire fixés
Odoo 17 / 18 / 19bêtatest de connexion, envoi des partenaires et des factures en brouillon ; pas de tirage en v1 ; testé sur serveur simulé
Sage, QuickBooks, EBP, Pennylane (fichiers)configuration requiseprofils CSV au format attendu par le logiciel, sans API
SAP, Dynamics 365, Oracle ERP, PeopleSoft, NetSuite, Cegid, Xero, Sage X3, API Sage (Accounting, Intacct, Active)non pris en chargefiche documentée, aucun échange

Le détail par éditeur (API, authentification, limites, points SYSCOHADA) figure dans le catalogue des connecteurs livré avec la documentation de la plateforme.

Mapping comptable

Tauraco ne reclasse jamais un compte : il applique la correspondance que vous déclarez (comptes, taxes, devises, journaux, tiers) et conserve la numérotation SYSCOHADA. Chaque pièce qui ne peut pas être envoyée est rejetée avec un motif, sans arrêter le lot (liste alignée le 2026-11-05 sur les motifs du moteur de mapping) :

MotifSens
missing_requiredchamp obligatoire absent
unmapped_accountcompte sans correspondance
unmapped_taxtaxe sans correspondance
currency_conversion_forbiddendevise différente sans conversion autorisée (jamais de conversion silencieuse)
invalid_datedate illisible
invalid_amountmontant invalide (non décimal, non fini ou plus précis que la devise)
unknown_partnertiers sans correspondance sur la connexion (à déclarer)
duplicatepièce déjà transmise à l'identique, ou présente deux fois dans le lot : elle est comptée skipped_duplicate (statut d'élément, pas un rejet)
remote_rejectedrefus du logiciel distant (message tronqué)
invalid_valuevaleur non convertible (par exemple un code devise qui n'a pas la forme ISO 4217 à trois lettres)

Un lot avec des rejets se termine PARTIAL ; un rapport de réconciliation compare les totaux locaux et distants. Une erreur de transport arrête le lot (FAILED). Une simulation (dry_run) applique le mapping sans rien envoyer.

Synchroniser un logiciel comptable par l'API

L'exemple lit les factures modifiées depuis le dernier passage (updated_after, avec un recouvrement de 5 minutes), dédoublonne par identifiant et écrit un journal des ventes équilibré (client au débit, ventes et TVA au crédit). Les comptes sont ceux de votre plan comptable ; les montants restent des Decimal.

python/synchro_comptable.pyTélécharger le fichier
"""Synchronisation incrémentale des factures vers un logiciel comptable (journal des ventes CSV).

Incremental invoice sync to accounting software (sales journal as CSV).

Principe : on relit les factures modifiées depuis le dernier passage (filtre
``updated_after``), avec un recouvrement de 5 minutes, et on dédoublonne par
identifiant de facture : une facture déjà écrite n'est pas réécrite. La table de
correspondance des comptes est celle de VOTRE plan comptable : Tauraco ne reclasse
aucun compte. Les montants restent des chaînes décimales (``Decimal``), jamais des
flottants.

Usage : TAURACO_CLIENT_ID=… TAURACO_CLIENT_SECRET=… python3 synchro_comptable.py
"""
from __future__ import annotations

import csv
import json
import os
from datetime import datetime, timedelta, timezone
from decimal import Decimal
from pathlib import Path
from typing import Iterable, Iterator, List

from client_credentials import get_token, iterate

STATE_FILE = Path(os.environ.get("SYNC_STATE", "etat_synchro.json"))
OUTPUT_FILE = Path(os.environ.get("SYNC_OUTPUT", "journal_ventes.csv"))
OVERLAP = timedelta(minutes=5)

#: Correspondance déclarée par l'entreprise (exemple SYSCOHADA : 411 clients, 701 ventes).
ACCOUNT_CUSTOMERS = os.environ.get("ACCOUNT_CUSTOMERS", "411100")
ACCOUNT_SALES = os.environ.get("ACCOUNT_SALES", "701100")
ACCOUNT_VAT = os.environ.get("ACCOUNT_VAT", "443100")
SYNCED_STATUSES = {"SENT", "PARTIALLY_PAID", "PAID", "OVERDUE"}


def journal_lines(invoice: dict) -> List[List[str]]:
    """Trois lignes équilibrées d'une facture : débit client, crédit ventes HT, crédit TVA."""
    total = Decimal(invoice["total"])
    subtotal = Decimal(invoice.get("subtotal") or invoice["total"])
    tax = Decimal(invoice.get("tax_total") or "0")
    if subtotal + tax != total:
        raise ValueError(f"facture {invoice['number']} : HT + taxes ≠ TTC, à vérifier")
    label = f"{invoice['number']} {invoice.get('customer_name') or ''}".strip()
    rows = [[invoice["issue_date"], "VT", invoice["number"], ACCOUNT_CUSTOMERS, label, str(total), "0"],
            [invoice["issue_date"], "VT", invoice["number"], ACCOUNT_SALES, label, "0", str(subtotal)]]
    if tax:
        rows.append([invoice["issue_date"], "VT", invoice["number"], ACCOUNT_VAT, label, "0", str(tax)])
    return rows


def new_invoices(invoices: Iterable[dict], already_synced: set) -> Iterator[dict]:
    for invoice in invoices:
        if invoice["status"] in SYNCED_STATUSES and invoice["id"] not in already_synced:
            already_synced.add(invoice["id"])
            yield invoice


def main() -> None:
    state = json.loads(STATE_FILE.read_text()) if STATE_FILE.exists() else {"since": None, "synced": []}
    started = datetime.now(timezone.utc)
    params = {"limit": "200"}
    if state["since"]:
        since = datetime.fromisoformat(state["since"].replace("Z", "+00:00")) - OVERLAP
        params["updated_after"] = since.isoformat().replace("+00:00", "Z")
    token = get_token(os.environ["TAURACO_CLIENT_ID"], os.environ["TAURACO_CLIENT_SECRET"],
                      "invoices:read", tenant=os.environ.get("TAURACO_TENANT"))["access_token"]
    synced = set(state["synced"])
    with OUTPUT_FILE.open("a", newline="", encoding="utf-8") as handle:
        writer = csv.writer(handle, delimiter=";")
        for invoice in new_invoices(iterate("/invoices", token, params), synced):
            writer.writerows(journal_lines(invoice))
    state = {"since": started.isoformat().replace("+00:00", "Z"), "synced": sorted(synced)}
    STATE_FILE.write_text(json.dumps(state))


if __name__ == "__main__":
    main()

Il s'appuie sur le client de l'exemple python/client_credentials.py (même répertoire).

Formats métier

  • FEC : disponible pour une entreprise au régime comptable français (fec), refusé ailleurs.
  • Factur-X (CII EN 16931) : développé, livré « bêta, non validé par Schematron ». UBL différé.
  • ISO 20022 : camt.053 (relevés) développé, « expérimental, non validé » ; pain.001 (virements) non pris en charge en v1, aucune coordonnée bancaire de bénéficiaire n'étant servie ; la validation XSD ne s'active que si les schémas officiels sont déposés par l'opérateur.

Aucune conformité n'est déclarée pour ces formats.

Sécurité des connexions sortantes

Les adresses de vos serveurs (REST, Odoo, SFTP) sont contrôlées à la création et à chaque exécution : résolution DNS complète, adresses publiques seulement, ports autorisés (443/8443 en HTTPS, 22/2222 en SFTP), aucune redirection. Les secrets de connexion sont chiffrés et jamais réaffichés. Un test de connexion rend un message générique (unreachable, host_key_mismatch, auth_failed, timeout), jamais la bannière du serveur distant.