Skip to content

Customizing Invoice PDFs

FOSSBilling generates invoice PDFs with Dompdf, which renders HTML and CSS into a printable document.

Dompdf is not a complete PDF engine. FOSSBilling uses Dompdf 3.x, which supports many print-friendly CSS features but still has layout limitations:

SupportedNot Supported
CSS 2.1 and some CSS3Flexbox
@import, @media, @pageCSS Grid
CSS custom properties and math functions such as calc()Browser-style complex layouts
Basic positioning and table layoutsSplitting table rows or cells across pages
  1. Copy /modules/Invoice/templates/pdf/default-invoice.css
  2. Paste as /modules/Invoice/templates/pdf/custom-invoice.css

FOSSBilling automatically uses custom-invoice.css if it exists.

PDF layout with CSS classes

The default stylesheet uses these classes:

  • .CompanyLogo — Company logo image
  • .TopSectionDivider — Divider below the header area
  • .InvoiceInfo — Invoice number, dates, and status
  • .CompanyInfo — Seller/company heading and details
  • .ClientInfo — Client heading and details
  • .Breakdown — Line items, tax, discount, and total table
  • .InvoiceText — Custom invoice text blocks
  • .InvoiceFooter — Payment details, company footer, and signature
  • .muted-text — Muted footer signature text

Customize the HTML structure by adding a custom Twig template.

  1. Copy /modules/Invoice/templates/pdf/default-invoice.twig
  2. Paste as /modules/Invoice/templates/pdf/custom-invoice.twig

FOSSBilling uses custom-invoice.twig automatically.

Available in PDF templates:

VariableDescription
currency_codeInvoice currency code for format_currency.
cssContents of custom-invoice.css or default-invoice.css, inserted into the template's <style> block.
logo_sourceResolved company logo source. This can be a local path, a remote URL, an SVG data URI, or an empty string.
sellerDisplay-ready seller/company lines keyed by labels such as Name, Address 1, Phone, and VAT Number.
seller_linesNumber of seller lines used by the default template for layout calculations.
footerCompany footer details, including company name, bank details, address fields, email, phone, VAT/company number, website, and signature.
buyerDisplay-ready buyer/client lines keyed by labels such as Company, Name, Address, City, Country, Phone, and VAT Number.
buyer_linesNumber of buyer lines used by the default template for layout calculations.
invoiceFull invoice API array. Line items are in invoice.lines; raw buyer, seller, and client data are in invoice.buyer, invoice.seller, and invoice.client.

The PDF renderer does not provide top-level client, company, or currency variables. Use invoice.client, seller/footer, and currency_code instead.

<div class="custom-header">
<img src="{{ company.logo_url }}" alt="{{ company.name }}">
<h1>{{ 'Invoice'|trans }} #{{ invoice.serie_nr }}</h1>
</div>

PDF templates support the same Twig filters available elsewhere in FOSSBilling:

{{ invoice.total|format_currency(currency_code) }} {# Format as currency #}
{{ invoice.created_at|format_date }} {# Format the invoice date #}
{{ invoice.text_1|default('')|markdown_to_html }} {# Render invoice text as HTML #}
  1. Make your edits to custom-invoice.css or custom-invoice.twig
  2. Generate a test invoice
  3. Download the PDF
  4. Review the output

For complex issues, enable FOSSBilling debug mode in config.php:

'debug_and_monitoring' => [
'debug' => true,
],

Then review your PHP or FOSSBilling logs for Dompdf-related messages.