---
canonical: https://validationfacture.fr/blog/br-co-15-arrondis-totaux
title: "BR-CO-15 : anatomie de la règle qui rejette le plus de factures"
description: "Le total TTC doit être exactement la somme du HT et de la TVA — au centime. Pourquoi cette règle évidente casse autant de factures : arrondis par ligne contre arrondis par taux, conversions de devises, et les patterns de code qui l'éliminent définitivement."
date: "2026-08-23"
slug: "br-co-15-arrondis-totaux"
---

La règle [BR-CO-15](/codes/br-co-15) tient en une ligne : le montant total
TTC (BT-112) est égal au total HT (BT-109) plus le total de TVA (BT-110).
Une évidence comptable. Et pourtant, c'est l'une des causes de rejet les
plus fréquentes des flux structurés — parce que l'évidence cache un piège
d'implémentation : **l'ordre des arrondis**.

## Le mécanisme de l'échec

Prenez trois lignes à 10,004 € HT, TVA 20 %. Deux stratégies de calcul :

- **Arrondir par ligne** : 3 × 10,00 = 30,00 HT ; TVA 3 × 2,00 = 6,00 ;
  TTC 36,00.
- **Arrondir en fin de calcul** : 30,012 → 30,01 HT ; TVA 6,0024 → 6,00 ;
  TTC 36,01.

Les deux sont défendables. Mais si votre module de lignes utilise la
première et votre module de totaux la seconde, votre facture affirme
`30,01 + 6,00 = 36,00` — et BR-CO-15 la rejette, à raison : le document se
contredit lui-même.

La norme tranche : la TVA se calcule **par catégorie et par taux** sur la
base taxable agrégée (c'est l'objet de la décomposition BG-23, contrôlée
par les règles BR-S-08 et sœurs), et les totaux du document doivent boucler
avec ces agrégats, au centime.

## Les trois variantes du même bug

1. **Lignes vs en-tête** : le cas ci-dessus — deux stratégies d'arrondi
   dans deux modules.
2. **Remises et charges de document** : une remise globale (BG-20) oubliée
   dans BT-109 mais répercutée dans BT-112, ou l'inverse.
3. **Flottants** : le calcul en `float` binaire (0,1 + 0,2 ≠ 0,3) au lieu
   d'arithmétique décimale. En Python, `Decimal` ; en Java, `BigDecimal` ;
   en JavaScript, une bibliothèque décimale — jamais le type natif.

## S'en débarrasser définitivement

- Une **seule fonction de totalisation** dans votre code, utilisée par les
  lignes, la décomposition de TVA et les totaux — pas trois
  implémentations qui divergent un jour de refactoring.
- De l'**arithmétique décimale** de bout en bout, l'arrondi (demi-pair ou
  demi-supérieur, mais choisi et documenté) appliqué à des points définis.
- Un **contrôle systématique avant émission** : nos règles rejouent
  exactement les équations de la norme — celles du
  [Schematron officiel du CEN](/blog/valider-facture-electronique-artefacts-officiels),
  que notre moteur exécute tel quel — et rendent l'écart au centime près :
  champ, valeur constatée, valeur attendue.

Le [scanner d'essai](/essai) vous dira en quelques secondes si vos
documents bouclent. Et si vous héritez d'un rejet BR-CO-15 d'une
plateforme, la [fiche du code](/codes/br-co-15) donne la lecture pas à
pas — c'est précisément le genre de code laconique que
[la réforme va multiplier](/blog/rejets-ppf-pdp-1er-septembre-2026) chez
ceux qui découvrent la validation structurée en production.
