SwissQrBill

Swiss QR-bill generation library for Elixir, implementing the SIX QR-bill standard (v2.3).

Generates the complete payment part (Zahlteil) with receipt as PDF, SVG, or PNG — ready for printing or embedding in invoices.

Issues & Feedback

This library is developed at git.e9li.com and mirrored to GitHub. If you found a bug or have a suggestion, you can either:

Installation

Add swiss_qr_bill to your list of dependencies in mix.exs:

def deps do
[
{:swiss_qr_bill, "~> 0.1.3"}
]
end

System requirements

PDF output works out of the box. For SVG and PNG output, you need pdftocairo from the Poppler utilities:

Usage

Building a QR bill

# Create addresses
creditor = SwissQrBill.Address.new("Muster AG", "Bahnhofstrasse", "1", "8001", "Zürich", "CH")
debtor = SwissQrBill.Address.new("Max Muster", "Hauptstrasse", "42", "3000", "Bern", "CH")
# Address without street (minimal form)
creditor = SwissQrBill.Address.new("Muster AG", "8001", "Zürich", "CH")
# Generate a QR reference
{:ok, ref} = SwissQrBill.Reference.QrReferenceGenerator.generate("210000", "313947143000901")
# Build the bill
bill =
SwissQrBill.new()
|> SwissQrBill.set_creditor(creditor)
|> SwissQrBill.set_creditor_information("CH44 3199 9123 0008 8901 2")
|> SwissQrBill.set_payment_amount("CHF", 2500.25)
|> SwissQrBill.set_debtor(debtor)
|> SwissQrBill.set_payment_reference(:qrr, ref)
|> SwissQrBill.set_additional_information("Invoice 2024-001")

Validation

{:ok, bill} = SwissQrBill.validate(bill)
# or
{:error, errors} = SwissQrBill.validate(invalid_bill)
# errors is a list of descriptive strings

Validates IBAN format, QR-IBAN/reference-type compatibility, address fields, character sets, and more.

PDF output

{:ok, pdf_binary} = SwissQrBill.to_pdf(bill, language: :de)
File.write!("qr_bill.pdf", pdf_binary)

SVG output

Text is converted to glyph outlines (paths), so the output renders identically on all devices — no font installation required.

{:ok, svg_binary} = SwissQrBill.to_svg(bill, language: :de)
File.write!("qr_bill.svg", svg_binary)

PNG output

Rasterized from the PDF at configurable DPI for print-quality output.

{:ok, png_binary} = SwissQrBill.to_png(bill, language: :de, dpi: 300)
File.write!("qr_bill.png", png_binary)

Output sizes

All three formats support the :output_size option:

ValueDimensionsDescription
:payment_slip210 x 105 mmPayment part with receipt (default)
:a4210 x 297 mmFull A4 page with payment part at bottom
:qr_code56 x 56 mmQR code only
{:ok, pdf} = SwissQrBill.to_pdf(bill, language: :de, output_size: :a4)
{:ok, svg} = SwissQrBill.to_svg(bill, output_size: :qr_code)
{:ok, png} = SwissQrBill.to_png(bill, output_size: :a4, dpi: 150)

Languages

The :language option supports five languages. Defaults to :de.

CodeLanguage
:deDeutsch (German)
:frFrançais (French)
:itItaliano (Italian)
:enEnglish
:rmRumantsch (Romansh)
{:ok, pdf} = SwissQrBill.to_pdf(bill, language: :fr)

Branding

All three formats accept the :branding option. When true, a small gray "Created by qrbill.dev" line is added, localized to the bill's :language. Defaults to false, and output without it is unchanged.

{:ok, pdf} = SwissQrBill.to_pdf(bill, branding: true)
{:ok, svg} = SwissQrBill.to_svg(bill, branding: true)
{:ok, png} = SwissQrBill.to_png(bill, branding: true, dpi: 300)

The localized text is:

CodeText
:deErstellt mit qrbill.dev
:frCréé avec qrbill.dev
:itCreato con qrbill.dev
:enCreated by qrbill.dev
:rmCreà cun qrbill.dev

Placement depends on the :output_size:

Output sizePlacement
:a4Centered just above the payment slip's top edge (outside the standardized payment part)
:payment_slipSmall text at the bottom-right edge of the payment part
:qr_codeBelow the QR code; the canvas grows by 4 mm (56 x 60 mm) to fit the line

Reference generators

QR reference (QRR)

Used with QR-IBANs (IID 30000-31999). Generates a 27-digit reference with mod-10 check digit.

# With customer ID (BESR-ID) and reference number
{:ok, ref} = SwissQrBill.Reference.QrReferenceGenerator.generate("210000", "313947143000901")
#=> {:ok, "210000000003139471430009017"}
# With reference number only
{:ok, ref} = SwissQrBill.Reference.QrReferenceGenerator.generate("313947143000901")
#=> {:ok, "000000000003139471430009018"}

Creditor reference (SCOR)

ISO 11649 creditor reference with RF prefix. Used with regular IBANs.

{:ok, ref} = SwissQrBill.Reference.CreditorReferenceGenerator.generate("I20200631")
#=> {:ok, "RF15I20200631"}

No reference (NON)

bill = SwissQrBill.set_payment_reference(bill, :non)

IBAN utilities

# Validate an IBAN
{:ok, normalized} = SwissQrBill.IBAN.validate("CH44 3199 9123 0008 8901 2")
#=> {:ok, "CH4431999123000889012"}
# Check if it's a QR-IBAN
SwissQrBill.IBAN.qr_iban?("CH4431999123000889012")
#=> true
# Format an IBAN
SwissQrBill.IBAN.format("CH4431999123000889012")
#=> "CH44 3199 9123 0008 8901 2"

Reference type and IBAN compatibility

IBAN typeAllowed reference types
QR-IBAN:qrr only
Regular:scor or :non

QR-IBANs are identified by their IID (positions 5-9) being in the range 30000-31999.

Minimal bill (no amount, no debtor)

bill =
SwissQrBill.new()
|> SwissQrBill.set_creditor(SwissQrBill.Address.new("Muster AG", "8001", "Zürich", "CH"))
|> SwissQrBill.set_creditor_information("CH93 0076 2011 6238 5295 7")
|> SwissQrBill.set_payment_amount("CHF")
|> SwissQrBill.set_payment_reference(:non)
{:ok, pdf} = SwissQrBill.to_pdf(bill)

When amount or debtor are omitted, placeholder corner marks are rendered per the SIX style guide.

Alternative schemes

Up to 2 alternative payment schemes can be added (e.g. eBill):

bill =
bill
|> SwissQrBill.add_alternative_scheme("eBill/B/41010560425610173")
|> SwissQrBill.add_alternative_scheme("//S1/10/10201409/11/190512")

Output layout

The payment slip renders the complete payment part (210 x 105 mm):

The layout follows the SIX style guide specifications.

Validation constraints

FieldConstraint
Amount0 to 999,999,999.99
CurrencyCHF or EUR
Creditor nameMax 70 characters
Creditor streetMax 70 characters
Building numberMax 16 characters
Postal codeMax 16 characters
CityMax 35 characters
Country2-letter ISO code
MessageMax 140 characters
Bill informationMax 140 characters
Alt. scheme parameterMax 100 characters
Alternative schemesMax 2
IBANCH or LI, 21 characters
QRR reference27 digits, valid mod-10
SCOR referenceRF + check digits + 1-21 alphanumeric

Dependencies

License

MIT