Un acheteur ajoute cent vingt pièces au panier. Son contrat prévoit un prix net jusqu’à quatre-vingt-dix-neuf unités, une remise de volume au-delà, une surcharge matière révisée chaque mois et une exception pour son établissement suisse. Le devis signé affiche 18,42 € l’unité ; le panier calcule 17,95 € ; l’ERP facture 18,67 €. Le problème n’est pas une décimale : trois systèmes ont pris une décision commerciale différente.
Le risque est double. Une erreur défavorable déclenche litige et correction manuelle ; une erreur favorable peut éroder la marge sans alerte. Copier les règles de l’ERP dans le site accélère parfois une première livraison, mais crée deux calendriers, deux conventions d’arrondi et deux réponses possibles à la même question.
La thèse de ce guide est simple : un moteur de prix B2B ne doit pas seulement retourner un total. Il doit produire une décision explicable, datée et reproductible à partir d’un contexte fermé. Vous allez pouvoir décider qui possède chaque règle, comment les priorités se composent, ce qui est figé au devis et quels seuils locaux imposent un arrêt.
Dans une démarche de développement web sur mesure, le bon objectif n’est donc pas de rendre toute remise configurable. Il consiste à construire un contrat de calcul partagé par le catalogue, le panier, le devis, la commande, la facture et le support, avec une reprise vérifiable lorsque l’une des dépendances ne répond plus.
Traiter le prix comme une décision, pas comme un champ
Le « prix » visible est le résultat d’une suite de choix : offre éligible, unité de vente, quantité, tarif de base, conditions de contrat, remises, surcharges, devise, taxe et arrondi. Chacun possède une provenance et une date d’effet. Enregistrer uniquement le total fait perdre la raison du montant, donc la capacité à répondre à un client ou à corriger une règle.
Un résultat exploitable contient le montant unitaire, le total, la devise, les taxes, les composants appliqués et refusés, la version des règles et un identifiant de calcul. Il distingue estimation, offre ferme et montant accepté. Cette distinction évite qu’un aperçu de catalogue soit présenté comme un engagement contractuel.
Contre-intuitivement, un moteur qui renvoie davantage de détails peut être plus simple à exploiter. Les composants rendent les divergences localisables : base correcte, remise absente, surcharge périmée ou arrondi différent. Sans eux, toute anomalie devient « le prix est faux » et exige une reconstitution complète.
Fermer le contexte de calcul
Le calcul reçoit des identifiants stables : offre, organisation acheteuse, établissement, contrat, quantité, unité, configuration, canal, destination, devise et instant métier. Les libellés et adresses libres n’identifient pas une règle. Le backend reconstitue les droits depuis l’identité authentifiée ; il ne fait pas confiance à un segment client envoyé par le navigateur.
L’instant métier doit être nommé. Pour un panier, s’agit-il du moment de consultation, de validation ou d’acceptation du devis ? Pour une commande différée, la règle dépend-elle de la date d’émission ou de livraison ? Une convention unique évite qu’un tarif expirant à minuit soit accepté sur un canal et refusé sur un autre.
Distinguer donnée absente et donnée inconnue
Une quantité absente est une erreur de contrat ; une quantité inconnue peut déclencher une estimation. Un contrat manquant peut conduire au tarif public si cette règle est autorisée, mais un contrat ambigu doit bloquer. Le moteur retourne un statut explicite plutôt que zéro, null ou le dernier prix connu.
Attribuer chaque donnée à une autorité
L’ERP peut posséder les tarifs de base et les contrats, le PIM les unités et attributs commerciaux, le CRM l’appartenance du client, tandis qu’un service dédié évalue les règles. « Source de vérité » ne signifie pas qu’un seul outil possède tout. Elle signifie que, pour chaque décision, une autorité écrit et les autres consomment une projection identifiable.
La matrice d’autorité précise objet, champ, owner, moyen de diffusion, délai attendu et comportement en cas de retard. Si le CRM change un établissement mais que le moteur conserve un cache, le délai de propagation devient une règle métier. Le site peut afficher « conditions en cours de mise à jour » plutôt que promettre un montant non prouvé.
Les corrections manuelles sont des commandes possédées, pas des edits directs en base. Elles portent motif, périmètre, auteur, approbateur, expiration et lien vers le contrat. Une dérogation sans date de sortie devient une politique parallèle et finit par gagner silencieusement sur la règle officielle.
Rendre les priorités déterministes
Les règles sont classées par nature avant d’être ordonnées : éligibilité, remplacement de base, remise, surcharge, plancher, arrondi. Un contrat peut remplacer le tarif de base ; une promotion peut être cumulable ou exclusive ; un plancher de marge peut déclencher une validation. Une simple colonne « priorité 1 à 999 » ne dit pas comment des familles différentes se composent.
La stratégie de résolution doit être lisible par le métier. Par exemple : choisir l’offre la plus spécifique, appliquer le prix contractuel, ajouter les options, appliquer les remises cumulables, ajouter les surcharges, contrôler le plancher, convertir puis arrondir. Chaque étape publie ses entrées, sa sortie et le motif d’une exclusion.
Deux règles de même niveau et de même périmètre ne doivent pas être départagées par leur ordre d’insertion. Elles créent un conflit à résoudre avant publication. Si une remise exclusive rencontre une autre remise exclusive, alors le moteur refuse la version plutôt que de choisir arbitrairement la dernière créée.
Versionner périodes et contrats
Une règle possède un intervalle d’effet, un fuseau, un statut et une version. Les bornes sont explicites, par exemple début inclus et fin exclue. Cela évite que deux tarifs soient actifs à la même milliseconde. Les types d’intervalle de PostgreSQL et les contraintes d’exclusion peuvent aider à empêcher des chevauchements, à condition que le périmètre métier soit lui aussi modélisé.
La date de saisie ne remplace pas la date d’effet. Une correction rétroactive peut être nécessaire pour une facture, mais elle ne doit pas réécrire les commandes déjà acceptées. Le modèle conserve « connu depuis » et « valable pour » afin de distinguer audit technique et réalité contractuelle.
Préparer une règle future
Une version future est testée en observation avec des paniers représentatifs. La publication vérifie conflits, références et dépendances. Le rollback désactive cette version et restaure la précédente pour les nouveaux calculs ; il ne recalcule pas les commandes historiques.
Composer quantités, devises, taxes et arrondis
Les seuils de volume portent une unité. Dix cartons de douze ne valent cent vingt unités que si la conversion est autorisée. La règle précise si la remise s’applique à toute la ligne ou seulement à la tranche. Le détail affiché au commercial doit reprendre cette convention, faute de quoi deux calculs exacts peuvent sembler contradictoires.
Les montants sont manipulés en décimal ou en unité mineure selon la devise, jamais en flottant binaire pour la décision contractuelle. La séquence d’arrondi est fixée : composant, ligne, taxe ou total. Le nombre de décimales internes peut dépasser celui affiché, mais le snapshot conserve les valeurs nécessaires à la reproduction.
La conversion monétaire enregistre taux, source, instant et sens. Les taxes dépendent du contexte fiscal validé ; elles ne sont pas une remise. Un prix « hors taxe » doit rester distinguable du montant payable. Le moteur retourne un défaut qualifié si la destination ou le statut fiscal est insuffisant.
Relier panier, devis et commande sans recalcul silencieux
Le panier est une simulation mutable. Un devis est une proposition identifiée avec durée, conditions et version. Son acceptation produit une preuve : lignes, unités, composants de prix, devise, taxes, quantités et contexte utile. La commande reprend ce snapshot ou refuse l’écart ; elle ne demande pas au moteur actuel ce que le client « aurait dû » payer.
Une modification significative — quantité hors tolérance, configuration changée, destination différente — crée une révision. Les changements purement éditoriaux ne l’invalident pas. Cette frontière est possédée par le métier et testée. Le client voit pourquoi une nouvelle validation est requise.
Le snapshot ne signifie pas copier toutes les données personnelles. Il conserve les éléments opposables et leurs identifiants, avec la politique de rétention adaptée. Les commandes anciennes restent interprétables même lorsque le contrat ou l’offre n’est plus actif.
Cas concret : un distributeur industriel et ses contrats imbriqués
Par exemple, si un groupe possède trois établissements, alors le contrat groupe fournit le prix de base, l’établissement lyonnais ajoute une remise annuelle et une offre projet fixe un montant sur deux références. Le moteur sélectionne d’abord l’établissement livré, puis l’offre projet la plus spécifique. La promotion publique est refusée car le contrat la déclare non cumulable.
Le test utilise quatre quantités autour du seuil local choisi par le métier : 99, 100, 101 et 250 unités. Il couvre aussi veille et jour d’effet, client autorisé et voisin non autorisé, euros et francs suisses. Le seuil n’est pas présenté comme universel : il provient du contrat analysé et doit être remplacé pour un autre client.
Cas concret. Le devis accepté à 100 unités reste à 18,42 €. Le client passe à 101 unités après acceptation ; si la tolérance contractuelle est nulle, alors une révision est obligatoire. En revanche, une correction d’adresse sans incidence fiscale conserve le devis. La preuve permet au support de distinguer ces deux scénarios sans tableur.
Implémenter un moteur de prix testable
Fermer contrat, fonctions et résultats
Les entrées et sorties sont versionnées ; les responsabilités séparent résolution du contexte, sélection des règles et calcul. Les dépendances ERP, PIM et CRM sont explicites. Une clé idempotence identifie la demande lorsque le calcul déclenche une réservation ou une trace durable, tandis qu’un calcul pur peut être rejoué sans effet.
La journalisation conserve identifiant, version, règles appliquées, règles écartées et latence. Le monitoring agrège erreurs, conflits et écarts sans exposer les remises négociées. Des seuils locaux déclenchent un repli : par exemple, suspendre l’ouverture si plus de deux divergences inexpliquées apparaissent sur le lot pilote, plutôt que tolérer un pourcentage arbitraire.
Tester par propriétés et exemples
Les tests unitaires couvrent chaque règle, ses bornes et son contre-exemple. Les tests de propriété vérifient qu’une remise plafonnée ne dépasse pas son plafond, qu’un montant final reste reproductible et qu’un client sans droit n’obtient jamais une condition privée. Les jeux dorés proviennent de devis approuvés et sont révisés avec la finance.
Le retry ne remplace pas une politique d’échec. Si l’autorité du contrat est indisponible et que le cache n’est plus dans sa fenêtre autorisée, le moteur retourne « prix à confirmer » ou bloque selon le parcours. Le runbook décrit owner, seuil, repli, rollback et reprise des calculs au verdict inconnu.
Protéger les conditions négociées
Le prix contractuel est une donnée autorisée par contexte. Le backend vérifie organisation, établissement et offre à chaque lecture, export et recalcul. Une URL devinable ou un cache CDN partagé ne doit pas révéler le montant d’un autre compte. La clé de cache inclut le contexte pertinent ou la réponse reste privée.
Les journaux privilégient identifiants de règle et empreintes plutôt que conditions complètes. L’administration sépare création, approbation et publication lorsque le risque métier le justifie. Une modification sensible porte un avant/après consultable et, si nécessaire, une double validation.
Les aperçus « comme ce client » sont eux-mêmes tracés et limités. Ils ne doivent pas permettre au support de commander au nom d’un compte. La capacité de diagnostic et la capacité d’engagement restent deux permissions différentes.
Observer les écarts, les caches et les reprises
Le monitoring utile rapproche prix du panier, devis, commande et facture sur le même identifiant. Il suit conflits de règles, calculs incomplets, âges de projection, latence, usage du repli et corrections manuelles. Chaque métrique possède un owner et une action, pas seulement une couleur.
Une divergence entre deux canaux est rejouée avec le contexte enregistré. Le support voit le composant différent et sa provenance. Si le cache a servi une version périmée, le correctif invalide précisément les clés concernées ; il ne vide pas tout en production comme réponse habituelle.
La réconciliation traite en priorité les commandes au verdict ambigu. Le rollback ferme la nouvelle version pour les futurs calculs. La reprise recalcule les paniers non engagés, demande confirmation pour les devis concernés et préserve les snapshots déjà acceptés.
Identifier les projets concernés
Cette architecture concerne grossistes, industriels, réseaux et services B2B dont les conditions dépendent de contrats, volumes, établissements, projets ou configurations. Commerce, finance, ADV, produit, sécurité, data et support participent. Le métier possède les règles ; l’équipe technique possède leur exécution fiable.
Pour un catalogue simple avec un tarif public et une remise unique par segment, les capacités natives de la plateforme peuvent suffire. Un service dédié devient pertinent lorsque plusieurs systèmes calculent, que les règles se chevauchent, que le devis engage ou que la preuve doit survivre aux évolutions.
Le volume de commandes n’est pas le seul critère. Cinquante commandes mensuelles à forte valeur et très négociées peuvent justifier plus de contrôle que dix mille paniers simples. La décision suit coût d’erreur, fréquence des exceptions et capacité réelle du support à expliquer le montant.
Erreurs fréquentes : six défauts coûteux
Coder la priorité dans des conditions dispersées
Des if dans le frontend, le checkout et l’ERP produisent des résultats divergents. Centralisez la décision ou un contrat partagé, puis exposez provenance et version.
Utiliser le prix public comme repli universel
Ce choix peut violer un contrat ou révéler une condition incohérente. Décidez par parcours si le prix peut être estimé, doit être confirmé ou doit bloquer.
Écraser un devis accepté
Recalculer avec les règles présentes détruit la preuve. Conservez le snapshot et créez une révision quand l’entrée contractuelle change.
Confondre remise, taxe et arrondi
Le total devient impossible à expliquer. Gardez les composants et leur ordre, avec les valeurs avant et après chaque étape.
Mettre toutes les conditions dans les logs
Le diagnostic ne justifie pas une fuite commerciale. Journalisez identifiants, versions et motifs ; réservez les détails aux rôles autorisés.
Publier sans cas de frontière
Un test nominal ne couvre ni seuil, ni date, ni cumul. Testez les valeurs juste avant, à et juste après chaque borne locale.
Décider : ERP, plateforme ou service de prix dédié
Bloc de décision. Conservez le calcul natif de la plateforme si une seule autorité, peu de règles et aucun engagement durable suffisent. Si l’ERP sait calculer à la latence du parcours et expliquer son résultat, alors exposez-le par un contrat stable. En revanche, créez un service dédié lorsque plusieurs canaux ont besoin du même verdict, que les règles exigent versions, simulation et preuve.
Priorisez identité client, périmètre du contrat, dates et snapshot plutôt que l’éditeur universel de remises. Différez les règles dont l’owner ou le contre-exemple manque. Refusez une ouverture si le site et la facture ne peuvent pas être rapprochés. Choisissez plutôt un devis assisté qu’un prix automatique non défendable.
- Conserver une autorité et un contrat de calcul par décision.
- Tester bornes, cumuls et droits avant publication.
- Ouvrir un périmètre où panier, devis et facture se rapprochent.
- Étendre seulement après rollback et reprise d’un cas ambigu.
Plan d’action en huit semaines
Semaines 1 et 2 : cartographier les décisions
Prélevez trente commandes, quinze devis, cinq avoirs et les contrats associés. Reconstituez le prix depuis les sources existantes. Nommez les composants, périodes, unités, arrondis, owners et corrections. Mesurez divergences, temps de recherche et impact de marge sans transformer ce lot en moyenne universelle.
Semaines 3 à 5 : construire et comparer
Fermez le contexte, le modèle de règles et la sortie explicable. Importez une famille et trois contrats. Exécutez le nouveau calcul en observation face au parcours actuel. Classez les écarts : donnée, priorité, période, unité, arrondi ou défaut de droit.
Provoquez date d’effet, quantité à la borne, changement d’établissement, cache ancien, dépendance indisponible et retry. Vérifiez les entrées, sorties, responsabilités, dépendances, journalisation et monitoring. Documentez le seuil local qui suspend la tranche et l’action attendue.
Semaines 6 à 8 : ouvrir une tranche contrôlée
Ouvrez une famille, trois contrats et un canal. Le support doit expliquer chaque montant depuis l’identifiant de calcul. Rapprochez panier, devis, commande et facture. Jouez rollback de version et reprise des paniers non engagés avant d’ajouter un client.
La revue décide selon les divergences inexpliquées, le délai de diagnostic et la marge corrigée. Si le lot pilote dépasse le seuil fixé par la finance, alors réduisez le périmètre. En revanche, étendez lorsqu’une période représentative reste sans correction cachée et que le runbook a été utilisé par l’équipe d’astreinte.
Enfin, révisez les droits et la rétention des snapshots. Vérifiez un devis expiré, une commande ancienne et une facture contestée. Chaque impossibilité de reproduction reçoit un owner et une échéance avant la vague suivante.
- Partir de prix réels et de leurs preuves.
- Fermer contexte, priorité, période et arrondi.
- Comparer en observation avant d’engager.
- Ouvrir par contrat avec seuil, rollback et reprise.
Relier catalogue, plateforme et tunnel de commande
Le guide des catalogues et tarifs négociés précise l’identité des offres et configurations. Le guide du tunnel spécifique aide à préserver cette décision jusqu’au paiement.
L’observabilité des workflows métier complète la chaîne lorsque prix, devis et facture traversent plusieurs systèmes. Ces principes doivent être testés avec les contrats, volumes et conventions propres à votre activité.
- Relier toute règle à son owner et à sa période.
- Conserver le détail du prix accepté dans la commande.
- Tester les droits d’un client voisin avant chaque extension.
Conclusion : rendre le prix accepté prouvable
Un prix B2B fiable n’est pas une valeur recopiée entre outils. C’est une décision produite depuis un contexte fermé, des règles prioritaires, des périodes non ambiguës et des composants explicables. Cette décision possède une version et un owner.
Le panier peut simuler ; le devis propose ; la commande conserve le snapshot accepté. Les évolutions futures ne réécrivent pas le passé. Les exceptions légitimes passent par une révision possédée plutôt que par un total modifié à la main.
Le meilleur test reste opérationnel : le support peut-il expliquer un écart entre site et facture, identifier la règle concernée et restaurer le parcours sans révéler un autre contrat ? Si la réponse dépend d’un tableur privé, le système n’est pas encore prêt à s’étendre.
Dawap peut vous accompagner pour cadrer et mettre en place ce moteur dans une démarche de développement web sur mesure : modèle de prix, intégration ERP, règles, snapshots, sécurité, tests de frontières et préparation du run.