La double saisie n’est que le symptôme visible. Le problème grave apparaît lorsque l’ERP et l’application métier savent tous les deux modifier un prix, valider un client ou décider qu’une commande est livrable. Les deux écrans semblent fonctionner, jusqu’au jour où une correction faite à 10 h disparaît à 10 h 05 sous l’effet d’une synchronisation.
Le vrai enjeu consiste à attribuer chaque décision à un seul système, puis à distribuer son résultat. L’application peut enrichir le travail de l’utilisateur sans recopier la logique comptable, commerciale ou logistique déjà portée par l’ERP. Elle peut aussi posséder un processus neuf, à condition que cette responsabilité soit assumée et que l’ERP reçoive un résultat plutôt qu’une version concurrente de la règle.
Une intégration réussie commence donc avant l’API. Elle cartographie les faits, les décisions et leurs propriétaires. Le développement d’une application métier sur mesure devient alors un travail de frontières : ce que l’interface présente, ce qu’elle décide, ce qu’elle demande à l’ERP et ce qu’elle accepte en retour.
L’objectif n’est pas que toutes les données soient instantanément identiques. Certaines peuvent être volontairement répliquées pour la lecture. Il faut surtout que leur autorité, leur fraîcheur et leur possibilité de correction soient explicites.
Le doublon commence par une décision partagée
Deux copies d’une adresse ne sont pas nécessairement dangereuses si l’une est une projection en lecture seule. Deux moteurs qui décident chacun de la remise applicable le sont. La première question ne porte donc pas sur le nombre de bases, mais sur le nombre d’endroits capables de produire une vérité nouvelle.
Pour repérer ces doublons, l’équipe suit les verbes : créer le client, approuver la limite de crédit, calculer le prix, réserver le stock, confirmer l’expédition, émettre la facture. Chaque verbe doit avoir un responsable fonctionnel et un système qui exécute la décision. Les autres systèmes consomment le résultat ou demandent l’action.
Un signal faible est révélateur : les utilisateurs ont appris qu’il faut « attendre la synchro avant de corriger ». Cette phrase indique qu’ils ne savent plus quelle action survivra. Un autre signal apparaît lorsque le support compare deux exports pour trancher un incident. L’architecture a déjà transféré son ambiguïté vers les opérations.
Désigner un propriétaire pour chaque fait
La matrice d’ownership descend au niveau utile. Dire « l’ERP possède le client » reste trop vague. L’ERP peut posséder le compte de facturation et la condition de paiement, le CRM posséder les contacts et l’application posséder la préférence liée à son propre service. Le même objet métier rassemble alors des attributs gouvernés ailleurs.
Pour chaque donnée, la matrice précise le créateur, le modificateur autorisé, les consommateurs, la latence acceptable et la réaction à une indisponibilité. Un prix contractuel peut exiger une lecture synchrone ; une raison sociale peut tolérer une copie vieille de quelques minutes ; un stock destiné à une promesse immédiate requiert une règle différente d’un stock affiché à titre indicatif.
Le propriétaire n’est pas forcément le logiciel historiquement présent. Si le nouveau workflow devient la seule équipe capable de qualifier une demande complexe, l’application peut posséder cette qualification. Mais le changement doit supprimer ou neutraliser l’ancien écran, faute de quoi le partage de responsabilité persiste sous une autre forme.
Séparer données, calculs et workflow
Une intégration confond souvent trois choses. La donnée décrit un fait : poids, code client, statut de facture. Le calcul transforme des entrées : prix net, taxe, seuil de crédit. Le workflow autorise une transition : devis accepté, commande libérée, litige clôturé. Copier une donnée pour l’afficher n’autorise pas à recopier son calcul ou sa transition.
L’application peut demander à l’ERP « calcule le prix pour ce client et ces lignes », puis conserver le résultat, la version tarifaire et la date. Elle ne réimplémente pas les remises dans le frontend. Si l’ERP n’expose pas cette capacité, un service dédié peut devenir le propriétaire du calcul, mais les deux systèmes doivent alors abandonner leur version locale.
Contre-intuitivement, centraliser toutes les règles dans l’ERP n’est pas toujours plus cohérent. Une règle d’expérience propre à l’application — par exemple qui peut enregistrer un brouillon — n’a aucune raison d’envahir l’ERP. La cohérence vient d’une frontière juste, pas d’un logiciel omniscient.
Traduire sans importer le modèle de l’ERP
Les codes et statuts d’un ERP reflètent son histoire. Les exposer directement dans l’application rend chaque écran dépendant d’un schéma qu’il ne maîtrise pas. Une couche d’adaptation traduit « client bloqué crédit » en une capacité compréhensible par le domaine de l’application, sans lui imposer toutes les nuances comptables.
Le modèle de couche anti-corruption décrit par Microsoft place justement une façade ou un adaptateur entre des sous-systèmes qui n’emploient pas la même sémantique. Cette couche transforme les requêtes et réponses ; elle ne doit pas devenir un second ERP rempli de règles sans propriétaire.
Chaque mapping est versionné et testé avec des exemples métier. Un code vide, inconnu ou supprimé possède un comportement explicite. Le contrat conserve la valeur source lorsqu’elle est nécessaire au diagnostic, mais le reste de l’application manipule ses propres concepts.
Stabiliser identifiants et correspondances
Un numéro visible n’est pas toujours une clé durable. Le code client peut changer après une fusion, un produit peut avoir plusieurs références et un établissement peut être recréé. L’intégration doit conserver les identifiants techniques stables de chaque système et une table de correspondance historisée.
La création suit une séquence. L’application génère son identifiant, envoie une demande munie d’une clé d’idempotence, puis attache l’identifiant ERP retourné. Si la réponse se perd, elle interroge le résultat avec la même clé plutôt que de recréer le client. Un état « en attente de correspondance » reste visible et interdit les opérations qui exigent l’identifiant ERP.
Les rapprochements automatiques sur email, nom ou adresse restent des propositions. Deux sociétés peuvent partager une boîte générique ; une société peut changer de nom. Le cas ambigu rejoint une file de revue avec les candidats, les sources et la décision prise.
Choisir appel synchrone, événement ou batch
Un appel synchrone convient lorsque l’utilisateur a besoin d’un verdict immédiat et que l’ERP peut tenir le niveau de service : validation d’un compte, calcul d’un prix ou disponibilité engageante. Le timeout est court, l’erreur est compréhensible et aucun retry aveugle ne crée une seconde opération.
Un événement convient lorsqu’un fait déjà décidé doit être propagé : client activé, facture émise, expédition confirmée. Le consommateur accepte une livraison répétée et une cohérence différée. Un batch convient aux volumes massifs, aux reprises initiales ou aux données dont quelques heures de retard restent acceptables.
Le mode ne se choisit pas par préférence technique. Il dépend de la latence métier, du volume, de l’ordre requis, de la capacité de reprise et du comportement attendu si l’ERP tombe. Un même parcours peut combiner lecture synchrone du prix, événement de commande et batch nocturne de reporting.
Éviter l’écriture réussie sans événement
Le double write classique enregistre une commande puis publie un message. Si le processus s’arrête entre les deux, la commande existe sans que l’ERP la connaisse. Inverser l’ordre crée le risque opposé : l’ERP traite un message dont la transaction locale a finalement échoué.
Une outbox écrit la commande et l’événement à publier dans la même transaction. Un worker transmet ensuite les lignes validées vers le broker. La documentation AWS du transactional outbox insiste sur ce problème de double écriture et sur la nécessité de rendre les consommateurs idempotents, car un message peut toujours être envoyé plusieurs fois.
Contrat d’exécution. L’entrée contient l’identifiant métier, la version et la clé d’idempotence ; la sortie contient l’objet ERP ou un rejet structuré. Le service de commande est owner de l’outbox, le worker journalise la tentative, le broker porte l’identifiant de corrélation et l’inbox ERP mémorise les messages déjà traités.
Reprise opérationnelle. Le monitoring alerte si un événement reste non publié plus de 5 minutes. Le retry applique une temporisation et ne modifie jamais la clé. Après dix échecs, le message rejoint une file de quarantaine ; le runbook permet de corriger la cause et de rejouer sans recréer l’effet local.
Traiter les conflits sans dernier arrivé gagnant
Le timestamp le plus récent ne dit pas quelle valeur est correcte. Une correction manuelle faite dans l’ERP à 9 h 02 peut être écrasée à 9 h 03 par une copie calculée sur des données plus anciennes. La résolution doit suivre la propriété et la version métier, pas l’horloge du serveur.
Quand un champ n’a qu’un propriétaire, le conflit est simple : la valeur de l’autre système est rejetée et l’écart est enregistré. Quand une fusion est légitime, elle est définie par attribut. Pour des contacts, l’application peut ajouter une note sans modifier l’adresse de facturation. Pour un statut, une machine d’états interdit de revenir d’« expédié » à « préparé » sur un événement tardif.
Les cas réellement ambigus rejoignent une file humaine. L’écran montre les deux valeurs, leur source, leur date métier, la règle applicable et l’effet du choix. La décision produit un événement traçable au lieu d’une modification silencieuse dans la table de mapping.
Définir le comportement quand l’ERP répond mal
Une indisponibilité ne doit pas provoquer la même réponse partout. Si le prix contractuel ne peut pas être confirmé, l’application peut bloquer la commande tout en conservant le panier. Si une adresse de facturation manque, elle peut permettre un brouillon mais empêcher la validation finale. Si un libellé produit est légèrement ancien, l’affichage peut continuer avec sa date de fraîcheur.
Chaque usage possède donc une tolérance : âge maximal de la donnée, action autorisée, message utilisateur et chemin de reprise. Le cache n’est pas une excuse pour masquer une valeur obsolète. Il porte la date source et s’invalide sur l’événement du propriétaire.
Le mode dégradé est testé avec un ERP lent, une réponse partielle, un code inconnu et une coupure après l’acceptation d’une commande. Le système doit distinguer « non reçu », « reçu mais pas encore traité » et « rejeté ». Sans ces états, le support relance à l’aveugle et crée les doublons que l’intégration devait supprimer.
Limiter les droits du connecteur
Le compte technique ne devrait pas pouvoir tout lire et tout modifier. Ses droits suivent les flux : créer une commande, lire un client, consulter un prix, mais pas changer la comptabilité ou administrer les utilisateurs. Les identifiants sont stockés dans un gestionnaire de secrets et renouvelés sans redéploiement manuel.
Les appels entrants vérifient signature, origine, horodatage et protection contre le rejeu. Les données sensibles sont minimisées dans les logs. L’identifiant de corrélation permet de suivre une opération sans recopier le payload complet dans chaque outil d’observabilité.
La revue d’accès accompagne l’évolution du contrat. Lorsqu’un flux est retiré, son droit disparaît. Un environnement de recette utilise des secrets et des données propres ; il ne réemploie pas un compte de production pour accélérer un test.
Suivre fraîcheur, échecs et divergences
Le taux de succès des appels ne suffit pas. L’équipe suit le délai entre décision et disponibilité, le nombre d’objets sans correspondance, la taille des files, les messages en quarantaine, les conflits par attribut et les écarts découverts au rapprochement.
Un tableau sépare les flux : clients, tarifs, stocks, commandes et factures. Une moyenne globale peut masquer un stock figé derrière des milliers de mises à jour client réussies. Chaque domaine possède un seuil et une action : suspendre une promesse, renforcer un worker, arrêter un import ou alerter une équipe métier.
Le journal de réconciliation compare périodiquement un échantillon ou l’ensemble des clés critiques. Il ne cherche pas à rendre chaque colonne identique ; il vérifie les invariants décidés. Par exemple, toute commande expédiée doit posséder un identifiant ERP, un montant rapproché et aucune ligne orpheline.
Passer du double emploi à une seule responsabilité
La migration commence en lecture. L’application observe le résultat ERP, le traduit et compare sa propre logique sans agir. Les divergences révèlent les règles cachées, les valeurs par défaut et les exceptions réellement utilisées. Cette phase évite de supprimer une fonctionnalité que personne n’avait documentée.
Vient ensuite le transfert d’écriture sur une cohorte limitée. L’ancien écran devient en lecture seule pour les données transférées. Les deux résultats peuvent être comparés temporairement, mais un seul est appliqué. Lorsque les seuils de divergence restent acceptables et que la reprise est prouvée, le périmètre s’élargit.
Enfin, l’ancienne règle et ses droits sont retirés. Conserver un bouton caché « au cas où » maintient une seconde voie non testée. Le rollback doit restaurer la version applicative ou le routage sans rendre simultanément deux systèmes écrivains.
Cas concret : clients, tarifs et commandes
Premier scénario : un commercial crée une demande dans l’application. Le CRM possède le contact, l’ERP possède le compte facturable et l’application possède la qualification du besoin. La demande peut avancer sans compte ERP jusqu’au devis ; la transformation en commande déclenche ensuite la création idempotente du compte si nécessaire.
Deuxième scénario : le tarif est demandé à l’ERP pour 120 lignes. L’application conserve le montant, la devise, la version et l’heure du calcul, mais elle ne sait pas recalculer la remise. Si l’ERP ne répond pas sous 3 secondes, le devis reste en brouillon avec un message précis ; aucun prix précédent n’est présenté comme engageant.
Troisième scénario : la commande locale et l’outbox sont validées ensemble. Le worker publie deux fois le même événement après un timeout ; l’inbox ERP reconnaît la clé et retourne le même numéro. Le rapprochement détecte toute commande sans numéro après 5 minutes et ouvre une action. Ces seuils sont des exemples à calibrer, mais chaque chiffre commande ici une réponse connue.
Pour qui cette méthode convient
Elle convient aux entreprises qui ajoutent un portail client, un configurateur, un workflow commercial, une application terrain ou un back-office spécialisé autour d’un ERP existant. Elle est utile lorsque plusieurs systèmes — CRM, PIM, WMS ou outil métier — se partagent déjà le cycle de la commande.
Pour un export ponctuel sans mise à jour retour, une matrice complète serait disproportionnée. Il faut néanmoins définir la source, la fréquence et le traitement des erreurs. Dès que les deux côtés peuvent écrire ou qu’une décision engage un client, l’ownership devient indispensable.
Erreurs fréquentes d’une intégration ERP
- Répliquer toutes les tables : l’application hérite du schéma sans comprendre les décisions qu’il représente.
- Synchroniser dans les deux sens : chaque correction risque de relancer une boucle.
- Utiliser l’email comme clé : fusion, doublon et changement d’adresse rendent le rapprochement instable.
- Mettre les règles dans le mapping : la couche technique devient un moteur métier sans responsable.
- Réessayer sans idempotence : un timeout se transforme en second client ou en seconde commande.
- Mesurer seulement les erreurs HTTP : les divergences silencieuses restent invisibles jusqu’au contrôle comptable.
Matrice de décision avant développement
- D’abord, nommer : le propriétaire de chaque donnée, calcul et transition métier.
- Ensuite, décider : la latence acceptable et le comportement lorsque l’ERP est indisponible.
- Puis, choisir : requête synchrone, événement ou batch selon la promesse utilisateur.
- À bloquer : toute écriture bidirectionnelle d’un même attribut sans règle de conflit explicite.
- À tester : timeout après validation, doublon, message tardif, code inconnu et reprise manuelle.
- À documenter : l’invariant de rapprochement et la personne qui traite son écart.
Plan d’action en six semaines
Semaines 1 et 2 : cartographier les responsabilités
Les équipes métier et SI partent de trois parcours réels, pas du dictionnaire complet de l’ERP. Elles listent les faits lus, les décisions prises, les écritures et les exceptions. Pour chaque élément, elles désignent le système propriétaire, la latence tolérée et la réponse attendue lorsque la source manque.
Les identifiants sont recensés avec leur stabilité et leur portée. L’équipe construit les correspondances nécessaires, repère les clés ambiguës et choisit les cas qui exigent une revue humaine. Le contrat initial couvre un seul flux de valeur de bout en bout.
Semaines 3 et 4 : construire la frontière
La couche d’adaptation expose les concepts de l’application et traduit ceux de l’ERP. Les schémas d’API et d’événements sont versionnés. L’outbox, l’inbox, l’idempotence et la corrélation sont implémentées avant l’ouverture du flux d’écriture. La CI exécute les tests de contrat sur des exemples métier anonymisés.
Le monitoring couvre temps de réponse, fraîcheur, backlog, échecs et divergences. Le runbook décrit le replay, la quarantaine et le rapprochement. La sécurité limite les droits du compte technique. La recette coupe réellement l’ERP et provoque des réponses tardives au lieu de valider seulement le chemin nominal.
Semaines 5 et 6 : transférer l’écriture
Une cohorte bornée utilise la nouvelle application tandis que l’ancien écran devient en lecture seule pour le périmètre transféré. La comparaison observe les décisions, pas seulement les colonnes. Toute divergence de prix, de statut ou d’identifiant suspend l’élargissement jusqu’à une cause comprise.
Après une fenêtre représentative, l’équipe retire l’ancienne règle et ses droits. Elle conserve les preuves de rapprochement et la procédure de correction, puis étend le périmètre suivant. Le projet avance domaine par domaine afin de ne jamais confondre une connexion technique réussie avec une responsabilité réellement transférée.
Approfondir données et échanges
La question du stock traverse souvent ERP, OMS, WMS et interface. La répartition de la vérité du stock entre ces systèmes aide à distinguer quantité physique, réservation et promesse client.
Pour les informations de compte, la frontière entre CRM et portail client précise quels attributs appartiennent à la relation commerciale ou à l’usage du service.
Lorsque la latence et le volume imposent un échange différé, le choix d’une file de messages permet d’évaluer débit, reprise, ordre et coût d’exploitation avant de rendre le flux asynchrone.
Conclusion : une règle, un propriétaire
Connecter un ERP ne consiste pas à recopier ses tables dans une interface plus agréable. La première responsabilité est de décider où vivent le fait, le calcul et la transition qui engagent le métier.
Les copies de lecture restent possibles lorsqu’elles portent leur source et leur fraîcheur. Les écritures, elles, exigent identifiants stables, idempotence, contrats versionnés, conflits explicites et rapprochement observable.
Pour construire cette frontière autour de votre ERP sans déplacer sa complexité dans un second outil, Dawap propose un accompagnement en développement web sur mesure, du cadrage des responsabilités jusqu’à la mise en production.