GuideMay 6, 2026 · 12 min read · By Rachid El Kedmiri, Senior Odoo Architect

How to Customize Your Invoices in Odoo:
Templates, Fields & Design — 2026 Guide

INTRODUCTION

In 2026, the Invoice Is Both a Brand Asset and a Compliance Object

The 2026 fiscal year has redefined what an invoice is supposed to do. It is no longer a static demand for payment—it is a structured data object consumed by tax authorities, a branded touchpoint your customer sees the moment money is on the line, and a machine-processable record that has to survive audits, e-invoicing networks, and AI-driven reconciliation engines. Odoo 19, with the Odoo 20 reveal scheduled for the OXP events in September 2026, is the version where customization decisions stop being cosmetic and start carrying real financial weight.

The pricing climate makes that point unavoidable. As of April 2026, Enterprise subscriptions still running on versions older than v17 are subject to a 25% legacy version surcharge, layered on top of a 30% North American price increase and a 7% annual indexation. Customizing invoices well now means migrating onto a current, supported version, then building on top of native layouts, Studio extensions, and QWeb inheritance in a way that survives the next two upgrades.

This guide walks through every layer of invoice customization in 2026: the document layout engine, dynamic sections, custom fields, Studio report editing, QWeb & XPath engineering, Peppol e-invoicing, EPC QR codes, AI-assisted automation, and the troubleshooting playbook for the issues that actually break PDFs in production.

01

The 2026 Migration Landscape: Why Your Invoice Strategy Starts With a Version Decision

Odoo’s 2026 roadmap follows a three-wave migration strategy that puts finance and compliance first. The reason is simple: mandatory e-invoicing across Europe, parts of Latin America, the Gulf, and an expanding list of public-sector buyers in North America requires that financial documents be both human-readable and machine-processable. If you customize an invoice on a legacy version, you are customizing a document that no longer matches the structural data integrity your tax authority expects.

VersionStatus (April 2026)SurchargePrimary Customization Surface
Odoo 14–16Legacy+25%Classic XML-RPC, raw QWeb
Odoo 17Covered0%QWeb, Studio, modern UI
Odoo 18Covered0%AI-first features, Studio, QWeb
Odoo 19Latest stable0%AI agents, vibe coding, collapsible sidebar
Odoo 20Reveal Sept 2026n/aGlobal OXP roadmap, advanced AI

On the developer side, the architectural shift continues. Classic XML-RPC integration endpoints are now scheduled for removal in v22, giving teams a transitional window to migrate external systems pulling invoice data toward the more efficient JSON-2 protocol. Treat that window as part of your invoice strategy, not as a separate project: the way invoices are pulled, signed, and rendered downstream is what makes or breaks a migration.

Strategic Read

If you’re still on v15 or v16, the cheapest path to a customized invoice is not to retrofit your old template—it’s to migrate to v19 first, then layer the customization on top. The 25% surcharge alone often eclipses the cost of a clean Wave 1 finance migration.

02

Native Document Layout: The No-Code Foundation Every Invoice Inherits

Before touching XML or Python, every Odoo invoice should be configured at the Document Layout level. This is the no-code engine that defines the visual identity shared across quotations, sales orders, invoices, and credit notes. Get this right and most of your invoice customization work disappears.

Where to Find It

Navigate to Settings › General Settings › Companies › Document Layout and click Configure Document Layout. The modal exposes four layout frameworks, each tuned to a different industry rhythm:

LayoutVisual SignatureBest Fit
BoxedDefined cells, hard bordersManufacturing, construction, audit-heavy environments
BoldStrong typography, high-contrast headersModern services, agencies, creative firms
StripedAlternating row backgroundsWholesale, distribution, long line-item invoices
LightMinimalist, content-firstRetail, luxury, brand-led B2C
Odoo 19 Configure Document Layout modal showing the four layout frameworks (Boxed, Bold, Striped, Light) with logo, brand color picker, font selector, and live preview
The Document Layout modal in Odoo 19 — four frameworks, logo upload, brand colors, font selection, and a live invoice preview, all without writing code.

Step-by-Step: Native Layout Configuration

  1. Open the dashboard — log into the v19 environment and open the Accounting or Invoicing module.
  2. Settings › Configuration — scroll to the Companies block.
  3. Configure Document Layout — pick the framework that matches your brand position.
  4. Branding — upload a PNG or SVG logo, set primary & secondary colors via hex picker, choose alignment (left / center / right).
  5. Typography & background — pick a corporate font (v19 expanded the rich-text font registry; no custom CSS required for most cases) and select a background style (Blank, Demo logo, Custom upload).
  6. Tagline & footer — add the corporate motto, certifications (ISO numbers, B-Corp status, etc.), and the legal footer line.
  7. Continue — saves the global settings and applies them to every external document including invoices.
Why Tagline Matters

The tagline field is the single best place for ISO/SOC 2 references, regulated-industry credentials, or QHSE certifications. It surfaces on every customer document without polluting the main body and eliminates the recurring “can you add the certification number?” ticket from the finance team.

03

Dynamic Sections, Visibility Controls, and Where Invoice Data Should Actually Live

Odoo 19 promoted invoice section management from a developer-only chore to a functional user capability. You can now reorganize, duplicate, or hide entire sections of a customer-facing invoice from the form view itself—no module update, no XML edits, no QA cycle.

Section & Sub-Section Management

Inside the invoice form, drag-and-drop handles let you split lines into named sections (“Phase 1 Discovery”, “Phase 2 Implementation”) and sub-sections (“Onsite Days”, “Remote Hours”). This pattern is invaluable for project-based invoicing where customers expect to see how the total was constructed.

Granular Visibility on the Printed PDF

Within any section, three independent toggles control what the customer actually sees on the rendered PDF:

  • Hide prices — useful for free-of-charge bonus lines or for “summary” invoices where only totals are disclosed.
  • Hide taxes — for export invoices, intra-EU reverse-charge scenarios, or cosmetic clean-up.
  • Hide whole section — lets you keep internal notes, cost-center breakdowns, or analytical lines on the invoice record without ever exposing them to the recipient.

Move Repetitive Fields Off the Invoice and Onto the Contact

The Other Info tab is still the central repository for Customer Reference, Payment Reference, and Incoterms. The 2026 best practice, however, is to push that data back to the contact record. Setting fiscal positions, payment terms, preferred bank, and receivable accounts on the contact form (Accounting › Customers › Customers) means every new invoice prefills correctly, eliminating per-invoice rework.

Invoice Data PointBest OriginWhy It Matters
Invoice DateAuto-filled at confirmationDrives the official issue date and tax period
Recipient BankJournal  /  Other Info tabDetermines the IBAN encoded in the EPC QR code
Fiscal PositionContact recordMaps tax substitutions and account remapping at scale
Payment TermsContact  /  Sales OrderDefines installment plans & early-payment discount text
04

Odoo Studio: Adding Custom Fields and Editing Reports Without Writing a Module

Studio occupies the middle ground between native settings and full code. It’s the right tool when you need a field that doesn’t exist out of the box, a column on the printed PDF, or a conditional block—without the overhead of shipping a custom module.

Step-by-Step: Add a Custom Field via Studio

  1. Open an invoice and click the wrench icon (Toggle Studio) in the upper right.
  2. Pick the Form view; Studio displays a sidebar with field types.
  3. Drag & drop the field type you need (Monetary, Selection, Many2One, Related, etc.) onto the form.
  4. Configure properties:
    • Label — e.g. “Environmental Fee”
    • Technical name — Studio prefixes with x_studio_
    • Visibility — required, invisible, or domain-driven
    • For relational fields, set the target model (e.g. res.users for a secondary salesperson)
  5. Close Studio — you’re back in the standard interface with the field live.
Odoo Studio sidebar on an invoice form showing the field type palette and a custom x_studio field configured with label, technical name, and visibility properties
Odoo Studio’s sidebar on an invoice form — drag a field type onto the layout, then configure label, technical name, visibility, and relational targets without leaving the browser.

The Studio Report Editor

The PDF report editor in v19 deviates from the form editor. Instead of dragging fields, you compose templates with slash commands and conditional blocks:

FeatureHow It WorksUse Case
External / Internal / Blank reportStarting templates from the new-report wizardUse External for invoices—keeps company header/footer
Slash commandsType / to insert tables, fields, conditional blocksAdd a “Brand / Manufacturer Part Number” column
Conditional blocksDashed rectangles bound by a logical expressionShow shipping address only when it differs from billing
Visibility groupsRestrict report sections to a user groupReveal margin breakdown to Accounting / Manager only
Studio Knows Its Limits

Studio is the right choice up to the point where your changes need to interact with computed fields, multiple inherited reports, or shared CSS across documents. The moment you need to coordinate two modules’ xpaths or override a method on account.move, drop into a custom module—Studio’s generated XML is fine, but it isn’t what you want as the source of truth for upgrade-safe customizations.

05

QWeb & XPath: Engineering Invoice Customizations That Survive Upgrades

For anything beyond Studio’s ceiling, the right answer is QWeb inheritance from a custom module. The cardinal rule is the same it’s always been: inherit, don’t override. Direct edits to account.report_invoice_document are wiped on every upgrade. Inherited templates survive because the ORM applies them as a layer on top of the base.

Anatomy of a Custom Invoice Report

Every report has two pieces: an ir.actions.report record (the metadata) and a QWeb template (the structure). The minimum viable custom invoice report:

For a developer-only deep-dive on QWeb invoice templates—PO numbers, project codes, wire instructions, multi-company layouts, conditional content—see our companion guide Level Up Your Billing: A Step-by-Step Guide to Customizing Odoo Invoices.

XML — reports/invoice_report.xml
<odoo>
  <record id="action_report_custom_invoice"
          model="ir.actions.report">
    <field name="name">Premium Invoice Template</field>
    <field name="model">account.move</field>
    <field name="report_type">qweb-pdf</field>
    <field name="report_name">
      my_module.custom_invoice_template
    </field>
    <field name="binding_model_id"
           ref="account.model_account_move"/>
  </record>

  <template id="custom_invoice_template"
            inherit_id="account.report_invoice_document">
    <xpath expr="//div[@name='reference']"
           position="after">
      <div t-if="o.x_customer_po"
           class="col-auto col-3 mw-100 mb-2">
        <strong>Customer PO:</strong>
        <p class="m-0" t-field="o.x_customer_po"/>
      </div>
    </xpath>
  </template>
</odoo>

XPath Position Cheat Sheet

PositionEffectWhen to Use
replaceRemoves the target element entirelyOverhauling the address block for legal compliance
after / beforeSibling insertionAdding a Project Manager next to the Salesperson
insideChild insertionAppending a disclaimer inside the T&C div
attributesModifies class / style / data-*Adding Bootstrap 5 utilities, brand colors
Use Named Anchors

Avoid positional selectors like //table/tbody/tr[last()]. The moment another module (sale_stock, l10n_*, OCA pack) inherits the same template and adds rows, your “last row” becomes their row. Target named anchors instead: //div[@name='payment_term'], //div[@name='reference'], //div[@name='total']. They’re stable across upgrades and across the OCA ecosystem.

Rendering Binary Images on the PDF

The single most common technical hurdle in v19 invoice work: product photos render in the web preview but disappear from the PDF. The wkhtmltopdf renderer can’t fetch binary image fields the way the browser does. The fix is to embed them as base64 via the image widget:

QWeb — render product image on every line
<span t-esc="line.product_id.image_128"
      t-options="{
        'widget': 'image',
        'max_width': '64',
        'class': 'rounded'
      }"/>
06

Peppol, EPC QR Codes, and Total in Words: Customizing for Compliance

The 2026 Wave 1 focus on finance is driven by mandatory e-invoicing. Customizing an invoice without integrating Peppol, EPC QR codes, and locale-specific structures is incomplete work—it’ll fail the moment you ship cross-border or onboard a public-sector customer.

Peppol Activation in Odoo 19

  1. Open Accounting › Configuration › Settings › Electronic Invoicing and click Activate Peppol.
  2. Provide the Peppol endpoint identifier (VAT number or GLN).
  3. For each customer, set the e-invoice format on the contact’s Accounting tab (Factur-X, UBL, CII, etc.).
  4. When the invoice is sent, v19 attaches the structured XML alongside the PDF automatically.
Odoo 19 Peppol Registration panel showing an active registration with the endpoint identifier and a Send button for outgoing e-invoices
An active Peppol registration in Odoo 19. Once the endpoint is verified, every confirmed customer invoice carries the structured XML alongside the PDF.

EPC / SEPA QR Codes

Odoo Customer Payments settings panel listing the available QR payment formats including SEPA QR, Pix, FPS and VietQR
The QR payment methods exposed under Customer Payments. Activating the right format per region drives the QR rendered at the bottom of the printed invoice.
  1. In Accounting › Configuration › Settings, enable QR Codes under Customer Payments.
  2. Confirm the bank journal carries both IBAN and BIC.
  3. Populate the Recipient Bank field on the invoice Other Info tab.
  4. Odoo auto-renders the EPC QR code at the bottom of the printed document; SEPA-area customers can pay via banking-app scan.
SEPA QR Code toggle activated in Odoo settings with the helper text Add a payment QR code to your invoices
The SEPA QR Code toggle is the single switch that makes EPC payment data appear on every printed invoice.
EPC QR code rendered at the bottom of a printed Odoo customer invoice with the prompt Scan me with your bank app to pay
The end result on the PDF: a single scan with a SEPA-zone banking app pre-fills IBAN, beneficiary, amount, and reference.

Region-specific equivalents are supported through localization modules: Pix (Brazil), FPS (Hong Kong), VietQR (Vietnam), and the various GCC localizations.

Total Amount in Words

In several jurisdictions the literal spelled-out total is a legal requirement to prevent post-print tampering. Enable it under Accounting › Configuration › Settings › Customer Invoices › Display Total in Letters. For per-journal control (uppercase forcing, language overrides for bilingual invoices), several OCA-grade modules expose journal-level configuration without forking the core.

07

AI Inside Invoicing: OCR, Ask AI, and Vibe Coding

In Odoo 19, AI is the interaction layer of the ERP, not a sidecar. For invoice work, that translates into three concrete capabilities you should design your customizations around:

  • OCR + learning preferences — the engine that digitizes incoming vendor bills also feeds tailored templates per supplier. Manual corrections train a per-vendor profile that improves with use.
  • Ask AI agentCtrl + K or the top-bar button; conversational queries over invoicing data, summarization of dispute history, automatic translation of chatter messages, semantic search (“find the invoice for the sustainability audit last September”).
  • Vibe coding & image generation (v19.2) — describe a portal or document layout in natural language, generate product visuals directly inside the ERP. The same product imagery flows automatically into your custom invoice templates.

When designing custom invoice fields, prefer well-named, well-typed fields over free-text Char dumps. The Ask AI agent and the OCR template engine reason about your data through field labels and types—naming a field x_customer_po_number with help text yields dramatically better automation than x_studio_field_4d2a1.

08

Three Production Pitfalls That Break Invoice Customization

1

Missing report.url System Parameter

You upgraded a containerized v19 stack and PDFs come out blank, headerless, or stripped of stylesheets. The renderer can’t resolve internal asset URLs because the report.url system parameter isn’t set.

Fix

Set report.url in Settings › Technical › System Parameters to the internal address Odoo can reach itself on (e.g. http://localhost:8069 in single-container deployments, or the internal Docker service URL when the worker isn’t the same container as Nginx). PDFs render instantly afterwards.

2

Flexbox / CSS Grid in the QWeb Stylesheet

Your invoice looks perfect in Chrome’s print preview, then arrives at the customer with everything stacked, overlapping, or missing. wkhtmltopdf is a WebKit fork from 2020—it speaks CSS 2.1 and a partial CSS3, but not flexbox, not grid, not custom properties.

Fix

Use Bootstrap’s row/col-*, table layouts, and display: inline-block. Validate against the actual wkhtmltopdf 0.12.6/0.12.7 binary, not browser preview. PostCSS in v19 already tree-shakes unused styles—leverage it.

3

Hardcoded Currencies, Symbols, and Tax Labels

A US-localized template ships fine for domestic clients, then a Quebec or Saudi customer receives invoices with the wrong symbol, decimal separator, or tax description. Hardcoded formatting collapses the moment invoices cross a border.

Fix

Always use t-field with t-options='{"widget": "monetary"}' for amounts, {"widget": "date"} for dates, and read tax labels from tax_id.description/tax_id.name. Never hardcode currency symbols or tax names; the company / fiscal position pair already encodes the correct rendering.

BUSINESS ROI

What a Properly Customized Invoice Returns

Invoice customization isn’t a branding line item—it’s a working-capital lever and a compliance hedge:

5–8 daysLower DSO

Clear bank details, embedded EPC QR codes, and visible payment terms compress the customer-side AP cycle by several days on average.

60%Fewer AR queries

PO numbers, project codes, and wire instructions surfaced on the document itself eliminate the back-and-forth tickets your finance team currently absorbs.

100%Compliance coverage

Peppol-ready XML, Total-in-Words, region-specific QR codes, and proper localization make every invoice audit-defensible across the jurisdictions you ship to.

For an organization sending 500 invoices per month at a $10K average value, a 5-day DSO improvement frees roughly $833,000 in working capital—a CFO-level result delivered by a one-time template project plus a Peppol activation.

LEARNING TRACK

The Odoo Academy (e-)Invoicing Curriculum

The 2026 Academy track on e-invoicing is structured as a 2-hour 2-minute progression that walks teams from the database basics through Peppol, regional localizations (Vietnam Form 01/GTGT, GCC/Saudi, etc.), and accountant transmission. It pairs well with this guide as a hands-on companion — full course on Odoo Academy: (e-)Invoicing.

ModuleTopicDuration
1Introduction to invoicing2 min
2Database creation & configuration13 min
3Sales: from quotes to invoices15 min
4Purchases & Peppol9 min
5Recurring billing & contracts15 min
6Payments & reconciliation12 min
7Mobile app workflows6 min
8Reporting & analysis8 min
9Accountant transmission2 min

Open the Odoo Academy (e-)Invoicing course →

From Odoo 19 to Odoo 20: Customize Once, Compound Forever

The path to Odoo 20 in late 2026 is fundamentally a finance-and-compliance journey. Invoice customization is the most visible expression of that journey—every field, every section, every QWeb xpath either compounds value with the next upgrade, or becomes technical debt that the 25% legacy surcharge will eventually price in.

Customize at the right layer. Use the document layout for branding, sections and contact records for data hygiene, Studio for tactical fields, and a custom module with QWeb inheritance for anything that has to survive the next two upgrades. Wire in Peppol, EPC QR codes, and Total-in-Words at the start, not as a follow-up project. Align AI-fed fields with semantic naming so OCR and Ask AI can reason about them. Done in this order, your invoices stop being a recurring cost center and start acting like the operational asset they were always meant to be.

Book a free invoice audit