En bref
- BR-33 exige qu’une
DocumentLevelAllowance(BG-20) ait soitReason(BT-97) soitReasonCode(BT-98). - BR-31 est une règle DIFFÉRENTE : elle concerne la présence du montant de la remise (
BT-92). - Si vous fournissez un code de motif, vérifiez son appartenance au sous-ensemble UNCL 5189 du profil exécuté.
- Un motif textuel réel suffit à BR-33 ; cette règle n’impose pas de renseigner simultanément le texte et le code.
/repairn’invente pas le motif commercial d’une remise : récupérez-le dans les données source ou faites-le préciser.
Ce que l’erreur veut dire
BR-33 demande un motif textuel (BT-97) ou un motif codé (BT-98) pour chaque remise de niveau document (BG-20). Le nom du groupe métier ne désigne pas une balise CII : en CII, la remise est un SpecifiedTradeAllowanceCharge sous ApplicableHeaderTradeSettlement, avec ChargeIndicator/udt:Indicator à false. Le motif est porté par Reason ou ReasonCode dans ce même bloc.
Le binding CII EN16931 1.3.16 contrôle la présence de l’un de ces éléments. Cela ne vérifie pas la réalité commerciale du motif : une balise vide ou un motif inventé ne constitue pas une correction métier. BR-31 contrôle séparément la présence du montant de la remise (BT-92).
Quand cette erreur arrive
Survient quand : (a) une remise est appliquée par l’ERP sans champ libre associé ; (b) la remise est purement commerciale et n’a pas de motif explicite saisi ; (c) remise calculée par règle métier (volume, fidélité) sans expliciter le moteur de calcul ; (d) export XML qui oublie le bloc Reason/ReasonCode même quand la valeur est saisie côté ERP.
Exemple XML qui déclenche l’erreur
Fragments sous ApplicableHeaderTradeSettlement, limités au contrôle de présence du motif. Ils ne constituent pas une facture complète validée.
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:ActualAmount>50.00</ram:ActualAmount>
<!-- ❌ ni Reason ni ReasonCode -->
</ram:SpecifiedTradeAllowanceCharge>
Exemple XML corrigé
Dans cet exemple, la remise de fidélité est confirmée par les données commerciales. Le texte seul satisfait la condition de présence de BR-33 :
<ram:SpecifiedTradeAllowanceCharge>
<ram:ChargeIndicator><udt:Indicator>false</udt:Indicator></ram:ChargeIndicator>
<ram:ActualAmount>50.00</ram:ActualAmount>
<ram:Reason>Remise commerciale fidélité</ram:Reason>
</ram:SpecifiedTradeAllowanceCharge>
Correction manuelle
- Vérifiez si le motif existe dans l’ERP mais a été perdu à l’export. Dans ce cas, rétablissez son mapping vers
ReasonouReasonCode. - Si le motif manque réellement, faites préciser la raison commerciale de la remise. Ne déduisez pas « fidélité », « volume » ou un autre motif du seul montant.
- Si vous utilisez un code, consultez le sous-ensemble UNCL 5189 publié par OpenPeppol et le profil cible. Par exemple,
95signifie Discount (remise) ; il ne prouve pas à lui seul une remise de fidélité. BR-CL-19 vérifie l’appartenance du code à la liste, séparément de BR-33. - Régénérez puis validez le XML. Le contrôle documentaire ne prouve pas la justification commerciale. Il ne garantit pas l’acceptation par une PA.
Réparable automatiquement par /repair ?
Pas par ajout d’un motif par défaut. Le contrat public de l’API exclut l’invention de données métier manquantes par /repair. Renseignez le motif réel dans le système source, corrigez son export puis contrôlez le nouveau XML avec /validate.
Et maintenant ?
Diagnostiquer ma facture →
Après correction de la source, contrôler le XML sans le modifier :
curl -X POST https://api.facturxapi.com/api/v1/validate \
-H "Authorization: Bearer VOTRE_CLE" \
-F "file=@./facture.xml"