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.

Acquittements — trois niveaux empilés

Tout flux EDI a besoin de trois accusés distincts pour être audit-clos : « j'ai reçu les octets », « la syntaxe est bonne », « j'ai pris en compte le contenu ». Les confondre est la première cause d'incidents d'intégration.

Problème

Quand l'émetteur d'un ORDERS EDIFACT veut savoir où en est sa commande, il n'a pas une question — il en a trois :

  1. Le partenaire a-t-il bien reçu les octets que j'ai envoyés ?
  2. Le message est-il syntaxiquement valide pour son parseur ?
  3. Son ERP a-t-il accepté la commande, partiellement ou en totalité ?

Sans réponse à chacune de ces trois questions, on ne peut ni clore l'envoi, ni déclencher un retry intelligent, ni alerter le bon métier. Or, dans la pratique, on voit trop souvent une seule case « ACK reçu » dans le journal d'intégration — sans préciser laquelle des trois.

Forces

  • Latence asymétrique. Les trois accusés n'arrivent pas en même temps : le transport revient en secondes, le fonctionnel en minutes, le métier en heures voire en jours.
  • Responsabilité juridique. La preuve de non-répudiation de réception (NRR) couvre uniquement les octets reçus, pas le traitement métier. Confondre les deux peut coûter cher en contentieux.
  • Multiplicité des standards. EDIFACT (CONTRL, APERAK), X12 (997, 999, 824), UBL et cXML ont chacun leurs propres formes d'accusé, et les conventions partenaires en redéfinissent souvent les seuils d'erreur.
  • Coût de l'absence d'ACK. Si le partenaire n'envoie aucun ACK fonctionnel sous N heures, faut-il retenter, alerter, ou considérer le silence comme un succès tacite ? Aucune des trois réponses n'est universelle.

Solution : trois niveaux empilés

Le pattern canonique consiste à modéliser chaque envoi avec trois états indépendants qui transitionnent sur réception d'un accusé d'un niveau donné. Une commande passe par :

  1. Niveau 1 — transport. État initial SENT. Reçoit un accusé MDN (AS2), Receipt (AS4) ou EERP (OFTP2). Transition vers DELIVERED. Si pas d'accusé dans le SLA partenaire, transition vers TRANSPORT_FAILED.
  2. Niveau 2 — fonctionnel. État DELIVERED. Reçoit un CONTRL ou un 997/999. Transition vers SYNTAX_OK ou SYNTAX_KO. C'est l'accusé qui valide que le partenaire sait lire le message — pas qu'il l'accepte.
  3. Niveau 3 — métier. État SYNTAX_OK. Reçoit un ORDRSP (EDIFACT), un 855/860/865 (X12), une ConfirmationRequest (cXML) ou une InvoiceResponse UBL. Transition vers ACCEPTED, PARTIAL ou REJECTED.
plaintext acquittements.txt
Émetteur                                Récepteur
────────                                ─────────

[1] POST AS2 (ORDERS D.96A signé)        ───►
                          ◄─── [2] HTTP 200 + MDN signé (Received-content-MIC)

  (côté récepteur, parse EDIFACT)
                          ◄─── [3] CONTRL — accusé syntaxique
  (côté récepteur, intégration ERP)
                          ◄─── [4] ORDRSP — réponse fonctionnelle
                                    (acceptation totale / partielle / rejet)

  Légende :
  [1]  Envoi
  [2]  Accusé de transport       — l'octet est passé
  [3]  Accusé fonctionnel        — la syntaxe est valide
  [4]  Accusé métier             — la commande est traitée

Implémentation EDIFACT — CONTRL et APERAK

En EDIFACT le niveau 2 (fonctionnel) est porté par le message CONTRL (UN/EDIFACT D.95B+). Il contient un segment UCI avec la référence de l'interchange acquitté, un UCM par message couvert, et un code d'action : 4 accepté, 7 rejet syntaxique, 8 rejet partiel. Le niveau 3 (métier) peut être porté par un APERAK en cas d'erreur d'application, ou directement par la réponse fonctionnelle ORDRSP.

edifact contrl-d96a.edi
UNB+UNOC:3+RECEIVER:14+SENDER:14+260514:1545+CTRL900042'
UNH+CTRL1+CONTRL:2:2:UN'
UCI+CTRL000001+SENDER:14+RECEIVER:14+7'
UCM+1+ORDERS:D:96A:UN+7'
UNT+4+CTRL1'
UNZ+1+CTRL900042'

Implémentation X12 — 997, 999, 824, 855

Le niveau 2 en X12 a deux variantes. Le 997 (Functional Acknowledgment, 4010+) couvre la syntaxe au niveau du groupe fonctionnel et de la transaction. Le 999 (Implementation Acknowledgment, 5010+) ajoute la conformité au guide d'implémentation partenaire (HIPAA impose explicitement le 999 depuis 2012). Pour les erreurs métier l'824 (Application Advice) sert d'APERAK X12. Le niveau 3 est en général le 855 (Purchase Order Acknowledgment).

plaintext 997-functional-ack.edi
ISA*00*          *00*          *ZZ*RECEIVER       *ZZ*SENDER         *260514*1545*U*00401*900000042*0*P*>~
GS*FA*RECEIVER*SENDER*20260514*1545*42*X*004010~
ST*997*0001~
AK1*PO*1000~
AK2*850*1001~
AK5*A~
AK9*A*1*1*1~
SE*6*0001~
GE*1*42~
IEA*1*900000042~

Lecture du 997 ci-dessus : l'AK1*PO*1000 identifie le groupe fonctionnel original (control number 1000), l'AK2*850*1001 cible la transaction 850 (control number 1001), l'AK5*A signale Accept, et l'AK9*A*1*1*1 résume : 1 groupe reçu, 1 accepté, 1 transaction acceptée.

Implémentation transport — MDN, Receipt, EERP

Le niveau 1 dépend du protocole :

  • AS2 — MDN signé contenant Received-content-MIC (cf. la page AS2). MDN synchrone ou asynchrone selon le profil partenaire.
  • AS4 — SignalMessage avec eb:Receipt et bloc NonRepudiationInformation (cf. AS4).
  • OFTP2 — EERP signé en CMS, émis après consommation applicative du Virtual File (cf. OFTP2).
  • SFTP — pas d'accusé natif. Une convention bilatérale (fichier .ok ou .contrl) sert d'accusé transport.

Séquence canonique

Anti-patterns

  • « Pas d'ACK = succès ». Un partenaire qui ne renvoie pas de 997 fait un succès tacite ? Non. Sauf clause contractuelle explicite, l'absence d'ACK est un échec.
  • Compter le MDN comme accusé métier. Un MDN signé prouve la réception des octets, pas l'acceptation de la commande. La preuve NRR juridique ne couvre que la couche transport.
  • CONTRL silencieux en cas de succès. Certaines implémentations EDIFACT historiques n'émettent CONTRL qu'en cas d'erreur — l'absence est alors supposée valoir succès. Mauvaise pratique : imposer un CONTRL action 4 (acknowledgement) même sur succès.
  • Retentes déclenchées sur niveau 1 manquant. Si l'on retente sur absence de MDN, on peut envoyer deux fois la même commande au partenaire — d'où la nécessité d'idempotence.
  • Délais d'alerte uniformes. Un délai d'attente CONTRL de 24h pour tous les partenaires masque les vrais incidents : un partenaire qui retourne historiquement le CONTRL en 10 minutes et qui met soudain 12 heures est probablement en panne, même si on est dans le SLA générique.

Patterns liés

  • Idempotence — pour ne pas retransmettre deux fois la même commande pendant qu'on attend un ACK.
  • Retry & backoff — la politique de retransmission quand un ACK manque.
  • Flux d'exception — la matrice d'escalade quand l'ACK métier est négatif.

Sources

  • Hohpe G., Woolf B. — Enterprise Integration Patterns, pattern Guaranteed Delivery et pattern Return Address. enterpriseintegrationpatterns.com — Guaranteed Delivery
  • RFC 4130 §7.2 — MDN reliability, retries, sync vs async. rfc-editor.org/rfc/rfc4130
  • ASC X12 — 997 Functional Acknowledgment, technical report TR3 (version 004010). Lecture publique des codes AK1/AK2/AK5/AK9.
  • UN/CEFACT — CONTRL D.95B+. Définition canonique du message d'accusé EDIFACT. service.unece.org/trade/untdid
  • Walmart Supplier CenterWalmart EDI Guidelines pour la convention 997 + 855 imposée à tous les fournisseurs depuis 2002.