ediverse Explorer la plateforme

À la une PEPPOL BIS Billing 3.0 L’obligation européenne d’e-invoicing arrive : France sept 2026, Belgique janv 2026, Allemagne 2025.

Idempotence et déduplication

Une même commande ne doit jamais être livrée deux fois. Le pattern est simple à formuler, brutal à implémenter quand on s'aperçoit qu'un retry storm a injecté 14 000 doublons dans l'ERP.

Problème

Dans toute communication EDI réelle, des envois peuvent être rejoués. Cause typique : le partenaire a bien reçu et traité le message, mais le MDN est perdu sur le retour réseau. L'émetteur, qui suit son SLA, retransmet. Sans dispositif d'idempotence côté récepteur, la commande est intégrée deux fois — et chaque doublon coûte du temps métier à isoler et à annuler (réception en double, facture en double, paiement potentiel en double).

Forces

  • L'émetteur ne sait pas avec certitude. Si le MDN est perdu, l'émetteur ne peut pas distinguer « le partenaire ne l'a pas reçu » de « le partenaire l'a reçu mais le MDN s'est perdu ». Conséquence : il doit retenter par sécurité.
  • Le récepteur doit donc tolérer les doublons. C'est lui qui porte la charge de la déduplication, parce qu'il est le seul à avoir une vue cohérente de ce qu'il a déjà traité.
  • La fenêtre de déduplication a un coût. Conserver l'historique de toutes les références déjà reçues est coûteux en stockage et en performance si l'on n'établit pas une fenêtre.
  • Les standards EDI fournissent la clé. UNB, ISA, AS4 définissent des références uniques par interchange — encore faut-il que les partenaires les utilisent correctement et que la fenêtre soit cohérente des deux côtés.

Solution : une clé d'unicité par envoi

Le pattern Idempotent Receiver (Hohpe & Woolf, 2003) prescrit de :

  1. Garantir, côté émetteur, qu'une retransmission utilise strictement la même clé d'unicité que l'envoi initial — pas une nouvelle clé.
  2. Côté récepteur, tenir une table des clés reçues sur une fenêtre temporelle connue contractuellement (souvent 30, 90 ou 180 jours en EDI). À la réception, vérifier l'absence de la clé : si elle existe, le message est un doublon → on renvoie l'ACK original (pour rassurer l'émetteur) mais on n'intègre pas.
  3. Définir un comportement explicite hors-fenêtre : en pratique, considérer le message comme nouveau et l'intégrer (avec un log d'avertissement).

EDIFACT — UNB Interchange Control Reference

Le segment UNB (Interchange Header) porte un Interchange Control Reference (composite 0020) qui doit être unique entre les deux partenaires pendant une fenêtre négociée. La norme ISO 9735 ne fixe pas cette fenêtre — elle est laissée à la convention bilatérale. La grande distribution européenne (EANCOM) recommande 14 caractères alphanumériques uniques sur 90 jours. La référence est répétée dans le trailer UNZ pour bornage.

edifact interchange-with-ctrl.edi
UNB+UNOC:3+SENDER:14+RECEIVER:14+260514:1545+ORD202605140001'
UNH+1+ORDERS:D:96A:UN:EAN008'
...
UNZ+1+ORD202605140001'

Lecture : l'ORD202605140001 ci-dessus est une convention Walmart-like — préfixe métier ORD, date 20260514, compteur 0001. Cette structure garantit qu'aucune retransmission accidentelle ne se présentera sous une nouvelle référence.

X12 — ISA13 et GS06

En X12 la clé d'idempotence est composite. L'élément ISA13 (Interchange Control Number) est le numéro de contrôle d'interchange — neuf chiffres incrémentaux, unique côté émetteur. L'élément GS06 (Group Control Number) est le numéro de groupe fonctionnel, unique à l'intérieur d'un interchange et répété en GE02. Pour la déduplication, on utilise typiquement le couple (émetteur, ISA13) comme clé primaire dans la table d'unicité.

plaintext x12-with-isa13.edi
ISA*00*          *00*          *ZZ*SENDERID       *ZZ*RECEIVERID     *260514*1545*U*00401*900042001*0*P*>~
GS*PO*SENDERID*RECEIVERID*20260514*1545*42*X*004010~
ST*850*0001~
...
SE*42*0001~
GE*1*42~
IEA*1*900042001~

L'enveloppe X12 stocke ISA13 sur 9 caractères, donc une fenêtre de roulement à 109 envois — soit, à 100 000 envois par jour, environ 27 ans avant collision théorique. Largement suffisant pour la fenêtre contractuelle de 6 mois en pratique.

AS4 — eb:MessageId et duplicate detection

AS4 systématise la déduplication au niveau protocole. Le bloc eb:Messaging contient un eb:MessageId obligatoire — typiquement un UUID, garanti unique par construction. La spécification AS4 (§3.2.3.3) définit une fonctionnalité optionnelle de Duplicate Detection que le récepteur peut activer : il journalise le MessageId et, sur réception d'un doublon, il ré-émet le même Receipt que la première fois sans re-livrer le payload à l'application.

Dans le réseau PEPPOL, la duplicate detection est obligatoire sur tous les Access Points. C'est ce qui permet à un émetteur de retenter sans peur après un timeout : la garantie est portée par le réseau, pas par l'application métier.

Fenêtre d'unicité côté récepteur

Trois questions à se poser explicitement :

  • Durée de la fenêtre. 30 jours est la valeur minimum, 90 jours la valeur recommandée pour les flux opérationnels (commandes, avis d'expédition), 180 jours à 1 an pour les flux financiers (factures, paiements) où le rejeu peut intervenir longtemps après.
  • Granularité de la clé. La clé peut être (a) la référence d'enveloppe seule (UNB CTRL, ISA13), (b) la référence d'enveloppe + identifiant émetteur, ou (c) la référence + hash du payload. L'option (b) est le standard ; l'option (c) protège aussi contre les replays malveillants.
  • Réponse sur doublon. Renvoyer le même ACK que la première fois est la bonne pratique — cela rassure l'émetteur sans polluer le journal métier. Ne jamais renvoyer une erreur « déjà reçu » qui pourrait déclencher des escalades indues.

Anti-patterns

  • Nouvelle clé à chaque retransmission. L'émetteur qui regénère un UNB CTRL différent à chaque tentative casse complètement la déduplication : le récepteur intègre N fois la commande. Toujours réutiliser la clé de l'envoi initial pour les retentes.
  • Fenêtre infinie. Garder pour toujours toutes les références déjà reçues est inutile et coûteux. Toujours définir une fenêtre explicite et purger au-delà.
  • Idempotence côté émetteur seul. Penser que c'est à l'émetteur de ne pas retransmettre est naïf : l'émetteur ne sait pas si le récepteur a réellement intégré. Le pattern doit impérativement être implémenté côté récepteur.
  • Déduplication par hash payload uniquement. Si deux commandes véritablement distinctes ont le même contenu (même client, même produit, même quantité, même date), le hash sera identique et la seconde sera rejetée à tort. Toujours utiliser la référence d'enveloppe en clé primaire, le hash en seulement complément.
  • Réinitialisation des compteurs ISA13. Un partenaire qui remet ISA13 à 1 après un redémarrage casse l'unicité — il faut persister le compteur dans une base, pas en mémoire.

Patterns liés

  • Acquittements — pour comprendre quand l'émetteur déclenche une retransmission.
  • Retry & backoff — la politique qui génère naturellement des doublons.

Sources

  • Hohpe G., Woolf B. — Enterprise Integration Patterns, pattern Idempotent Receiver. enterpriseintegrationpatterns.com — Idempotent Receiver
  • ISO 9735 §6.5 — Interchange Control Reference, fenêtre d'unicité bilatérale (le standard de syntaxe EDIFACT).
  • X12 .004010 — section ISA / GS. Définition des Interchange Control Number et Group Control Number.
  • OASIS AS4 Profile §3.2.3.3 — Duplicate Detection, semantique de la déduplication sur eb:MessageId. docs.oasis-open.org/ebxml-msg/ebms/v3.0/profiles/AS4-profile
  • OpenPEPPOL — Reception Profile. Spécifie la duplicate detection comme exigence des Access Points.