When I started working on B2B e-invoicing, I thought the technical part would be straightforward. Generate a PDF, embed an XML, follow a standard. On paper, it seemed linear.
In practice, it's something else entirely.
Here's what actually took time — not the concepts, but the details that break everything in production.
The Comfort profile is not declared — it is earned
EN16931 defines several profiles. The Comfort profile, the one that guarantees real interoperability with accounting systems, requires strict identifier completeness.
SIREN alone is not enough. SIRET alone is not enough. The combination of SIREN + SIRET + VAT number determines the profile declared in the XML. If one identifier is missing, the profile changes. And an incorrect profile means a technically invalid invoice — even if it looks perfectly fine visually.
I implemented conditional validation logic before generation. No silent correction, no approximation. Either the data is complete, or the invoice does not go out.
Multi-period invoicing is a state problem, not a calculation problem
Invoicing across multiple months in a single document seems simple. It is not.
The real issue: a period included in an issued invoice is permanently closed. It cannot be re-invoiced, partially modified, or cancelled. This is not a software constraint — it is a legal and accounting one.
I had to model an explicit state system per period and per client, using immutable archiving flags. No database — only locked, deterministic and traceable files.
Deduplication without a database
The classic question: how do you prevent issuing the same invoice twice if the process is restarted?
My answer: file-based locks. Each execution cycle checks for the existence of a lock file before generating anything. No race condition, no distributed transaction, no external dependency. One execution = one deterministic cycle. If the file exists, skip. Otherwise, generate and lock.
Simple, traceable, reliable.
The pipeline runs on cron — no background process, no service to keep alive
No persistent process running in the background, no service to maintain active, no SaaS dependency. The engine triggers, processes, archives and stops. Each execution is independent and reproducible.
This architectural choice has a direct consequence: if something goes wrong, there is nothing to restart, nothing to debug live. Logs are exhaustive, states are explicit, generated files are evidence.
What I take from this
Factur-X is not a PDF generation problem. It is a structured pipeline problem — controlled states and normalized data before production.
Tools that "generate Factur-X" are plentiful. Systems that guarantee end-to-end compliance, full traceability and zero implicit correction are far less common.
https://palks-studio.com/en/batch-invoicing-facturx
If you're interested in how it works under the hood:
Here’s a technical breakdown of the system architecture.
Overview Project
This repository presents a financial automation system designed to handle:
- invoice generation (single & batch)
- revenue tracking
- payment reconciliation
- client balances
- accounting-ready exports
The system is deterministic, auditable, and explicit by design.
It operates:
- without a database
- without a CMS
- without a SaaS dependency
- without any exposed web interface
All executions run server-side, via CLI scripts and cron, with a strict separation of responsibilities.
This project is not a product, not a SaaS, and not a plug-and-play tool.
It documents a production-grade approach to financial automation.
Over time, the engine has been progressively extended
to cover real-world business cases,
without compromising its original design principles.
The billing system now supports:
- multi-line invoices
- multiple VAT rates per invoice
- complex or extended service periods
- multi-month billing scenarios
- complex combinations while remaining EN16931 Comfort compliant
This functional expansion did not alter
the deterministic, auditable, and traceable nature of the system.
Electronic invoicing (Factur-X)
The system natively integrates Factur-X electronic invoicing (hybrid PDF with embedded XML),
in compliance with the European EN 16931 standard (Comfort profile):
- generation of a semantically EN 16931-compliant Factur-X XML
- XML validation (XSD and Schematron)
- injection of the XML into the PDF
- production of a single final document: the Factur-X hybrid PDF
- direct integration into the
run.phpandrun_batch.phppipelines - no parallel formats
- no persistent XML storage
The system targets business compliance and e-invoicing interoperability (France / EU).
PDF/A compliance (document archiving) is not a functional objective of the project and is deliberately out of scope.
Factur-X is handled as a native component of the engine,
not as an external or optional module.
Project structure
automation_finance/
│
├── engine/
│ ├── build_facturx_xml.php → Factur-X XML generation
│ ├── build_json.php → Client onboarding JSON builder
│ ├── inject_facturx.py → Factur-X XML injection into PDF
│ ├── run.php → Main automation engine (cron / CLI)
│ ├── run_batch.php → Batch automation engine for client invoicing
│ ├── billing_rules.php → Billing rules and dynamic pricing logic
│ ├── alerts.php → Execution alerts and notifications handling
│ ├── import_csv.php → Client CSV import and validation handler
│ ├── mailer.php → Email sender with invoice attachment
│ ├── mail_signature.php → Palks Studio signature
│ ├── vendor/ → PHP dependencies (e.g. DomPDF)
│ └── templates/ → Invoices PDF template (bilingual FR / EN)
│
├── data/
│ ├── logs/ → Execution logs per client
│ ├── onboarding/ → JSON files generated by the client onboarding form
│ ├── onboarding_done/ → Processed onboarding JSON archived after build
│ ├── archive_batch/ → Archived client CSV
│ ├── batch_sent/ → Zip sent
│ ├── usage/ → Monthly client usage tracking
│ ├── revenues/ → Cumulative revenues (internal accounting source)
│ ├── payments/ → Payments received from the client (bank transfers, actually received amounts)
│ ├── balance/ → Client accounting balance (invoiced vs paid, paid / unpaid status)
│ ├── invoices/ → Invoices from the main activity (direct invoicing, internal use)
│ ├── invoices_batch/ → Invoices generated as part of the batch service (end clients)
│ ├── inbox_batch/ → Client-provided CSV file (batch invoicing source)
│ ├── counters/ → Annual invoice counter per client (direct invoicing)
│ └── counters_batch/ → Annual invoice counter per client (batch invoicing)
│
├── tools/
│ ├── update_balances.php → Updates client balances based on revenues and payments
│ ├── find_client.php → Client lookup utility
│ ├── build_client.php → Client email index builder
│ ├── send_paid_receipts.php → Automatic sending of paid client receipts
│ ├── purge_log.php → Cleanup Script
│ ├── client_project.php → CLI script aggregating and exporting client data by identifier
│ ├── recettes_year.php → Export actually received revenues for a full year
│ ├── recettes_month.php → Export actually received revenues for a given month
│ └── revenues_csv.php → Export revenues to a CSV file (accounting)
│
├── exports/
│ ├── recettes/ → Monthly CSV exports generated on demand / Yearly CSV exports generated on demand
│ └── payments/ → CSV generated from the received payments JSON files
│
├── downloads/ → Monthly ZIP archives per client, containing automatically generated PDF invoices
├── clients/ → Client configuration file (only file to edit per client)
├── batch_clients/ → Batch configuration for an end client (monthly invoicing)
├── CONTRATS/ → Legal documents related to the service
│
├── LICENCE.md → Conditions d’utilisation et cadre légal (FR)
├── LICENSE.md → Terms of use and legal Framework
│
└── docs/
├── README_FR.md → Documentation générale du système (FR)
├── README.md → General system documentation
│
├── SERVICE_MEMO_FR.md → Note interne de positionnement du service (FR)
├── SERVICE_MEMO.md → Internal Service Positioning Memo
│
├── README_DEPLOY_FR.md → Guide d’installation et d’exploitation (FR)
├── README_DEPLOY_EN.md → Installation and Production Guide
│
├── VUE_DENSEMBLE_AUTOMATION.md → Vue d’ensemble du système d’automatisation de facturation (FR)
└── SYSTEM_OVERVIEW_AUTOMATION.md → Billing Automation System Overview
If you want to explore the technical implementation, you can find it here:
https://github.com/Palks-Studio/automation-finance

Top comments (0)