cXML PunchOutOrderMessage
Message qui clôt une session punchout et transfère le panier que l'utilisateur a construit chez le fournisseur vers l'ERP de l'acheteur. Posté par le navigateur, pas par le serveur fournisseur — particularité capitale du flux.
Objet de la transaction
Quand l'utilisateur clique sur "Checkout" dans le catalogue du fournisseur, le
fournisseur ne poste pas le panier en serveur-à-serveur. Il génère une page HTML
avec un <form> caché contenant le PunchOutOrderMessage
en cXML, et soumet ce formulaire depuis le navigateur de l'utilisateur, qui le
relaie vers la BrowserFormPost URL communiquée par l'ERP au moment du
setup.
L'ERP réassocie le panier reçu à sa demande d'origine grâce au BuyerCookie
— c'est le seul lien entre le PunchOutSetupRequest et ce message. Le
PunchOutOrderMessage n'est pas une commande au sens cXML :
c'est un panier qui sera transformé en OrderRequest après validation
interne dans l'ERP.
Structure XML
Le DTD déclare :
PunchOutOrderMessage (BuyerCookie, PunchOutOrderMessageHeader, ItemIn*).
Le contenu utile est donc en trois blocs : le cookie qui sert de corrélation
de session, un header qui résume les montants, et la liste des articles que
l'utilisateur a placés dans son panier.
Le PunchOutOrderMessageHeader est défini comme : (SourcingStatus?,
Total, ShipTo?, Shipping?, Tax?, SupplierOrderInfo?). Seul Total
est obligatoire au contenu. L'attribut operationAllowed est
#REQUIRED et indique le type d'opération que l'acheteur peut faire
sur le panier : create (utiliser tel quel), inspect
(le réouvrir en lecture seule plus tard) ou edit (le réouvrir pour
modification — implique que le fournisseur stocke l'état pour pouvoir le restaurer).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.069/cXML.dtd">
<cXML payloadID="260513.150500.poom@supplier.example"
timestamp="2026-05-13T15:05:00+02:00"
version="1.2.069">
<Header>
<From>
<Credential domain="DUNS"><Identity>987654321</Identity></Credential>
</From>
<To>
<Credential domain="DUNS"><Identity>123456789</Identity></Credential>
</To>
<Sender>
<Credential domain="DUNS">
<Identity>987654321</Identity>
<SharedSecret>shared-secret-here</SharedSecret>
</Credential>
<UserAgent>supplier-catalog/3.2</UserAgent>
</Sender>
</Header>
<Message>
<PunchOutOrderMessage>
<BuyerCookie>session-abc-12345</BuyerCookie>
<PunchOutOrderMessageHeader operationAllowed="edit">
<Total>
<Money currency="EUR">129.97</Money>
</Total>
<ShipTo>
<Address>
<Name xml:lang="fr">Acheteur SA — Site Paris</Name>
<PostalAddress>
<Street>10 rue de la Paix</Street>
<City>Paris</City>
<PostalCode>75002</PostalCode>
<Country isoCountryCode="FR">France</Country>
</PostalAddress>
</Address>
</ShipTo>
</PunchOutOrderMessageHeader>
<ItemIn quantity="3" lineNumber="1">
<ItemID>
<SupplierPartID>SKU-A100</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice><Money currency="EUR">29.99</Money></UnitPrice>
<Description xml:lang="fr">Chaise de bureau ergonomique noire</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
<Classification domain="UNSPSC">56101504</Classification>
<ManufacturerName>Acme Furniture</ManufacturerName>
</ItemDetail>
</ItemIn>
<ItemIn quantity="2" lineNumber="2">
<ItemID>
<SupplierPartID>SKU-B200</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice><Money currency="EUR">20.00</Money></UnitPrice>
<Description xml:lang="fr">Repose-pieds réglable</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
<Classification domain="UNSPSC">56121601</Classification>
<ManufacturerName>Acme Furniture</ManufacturerName>
</ItemDetail>
</ItemIn>
</PunchOutOrderMessage>
</Message>
</cXML> Requis vs optionnel
Dans le corps du message : BuyerCookie et
PunchOutOrderMessageHeader sont obligatoires (cardinalité 1), les
ItemIn* sont optionnels mais en pratique présents — c'est l'objet du
message. Un panier vide est théoriquement possible (utilisateur qui sort sans rien
acheter) mais inhabituel.
Sur PunchOutOrderMessageHeader : operationAllowed est
#REQUIRED, quoteStatus a une valeur par défaut
"final" (alternative : "pending"). Le contenu impose
un Total obligatoire ; ShipTo, Shipping,
Tax, SourcingStatus et SupplierOrderInfo sont
optionnels.
Sur chaque ItemIn : quantity est #REQUIRED,
lineNumber est #IMPLIED (mais quasi systématiquement
fourni). Le contenu impose ItemID et ItemDetail. Le
ItemDetail impose UnitPrice, au moins une Description,
UnitOfMeasure et au moins une Classification.
Patterns courants
Le navigateur comme courrier n'est pas un détail : cela signifie
que le serveur fournisseur ne connaît jamais l'URL BrowserFormPost sous
sa forme finale (il pourrait être derrière un load balancer interne de l'acheteur).
Il ne signe pas non plus le message côté HTTP — c'est le contenu cXML lui-même qui
porte les credentials, et l'ERP authentifie via le SharedSecret partagé
et le BuyerCookie.
Le panier d'un punchout est complet et autonome : pas de
référence à un quelconque OrderRequest préalable. Chaque ItemIn doit
porter le prix, la description, l'unité et la classification. L'ERP s'en servira
pour générer son propre OrderRequest après validation.
Astuce d'implémentation : générer aussi un identifiant côté supplier dans
SupplierOrderInfo pour pouvoir corréler ultérieurement
OrderRequest ↔ panier punchout.
Flux Punchout (vue finale)
Le PunchOutOrderMessage est l'étape 2 du flux complet :
Acheteur (ERP) Navigateur utilisateur Fournisseur (catalogue)
│ │ │
│ │ (session web active) │
│ │◄─────────────────────────────────┤
│ │ │
│ │ l'utilisateur clique "Checkout"
│ │ │
│ │ 1. génère PunchOutOrderMessage │
│ │ avec BuyerCookie + ItemIn* │
│ │◄─────────────────────────────────┤
│ │ │
│ 2. HTTP POST navigateur ► BrowserFormPost URL (cXML body) │
│◄═════════════════════════╪ │
│ │ │
│ 3. ERP réassocie via BuyerCookie, charge le panier │
│ 4. workflow validation interne, puis... │
│ │ │
│ 5. OrderRequest (serveur-à-serveur) │
├──────────────────────────────────────────────────────────► │ Documentation
- Fulfill.dtd — version courante
— chercher
ELEMENT PunchOutOrderMessageetELEMENT PunchOutOrderMessageHeader. - cXML Reference Guide (PDF) — chapitre Punchout, mécanique du retour panier via navigateur.
- PunchOutSetupRequest
— l'amorce qui définit le
BuyerCookieet laBrowserFormPostURL.