Home/ Work/Invoicing System for Slovenian Small Businesses
Creator · 2024 — 2026 · Live

Invoicing System for Slovenian Small Businesses

A self-hosted PHP invoicing tool built for Slovenian small businesses — UPN QR codes, DDV/VAT compliance, dual PDF engines, and email delivery. Battle-tested across real books and client deployments.

Role Creator / Sole Author
Duration 2024 → 2026
Stack PHP 8 · TCPDF · mPDF · PHPMailer
Storage JSON flat-file · data outside web root
Compliance 94. člen ZDDV-1 · UPN QR · SI00 reference
Deployment cPanel VPS · GitHub CI/CD
PDF engines
2
TCPDF + mPDF with auto-fallback
Tax regimes
2
domestic DDV-exempt + EU reverse-charge
Email methods
3
php_mail · sendmail · SMTP
UPN QR standard
19-field
ISO-8859-2, SI00 reference

Overview

I built this invoicing system for small Slovenian businesses — the kind that issue a few dozen invoices per year, need to stay compliant with Slovenian DDV/VAT rules, and want a self-hosted tool that doesn’t phone home or lock them into a SaaS subscription.

It’s been running in production since 2024, covering real invoicing cycles. The scope is deliberately narrow: create an invoice, generate a compliant PDF with a UPN QR code the client’s bank can scan, and send it by email. Everything is configurable through a web UI with no framework overhead — raw PHP 8, flat JSON storage, and a REST API that also lets me issue invoices from the CLI or from other tools.

The hardest part wasn’t the UI — it was getting the UPN QR code exactly right. The standard mandates a specific 19-field payload in ISO-8859-2 encoding, a GDSV purpose code, an SI00 payment reference derived from the invoice number, and a 3-digit checksum that counts all field lengths plus the newline characters between them. Every Slovenian banking app validates this strictly. I also implemented the sibling UPN-QR microservice as a standalone Node.js/Express QR generator that follows the same standard — useful for other integrations.

Architecture

~/invoices/architecture/system-map.svg
01 — ENTRY POINTSWeb UIbrowser · create/view/sendREST APIX-API-Key · CLI / integrationsInvoiceGenerator.phpPHP 8 · invoice data model · template renderingdual PDF engine (TCPDF / mPDF) · UPN QR payloadDDV-exempt note · SI00 reference · ISO-8859-202 — OUTPUTTCPDFprimary PDF enginemPDFHTML-to-PDF fallbackUPN QR19-field · GDSV · SI00PHPMailer 6SMTP · sendmail · mail()03 — STORAGEJSON flat-filesclients · invoices · servicescPanel VPS · GitHub CI/CD via SSH deploy key · data dir outside web root · async backup to private repo04 — INFRA

Reading the diagram: Invoices enter via the browser UI or the REST API (API-key authenticated). The InvoiceGenerator class handles the full data model — dates, DDV-exempt notes, per-item discounts, and UPN QR payload generation. PDFs are rendered by TCPDF (primary) with automatic fallback to mPDF; the QR code is embedded directly. Completed invoices are stored as JSON flat-files in a directory outside the web root, and email delivery goes through PHPMailer 6 supporting three sending methods. Everything deploys via GitHub → cPanel SSH.

Invoice mockup

~/invoices/output/101-2025-ClientName.pdf
NINVOICEPodjetje d.o.o.Glavna ulica 11000 LjubljanaKraj izdaje:Blejska DobravaDatum izdaje:15.01.2025Datum zapadlosti:23.01.2025YOUR COMPANY D.O.O.Blejska Dobrava 61, 4273Davčna št.: 82426627DDV zavezanec: NERačun št.:101-2025ŠT.STORITEVKOL.CENAPOPUSTVREDNOST1Letno gostovanje - primer.si - 1 leto - 1.1.2025 - 31.12.2025175,00 EUR75,00 EUR2Podaljšanje domene .si - primer.si - 1 leto - 7.2.2025 - 6.2.2026122,00 EUR22,00 EUROpomba: DDV ni obračunan na podlagi 1. odstavka 94. člena ZDDV-1SKUPNA VREDNOST:97,00 EURSKUPAJ POPUST:- €SKUPAJ ZA PLAČILO EUR:97,00 EURUPN QR kodaNačin plačila:TRRIBAN:SI56 1010 0005 2158 156Sklic:SI00 1012025INFO@YOURBIZ.SI · WWW.YOURBIZ.SI · +386 XX XXX XXXVEM št. 0414-81-20130702-000531 · Matična št.: 6405380000

Stylized mockup of the generated PDF — three-column header, line-item table with per-item discounts, DDV-exempt footnote, UPN QR code (scanned by any Slovenian banking app), and SI00 payment reference derived from the invoice number.

03 What I delivered · challenges solved

Six things shipped,
three hard ones solved.

Key contributions

  • Designed and implemented the full invoicing system from scratch — web UI, REST API, PDF pipeline, email delivery, and data layer.
  • Implemented the Slovenian UPN QR standard: 19-field ISO-8859-2 payload, SI00 payment reference, GDSV purpose code, and 3-digit checksum.
  • Built a dual-engine PDF pipeline (TCPDF + mPDF) with automatic fallback and separate flex-free mPDF template for compatibility.
  • Wired DDV/VAT compliance for two regimes: domestic small-business exemption (94. člen ZDDV-1) and EU reverse-charge (Article 44, Directive 2006/112/ES).
  • Shipped configurable email delivery — php_mail, sendmail, and full SMTP via PHPMailer 6 — with Markdown-templated messages and PDF attachment.
  • Set up CI/CD from GitHub to cPanel VPS via SSH deploy keys; data files live outside web root and async-backup to a sibling private repo.

Challenges solved

  • The Slovenian UPN QR standard is strict: 19 newline-separated fields, amounts in cents zero-padded to 11 digits, content in ISO-8859-2, and a 3-digit checksum that counts all newline characters. One byte off and every banking app rejects it.
  • TCPDF and mPDF behave differently with flexbox HTML — mPDF simply ignores it. Maintaining two template variants without duplicating business logic required a clean separation between data rendering and layout.
  • cPanel shared-hosting imposes tight constraints: no background workers, no Redis, no writable system temp by default. Async backup uses proc_open with bypass_shell on both Windows (dev) and Linux (prod) paths.
Small doesn't mean simple to get right. Slovenian invoicing has real legal requirements, and every PDF that ships is a legal document.
Davor Majc, Creator
04 Tech stack

What's under the hood.

PHPTCPDFmPDFPHPMailerUPN QRDDV/VATJSONcPanel VPSGitHub Actions
Let's talk

¿Listo para arreglar, construir
o escalar?

30 minutos, conmigo personalmente. Leo tu sistema como un archivo de logs y te digo qué haría primero. Sin presentaciones, sin embudo de ventas.

Davor Majc, fundador, Numen

What you get on call
→ un diagnóstico de una página
→ 2–3 formas de solución, ordenadas por impacto
→ coste aproximado + plazo para cada una
→ sí/no — ¿soy la elección adecuada?
+386 40 828 474 · Blejska Dobrava, SI