Aller au contenu
Gatebold

Publié le

Erreurs cXML les plus fréquentes : comprendre, debugger, résoudre

Les erreurs cXML sont silencieuses, mal documentées, et les buyers donnent rarement de détails. Ce guide couvre les codes Status les plus rencontrés en intégration Magento 2 / Adobe Commerce et comment les debugger rapidement.

Si vous avez déjà cherché comment debugger un message cXML, vous connaissez la sensation : tout semble fonctionner côté 200 OK, mais le panier ne revient pas, l’acheteur dit que ça ne marche pas, et vos logs ne disent rien.

Les erreurs cXML sont silencieuses par construction. Le standard mélange codes HTTP et codes Status cXML, les buyers (SAP Ariba, Coupa, Oracle Procurement, etc.) renvoient rarement des messages exploitables, et chacun a ses interprétations propres. Ce guide passe en revue les erreurs que vous rencontrerez réellement en production sur Magento 2 et Adobe Commerce, avec leurs causes, des exemples, et la méthode de résolution.

Comprendre les codes Status cXML : la base du debug

Première chose à intégrer : un 200 OK HTTP ne veut PAS dire que le message a été accepté. Le cXML utilise sa propre couche de statut via l’élément <Status> :

<cXML payloadID="..." timestamp="...">
  <Response>
    <Status code="200" text="OK">Success</Status>
  </Response>
</cXML>

La structure typique :

  • Le transport HTTP renvoie son code (200, 401, 500…)
  • Le message cXML lui-même porte son propre <Status code="..." text="...">

Concrètement, un buyer peut très bien recevoir un HTTP 200 et trouver à l’intérieur un <Status code="400"> qui rejette le message. C’est la première source de confusion en debug : regardez TOUJOURS le <Status> cXML avant de conclure que tout va bien.

Erreurs d’authentification (4xx)

401 - Unauthorized

Cause la plus fréquente : le SharedSecret envoyé ne correspond pas à celui configuré côté buyer.

<!-- Reçu par le buyer -->
<Sender>
  <Credential domain="NetworkId">
    <Identity>supplier_id</Identity>
    <SharedSecret>WrongSecret123</SharedSecret>
  </Credential>
  <UserAgent>Gatebold/1.0</UserAgent>
</Sender>

<!-- Réponse buyer -->
<Status code="401" text="Unauthorized">SharedSecret mismatch</Status>

Vérifier en priorité :

  1. Le secret a-t-il été rotaté côté buyer sans vous prévenir ? (Ariba le fait régulièrement)
  2. Êtes-vous sur l’environnement sandbox ou production ? Les secrets diffèrent.
  3. Le secret contient-il des caractères spéciaux mal échappés en XML ?
  4. Un BOM UTF-8 traîne-t-il en début de fichier ? (Casse les comparaisons strictes) (BOM : 3 octets invisibles 0xEF 0xBB 0xBF ajoutés en tête de fichier UTF-8 par certains éditeurs Windows comme Notepad)

403 - Forbidden

Le secret est correct, mais l’identité (<From> ou <To>) ne match pas avec ce qui est attribué chez le buyer.

<From>
  <Credential domain="NetworkId">
    <Identity>AN01234567890</Identity>
  </Credential>
</From>

Sur Ariba, cet Identity correspond à l’ANID (Ariba Network ID). Une erreur de copie d’un caractère = 403.

417 - Expectation Failed

Le header HTTP est incomplet (typiquement Content-Type ou Content-Length manquant). Magento 2 module mal configuré qui envoie du application/json au lieu de text/xml.

Erreurs de schéma DTD (400 + 450)

400 - Bad Request (schéma invalide)

Le message ne respecte pas la grammaire du DTD cXML officiel. Les cas les plus courants :

  • Élément requis manquant (<BuyerCookie> absent dans PunchOutSetupRequest)
  • Ordre des enfants incorrect (<To> avant <From> dans <Header>)
  • Valeur d’attribut hors enum (operation="update" au lieu de create/inspect/edit)
  • Attribut requis manquant (payloadID ou timestamp sur <cXML>)

450 - Bad/Missing data

Spécifique au cXML : le message est syntaxiquement valide mais une donnée métier manque.

<!-- ItemIn sans UnitPrice -->
<ItemIn quantity="2">
  <ItemID>
    <SupplierPartID>SKU-001</SupplierPartID>
  </ItemID>
  <ItemDetail>
    <Description xml:lang="fr">Cartouche d'encre</Description>
    <!-- ❌ UnitPrice manquant -->
  </ItemDetail>
</ItemIn>

Buyer renvoie : <Status code="450" text="Bad/Missing data">UnitPrice required for ItemIn</Status>

Erreurs de cart return (475)

Le 475 est un code propriétaire largement utilisé pour “processing error” (erreur métier non standardisée).

<Status code="475" text="Processing error">
  Item SKU-001 not found in buyer catalog
</Status>

Causes typiques :

  • Produit envoyé non référencé dans le catalogue interne du buyer (Ariba interne, Coupa CSP)
  • Prix renvoyé différent du prix contractuel négocié
  • Devise inattendue (EUR envoyé alors que le contrat est en USD)
  • Code UNSPSC manquant ou invalide (cf. mapping UNSPSC)

Erreurs côté système buyer

500 - Internal Server Error (chez le buyer)

Pas votre problème, mais vous allez quand même devoir le débugger. Souvent un crash côté e-proc avec des messages cryptiques. Récupérez le payloadID que vous avez envoyé et transmettez-le au support du buyer.

Session timeout (pas de code, mais panier perdu)

Le prescripteur traîne trop longtemps sur votre boutique, sa session côté buyer expire. Aucune erreur n’est levée, mais le PunchOutOrderMessage que vous envoyez se perd dans le vide.

Lost SetupRequest (firewall / DNS)

Le buyer dit qu’il a envoyé le PunchOutSetupRequest, vous ne voyez rien dans vos logs. 9 fois sur 10 : votre firewall bloque l’IP du buyer, ou votre DNS pointe vers la mauvaise IP.

Fix : tail -f les access logs Apache pendant que le buyer relance. Si rien n’arrive, le problème est en amont du serveur.

Logs à activer pour debugger cXML sur Magento 2

C’est probablement la section la plus utile de cet article. Sans logs corrects, vous débuggez à l’aveugle.

Ce qu’il faut logger systématiquement :

  1. Payload XML entrant complet (PunchOutSetupRequest) avec le SharedSecret redacté (****).
  2. Payload XML sortant (PunchOutSetupResponse et PunchOutOrderMessage).
  3. Timestamp précis (millisecondes) pour reconstruire une chronologie.
  4. Correlation ID : un UUID que vous générez à la réception du SetupRequest, propagé partout, présent dans chaque log.
  5. Status HTTP + Status cXML côté réponse buyer (les deux !).

Où les stocker dans Magento 2 :

  • var/log/punchout.log pour les payloads (fichier dédié, pas dans system.log)
  • Rotation quotidienne, rétention 30 jours (RGPD)
  • Jamais le contenu du SharedSecret en clair, jamais les détails personnels du prescripteur

Méthode de debug structurée

Quand un buyer vous remonte un problème :

  1. Demander le payloadID du message en erreur (toujours présent côté buyer)
  2. Retrouver le payload dans vos logs via ce payloadID
  3. Valider la syntaxe avec le validateur cXML
  4. Vérifier le Status dans la réponse (HTTP + cXML)
  5. Croiser avec les specs du buyer (ANID valide ? Catalogue à jour ? Prix contractuels ?)
  6. Si bloqué : envoyer le payload XML au support du buyer avec votre payloadID et leur correlationID

Comment Gatebold simplifie ce debug

Sur une intégration custom Magento 2, chaque erreur vous demande de fouiller plusieurs systèmes. La plateforme Gatebold centralise :

  • Logs structurés par session PunchOut (correlation ID auto, payloads horodatés)
  • Validation DTD systématique des messages avant envoi (rejet préventif)
  • Dashboard d’erreurs : Status code, fréquence, buyer concerné
  • Rejeu d’un message en mode debug sans toucher à la prod
  • Rotation des SharedSecret sans redéploiement Magento 2

Pour les équipes qui gèrent plusieurs buyers (Ariba, Coupa, Oracle, etc., simultanément), ce niveau d’observabilité fait la différence entre 2h de debug et 2 jours.

En résumé

Les erreurs cXML les plus fréquentes que vous rencontrerez :

CodeTypeCause typiquePremier réflexe
401AuthSharedSecret KOVérifier le secret + l’environnement
403AuthANID/Identity KOComparer avec config buyer
400SchémaDTD invalideValider via notre validateur
450MétierDonnée requise absenteVérifier le payload sortant
475BuyerCatalogue/prix/deviseTracer le PunchOutOrderMessage
500ServeurCrash buyerRécupérer payloadID + escalader support

La règle générale : logguez tout, redactez les secrets, gardez 30 jours. Sans ça, chaque erreur de production prend 5x plus de temps à résoudre.

Pour la liste complète des codes Status cXML avec causes, debug et fix, consultez notre référence des codes d’erreur cXML - sourcée du cXML Reference Guide 1.2.070 avec en bonus 15 pièges fréquents hors codes (encoding, payloadID, SharedSecret, etc.).

Pour les articles techniques sur les implémentations spécifiques par buyer, voir nos guides SAP Ariba, Coupa, Oracle Procurement, etc. Si vous voulez en discuter pour votre projet Magento 2, contactez-nous.

Questions fréquentes

Comment debugger une erreur cXML 401 Unauthorized ?
Vérifier en priorité le SharedSecret côté buyer (souvent rotaté en silence), comparer environnements sandbox/production (les secrets diffèrent), et confirmer qu'aucun BOM UTF-8 n'a été ajouté en tête de fichier. Activer des logs Magento 2 dédiés (avec SharedSecret redacté) permet de comparer rapidement la configuration côté supplier avec celle côté buyer.
Comment voir les payloads cXML envoyés à un buyer ?
Activer un log dédié sur Magento 2 (var/log/punchout.log) qui capture le PunchOutSetupRequest, le PunchOutSetupResponse et le PunchOutOrderMessage avec un correlation ID (UUID) propagé sur toute la session PunchOut. Sans ces logs, debug à l'aveugle. Toujours redacter le SharedSecret.
Que signifie un Status code cXML 450 ?
Le 450 est un code cXML spécifique qui veut dire Bad/Missing data : le message est syntaxiquement valide mais une donnée métier obligatoire manque (UnitPrice, currency, unit of measure, etc.). À ne pas confondre avec le 400 qui signale une violation du schéma DTD.
Pourquoi un PunchOutOrderMessage se perd-il chez le buyer ?
Trois causes typiques : session buyer expirée pendant que le prescripteur traînait sur le storefront Magento 2, article non référencé dans le catalogue interne du buyer (provoque souvent un Status 475), ou divergence de prix/devise avec le contrat négocié. Le payloadID dans les logs permet de retrouver la session côté buyer.
Comment debugger un cart return cXML qui ne revient pas ?
Vérifier dans l'ordre : (1) le payloadID est-il visible dans les logs Magento 2 ? (2) le Status code dans la réponse buyer (HTTP et cXML, les deux peuvent différer), (3) la session buyer est-elle encore active, (4) le firewall/DNS côté supplier laisse-t-il bien passer la requête entrante. Sans payloadID, escalader au support du buyer est inutile.
Quels logs activer pour debugger cXML sur Magento 2 ?
Au minimum : payload XML entrant complet (SharedSecret redacté), payload XML sortant, timestamp précis (ms), correlation ID UUID propagé sur toute la session, Status HTTP et Status cXML de la réponse buyer. Rotation quotidienne des logs, rétention 30 jours pour rester conforme RGPD (les payloads contiennent des données personnelles du prescripteur).