Business Rules
Two views on the French CTC rules of the AFNOR XP Z12-012 V1.4 matrix.
- Points of attention — twelve topics written from chapter 4.4 of XP Z12-012 (June 2026) and checked against the standard: line and total calculation, rounding, gross/discount/net price, allowances and charges, VAT categories and exemption codes, non-VAT taxes and WEEE, credit notes vs negative invoices, notes and mandatory mentions, profile and invoicing framework, data types, sub-lines, and multi-seller invoices. Each topic states what the standard requires and how NomaUBL implements it, with the chapter cited.
- Rule catalogue — the 148 French CTC rules of the matrix (BR-FR controls, consistency, flux 1 / 10.1 mapping, numeric formats, multi-seller, PPF rules) with their full text, a family filter, search, and the UBL terms each rule constrains.
Each UBL term on the UBL Reference page links back to the rules that apply to it.
Points of attention written from AFNOR XP Z12-012 (June 2026), checked on 2026-09-25.
§4.4.5Line and total calculation rule
What the standard requires
- Invoice line net amount (BT-131) = (net price BT-146 ÷ price base quantity BT-149 × invoiced quantity BT-129) rounded to 2 decimals, minus the sum of line allowances (BT-136), plus the sum of line charges (BT-141). The product is rounded before allowances and charges are applied, which are already 2-decimal amounts.
- The unit of the price base quantity (BT-150) must be the unit of the invoiced quantity (BT-130), otherwise the result is off by the unit factor (gram vs kilogram = 1,000).
- This line formula is not checked by the EN 16931 schematron today; the revision of the standard will add it with a tolerance. Document totals are checked (BR-CO-10 to BR-CO-16): BT-106 = Σ BT-131; BT-109 = BT-106 − BT-107 + BT-108; BT-110 = Σ BT-117; BT-112 = BT-109 + BT-110; BT-115 = BT-112 − BT-113 + BT-114.
- Per VAT category and rate: base = Σ BT-131 of the lines in the category + document charges − document allowances of the same category; amount = base × rate ÷ 100, rounded to 2 decimals.
- The EXTENDED-CTC-FR profile tolerates 0.01 € per line and per document allowance/charge in these sums (VAT-inclusive B2C prices, VAT computed per line). Only DETAIL lines, or lines without a sub-type, enter the calculations.
In NomaUBL
- JDE amounts are passed through: the XSL recomputes neither BT-131 nor the totals, it normalises what the spool carries. Consistency therefore depends on the mapping (TAG_LINE_AMOUNT against TAG_LINE_PRICE, TAG_LINE_QUANTITY and TAG_LINE_PRICE_BASE_QTY).
- The invoice modal recomputes every line and every total with exactly this formula, including the division by the base quantity.
- NomaUBL schematron rule BR-NOMAUBL-02 raises a warning (not an error) when BT-131 deviates from the formula by more than 0.011: the AFNOR calculation is checked before sending even though EN 16931 does not check it.
Terms:BT-131BT-146BT-149BT-129BT-136BT-141BT-106BT-109BT-110BT-112BT-115
§4.4.6Rounding rule
What the standard requires
- Round to nearest, and on a tie (…5) away from zero: 13.455 gives 13.46 and −13.455 gives −13.46, so that two opposite amounts stay opposite once rounded. Applies at every multiplication or division.
In NomaUBL
- XSL: no arithmetic on amounts, except BT-115 when a prepaid or rounding amount is set (subtraction of 2-decimal values, no tie possible). Rounding is therefore JDE's responsibility.
- Invoice modal: every multiplication or division goes through a "half away from zero" rounding (roundHalfAwayFromZero in buildUblXml.ts), guarded against the binary representation of decimals (13.455 × 100 = 1345.4999…). Price × quantity is rounded to 2 decimals before line allowances, VAT = base × rate ÷ 100 rounded to 2 decimals, unit prices to 6 decimals. Fixed on 2026-09-25; before that Math.round rounded ties toward +∞ (−13.455 gave −13.45).
§4.4.9Gross price, discount and net price (BG-29)
What the standard requires
- Three levels of allowance/charge: document (own VAT, summed into BT-107/BT-108), line (same VAT as the line, folded into BT-131) and unit price, only a discount (BT-147) that turns the gross price (BT-148) into the net price (BT-146).
- The net price (BT-146) is mandatory and is what multiplies the quantity. The gross price is optional in EN 16931 but becomes mandatory in France as soon as it differs from the net price. It contains any included charges or taxes (eco-tax for instance).
- Related checks: net = gross − discount within 1 cent (G1.55); a missing gross is copied from the net in flux 1 and 10.1 (BR-FR-MAP-21/22); several discounts are summed and BT-147 becomes mandatory in those flows from September 2027 (BR-FR-MAP-30); 6 decimals maximum, never negative outside framework 9 (BR-FR-DEC-03).
- Never declare the same discount twice: either as a price discount (BT-147) or as a line allowance (BG-27), never both. A price declared net with the discount repeated in BG-27 makes BT-131 wrong by the discount amount.
In NomaUBL
- Mapping variables: TAG_LINE_PRICE (BT-146), TAG_LINE_GROSS_PRICE (BT-148), TAG_DISCOUNT_AMOUNT (BT-147), TAG_LINE_PRICE_BASE_QTY (BT-149). Spool with gross + discount: map both, the net is derived (gross − discount). Spool with net + discount: the gross is emitted as net + discount.
- Invoice modal: the "Price (BG-29)" block edits gross and discount, the net is computed; the line amount uses the net and the header price is locked while BG-29 is active.
Terms:BT-146BT-147BT-148BT-149BT-150BT-136
§4.4.9Allowances and charges
What the standard requires
- In UBL, allowances and charges share the cac:AllowanceCharge element, told apart by cbc:ChargeIndicator: false for an allowance, true for a charge. Amounts are positive, except to reverse them in a negative invoice.
- A line allowance or charge must carry the same VAT rate as the line; otherwise it becomes a line of its own (positive for a charge, negative quantity for an allowance).
- Document allowances and charges carry their own VAT category and rate (BT-95/BT-96, BT-102/BT-103) and feed the VAT breakdown like additional lines.
In NomaUBL
- The invoice modal handles document and line allowances and charges with their VAT category; BT-131 includes the line ones.
- Two mappings exist for a line discount: TAG_DISCOUNT_AMOUNT as a price discount (BG-29) or the TAG_LINE_AC_* group as a line allowance/charge (BG-27/BG-28). A given discount must go through only one of them.
Terms:BT-92BT-95BT-96BT-99BT-102BT-103BT-136BT-141
§4.4.7VAT categories and exemption reasons
What the standard requires
- S standard rate; E exempt, with a mandatory reason as text and code (BT-120/BT-121); AE reverse charge, code VATEX-EU-AE (VATEX-FR-AE domestic); K intra-EU supply of goods, VATEX-EU-IC; G export outside the EU, VATEX-EU-G, including services outside the EU; O out of scope, VATEX-EU-O. Z (zero rate) is not used in France, except as the transcoding of the franchise en base.
- Services sold within the EU: category AE (reverse charge by the customer), not K, despite K's wording; EU-level confirmation pending.
- Rule BR-O-11 (an O invoice contains only O) is lifted in the EXTENDED-CTC-FR profile: O lines may coexist with other categories.
- Breakdown (BG-23): one entry per category and rate present in the lines, base = sum of the lines, rate 0 if exempt and absent for O, zero amount when no VAT, and a reason in every case but S. Franchise en base: E + VATEX-FR-FRANCHISE, transcoded to Z in flux 1 and 10.1 (BR-FR-MAP-08/09). Allowed rates: list in BR-FR-16.
In NomaUBL
- Line category, rate and reasons: TAG_LINE_VAT_CATEGORY, TAG_LINE_VAT_RATE, TAG_LINE_VAT_EXEMPTION_CODE and TAG_LINE_VAT_EXEMPTION_REASON. The BG-23 breakdown and its reasons must stay consistent with the lines; the EN 16931 and CTC-FR schematrons check it at validation.
Terms:BT-118BT-119BT-120BT-121BT-151BT-152EXT-FR-FE-178EXT-FR-FE-179
§4.4.8Taxes other than VAT, WEEE eco-contribution
What the standard requires
- Tax subject to the same VAT as the product: line charge (BG-28) with reason BT-144 or code BT-145. Tax not subject or at a different rate: separate service line; for para-fiscal taxes GS1 publishes dedicated GTINs (BT-157 with scheme 0160).
- Tax on the whole invoice: document charge (BG-21) with reason BT-104/BT-105 and its VAT in BT-102/BT-103.
- The WEEE eco-contribution is usually included in the unit price and merely stated ("including xx.xx € eco-contribution") in a line note (BT-127) or a document note with subject code BLU. It plays no role in the buyer's accounting integration.
- The EN 16931 revision adds non-VAT tax codes (BT-193 at line, BT-177 at document, UNTDID 5153 list) as an alternative to the reason codes BT-145/BT-105; already part of the EXTENDED-CTC-FR profile.
In NomaUBL
- No non-VAT tax is emitted by default. A WEEE mention goes through a line note prefixed ##BLU##; the BT-193/BT-177 codes are not mapped.
Terms:BT-141BT-144BT-145BT-193BT-177BT-127BT-157
§4.4.4Credit notes and negative invoices
What the standard requires
- Two representations: the typed credit note (381, 261, 396, 502, 503) whose totals all keep the sign of the cancelled invoice, and the negative invoice (invoice type, positive unit prices, negative quantities, reversed allowances and charges) that results from a billing calculation with take-backs.
- Forbidden: the negative credit note (to cancel a credit note, issue an invoice referencing it) and the credit note with a negative total from mixed-sign lines (prefer a corrective invoice). French practice: the typed credit note, a clone of the invoice with a new number, date, reference to the cancelled invoice and possibly due date.
- A credit note must reference the preceding invoice: in the header (BT-25 with its date BT-26) or on every DETAIL line (EXT-FR-FE-136 and EXT-FR-FE-138), never both at once or flux 1 is rejected (G1.31). A corrective invoice (384, 471, 472, 473) carries exactly one header reference.
In NomaUBL
- Credit notes are emitted as UBL CreditNote (CreditNoteLine, CreditedQuantity) with BT-3 = 381; the header reference comes from TAG_LINE_BILLING_REF / TAG_LINE_BILLING_REF_DATE or the document references.
- The invoice modal edits BG-3 in the header and EXT-FR-FE-136 at line level (with DocumentStatusCode), strictly one level at a time.
Terms:BT-3BT-25BT-26EXT-FR-FE-136EXT-FR-FE-138
§4.4.3Notes and mandatory mentions
What the standard requires
- Mandatory mentions with no dedicated field are carried by a note (BT-22) qualified by a subject code (BT-21); in UBL the code is written between ## at the start of the text. Same mechanism for line notes (BT-127, code EXT-FR-FE-183).
- Every invoice carries at least PMT (40 € flat recovery indemnity), PMD (late-payment penalties) and AAB (discount terms or their absence), rule BR-FR-05; PMD, PMT, AAB and TXD at most once each, rule BR-FR-06.
- Other common subjects: AAI general information, ABL legal mentions (RCS…), ACC factoring subrogation, ADN B2G invoice, BAR expected processing (B2B, B2BINT, B2C, OUTOFSCOPE, ARCHIVEONLY, rule BR-FR-20), BLU eco-contribution, CUS customs, DCL billing mandate, SUR supplier remarks, TXD member of a VAT group (text MEMBRE_ASSUJETTI_UNIQUE).
In NomaUBL
- Each mapped note is emitted with its ##CODE## prefix. Make sure PMT, PMD and AAB are always present, for instance through the company defaults.
Terms:BT-21BT-22BT-127EXT-FR-FE-183
§4.4.2Profile (BT-24) and invoicing framework (BT-23)
What the standard requires
- BT-24 identifies the profile: urn:cen.eu:en16931:2017 for EN 16931, urn:cen.eu:en16931:2017#conformant#urn.cpro.gouv.fr:1p0:extended-ctc-fr for EXTENDED-CTC-FR; Factur-X has its own URNs (basicwl, basic, extended).
- BT-23 encodes the invoicing framework: first letter B goods, S services, M mixed; digit 1 standard, 2 already paid, 3 B2G subcontracting, 4 final after deposit, 5/6 subcontractor / co-contractor, 7 already e-reported, 8 multi-seller, 9 bidirectional (list in BR-FR-08). Constraints: framework 4 excludes deposit types (BR-FR-CO-08); framework 2 requires BT-113 = BT-112, BT-115 = 0 and the payment date in BT-9 (BR-FR-CO-09).
- The scope (e-invoicing, international B2B or B2C e-reporting, out of scope) cannot be inferred from the invoice; it may be carried by a BAR note (BR-FR-20) or by the transmission channel to the PA.
In NomaUBL
- BT-24 is fixed to the EXTENDED-CTC-FR profile; BT-23 is mapped per document template (B1, S1 or M1 in everyday use).
Terms:BT-23BT-24
§4.4.1Data types and decimals
What the standard requires
- Amounts: 2 decimals maximum, decimal point, no thousands separator, currency always present in UBL (currencyID). Unit prices: no limit in EN 16931 today, 6 decimals maximum in France (BR-FR-DEC-03), 4 in the coming revision. Quantities: 4 decimals (BR-FR-DEC-02). Percentages: 2 decimals, value 20 for 20 % (BR-FR-DEC-04). 19 significant digits overall.
- Dates YYYY-MM-DD in UBL; identifiers with schemeID when several schemes exist (VAT for a VAT number in UBL); codes with their list; binary object with mimeCode and filename.
In NomaUBL
- The XSL cleans spool values (spaces, €, decimal comma): amounts normalised to 2 decimals, unit prices up to 6. The modal applies the same precisions.
§4.4.11Sub-lines (DETAIL, GROUP, INFORMATION)
What the standard requires
- The EXTENDED-CTC-FR profile nests lines with the parent line identifier (EXT-FR-FE-162) and the line sub-type (EXT-FR-FE-163). Only DETAIL lines, or lines without a sub-type, enter the totals, the VAT breakdown and flux 1 / 10.1 (BR-FR-MAP-24).
- INFORMATION makes net price, quantity, unit, VAT and line amount optional; GROUP is a grouping line whose amount, when present, must equal the sum of the directly attached DETAIL or GROUP sub-lines. Several levels are possible; the line number need not mirror the hierarchy.
- In UBL both fields go through cac:BillingReference (BillingReferenceLine/ID and InvoiceDocumentReference/DocumentStatusCode) with InvoiceDocumentReference/ID equal to the invoice's own number; the implementation may still evolve.
In NomaUBL
- NomaUBL does not generate sub-lines. The modal exposes DocumentStatusCode on line-level preceding-invoice references, which is the same UBL element: use INFORMATION or GROUP only knowingly.
Terms:EXT-FR-FE-162EXT-FR-FE-163
§4.4.12 / §4.4.13Multi-seller invoices and bidirectional self-billing
What the standard requires
- Frameworks B8/S8/M8 (multi-seller) and B9/S9/M9 (bidirectional self-billing). Each unit invoice is a parentless GROUP line carrying the line seller (EXT-FR-FE-BG-12), its number (BT-128 with scheme AFL), its framework (BT-128 with scheme AVV), its VAT point and its VAT and gross amounts; every DETAIL line carries the AFL number, the seller's legal identifier and an exemption reason starting with #number#. Same date and same type for all unit invoices.
- The issuing PA rebuilds one unit invoice per seller and produces one flux 1 or 10.1 per unit invoice; document allowances and charges stay with the main seller and are discouraged. Bidirectional self-billing is to be avoided unless the practice is already tolerated by the tax administration.
In NomaUBL
- Not supported: a JDE invoice has a single seller.