π¬π§ English | π«π· FranΓ§ais
β οΈ This repository presents the project and its technical documentation.
The production version is not publicly distributed.Installation is performed directly on the client's hosting infrastructure.
If you are interested in using this system, please contact Palks Studio.
Complete, autonomous and bilingual (FR/EN) billing system deployable on any PHP/Apache hosting. No database. No SaaS dependency. Self-hosted with full ownership of your data.
Billing System is a suite of three interconnected billing tools accessible from a unified interface. It covers the full lifecycle of a service engagement: from quote generation to invoice settlement, including electronic signature and structured archiving.
The system is designed to be deployed directly on the client's server, on a standard Apache hosting environment with PHP 8.x and Composer. It requires no database, no third-party service, and no subscription.
- Client-side quote PDF generation (jsPDF)
- Server-side invoice PDF generation (Dompdf)
- Automatic pre-generation of the paid invoice at billing time
- Electronic quote signing by the client (touch/mouse canvas)
- Client auto-fill from archives (SIREN, SIRET, VAT, email, name)
- Structured archiving by client and period
- Secure sequential numbering (file lock)
- Monthly export of invoices (ZIP)
- Monthly export of revenue records (CSV)
- Yearly export of the revenue journal (CSV)
- Automatic email notifications at each stage (quote, invoice, settlement)
- Cross-module navigation bar
- Bilingual FR/EN interface with real-time language switch
- Dark mode / light mode with persistence
- No database
- No SaaS dependency
- Basic security: secure sessions, tokens, brute-force protection
billing-system-en/
β
βββ billing-public/
β β βββ assets/
β β βββ logo* β User logo if provided
β β βββ signature.png β User signature used on quotes and invoices
β β βββ favicon* β Optional site favicon displayed in the browser tab
β β βββ jspdf.umd.min.js β jsPDF library used to generate PDFs in the browser
β β
β βββ generator-direct.php β Quote generation endpoint
β βββ engine-direct.php β Invoice generation endpoint
β βββ invoice-direct.php β Direct invoice generation endpoint
β β
β βββ quote-generator.php β Web interface for quote generation
β βββ invoice-engine.php β Web interface for direct invoice generation
β βββ mark-paid.php β Web interface used to mark an invoice as paid
β βββ signer.php β Web interface for quote viewing and signing
β βββ export-invoices.php β ZIP export of archived invoices
β βββ export-recettes.php β CSV export of the revenue journal
β β
β βββ config.php β Central configuration for issuer and bank details
β βββ lookup.php β Client information lookup and auto-fill
β βββ pdf-proxy.php β Secure PDF access via token
β βββ .htaccess β Apache security and configuration rules
β βββ quote-generator-save.php β Generated quote saving and archiving
β
βββ vendor/ β Libraries used for PDF document generation
βββ templates/ β HTML templates used to render documents
β βββ invoice-template.php β Document rendering template (PDF or preview)
β
βββ mailer.php β Internal email sending script with attachments
βββ engine.php β Main engine: document generation, calculations and archiving logic
βββ LICENSE.md β Project license
β
βββ contracts/ β Archive of signed and unsigned quotes
βββ counters/ β Sequential numbering counters for quotes and invoices
βββ logs/ β System logs (optional)
βββ data/
β βββ invoices/ β Archive of invoices awaiting payment
β βββ invoices_state/ β Pre-generated paid invoices
β βββ invoices_paid/ β Paid invoices archive
β βββ revenues/ β Revenue CSV files
β
βββ docs/
βββ USER_GUIDE.md β User guide
βββ OVERVIEW.md β Project overview and general system description
βββ README.md β Installation and usage documentation (client version)
Quote creation interface with PDF generation entirely in the browser (jsPDF). No data is sent to the server before the user confirms.
Workflow:
- The user fills in the form: issuer details, client details, service lines, bank details, settings (currency, PDF language).
- A live total preview (excl. VAT / VAT / incl. VAT) is calculated in real time.
- On submission, a confirmation dialog appears before generation.
- The PDF is generated locally and downloaded. Simultaneously, the quote is archived server-side with a signature token valid for 30 days.
- An email is sent to the client with a link to review and sign online.
Technical details:
- Numbering is automatic and resumes from the client's existing base
- Client auto-fill by SIREN, SIRET, VAT number, email or name (lookup in archives)
- Browser-side Luhn validation for SIRET/SIREN
- Auto-fill SIREN from SIRET
- Real-time FR/EN language switch without page reload (100+ i18n keys)
- Currency selector: EUR, USD, GBP, CHF, CAD
- Conditional bank details (IBAN/BIC) in PDF
- "Approval" block with configurable signature image
- Conditional VAT footer (art. 293B CGI if VAT = 0)
- Automatic PDF pagination
Server-side invoice generation interface via Dompdf. Produces two PDFs simultaneously on each generation: the standard invoice and the paid invoice (pre-generated, awaiting payment confirmation).
Workflow:
- The user fills in the form: client details, service lines, service date, optional deposit, associated quote reference.
- On submission, the server validates the data, generates both PDFs and archives the metadata.
- The standard invoice is downloaded automatically and emailed to the client as an attachment.
- The paid invoice is stored in
invoices_state/awaiting payment confirmation.
Technical details:
- Annual sequential numbering in the format
ALT-YYYY-0001with file lock (flock). The counter resumes from the client's existing base if invoices are already present - Protection against duplicate invoicing on the same quote reference (HTTP 409)
- Full input validation with FR/EN error messages
money2()calculation with epsilon correction (float precision)- VAT aggregation by rate
- PNG logo converted to JPEG via GD if available (transparency handling for Dompdf). Without transparency, the output is identical
- Issuer details retrieved from the most recent known
meta.json - SHA256 of archived PDF stored in metadata
- Email with PDF attachment via internal mailer
Interface for tracking pending invoices and confirming settlement. Displays the list of generated invoices not yet paid, allows marking them as paid, and maintains a revenue log.
Workflow:
- The module automatically scans
invoices_state/and lists all pre-generated paid invoices not yet confirmed. - The user selects the payment date and clicks "Mark as paid".
- The system moves the paid PDF to
invoices_paid/, updates themeta.json, appends a line to the revenue CSV, logs the operation, and emails the paid invoice to the client. - A table of the 10 most recent revenues for the current year is displayed at the bottom of the page.
Technical details:
- Recursive scan via
RecursiveIteratorIterator(detects both_ACQUITTEE.pdfand_PAID.pdf) - Filters already-paid invoices via
meta.json - CSV deduplication (checks invoice number before appending)
flockon all file writes- POSTβGET redirect (
?success=) to prevent form resubmission - Pending invoice counter badge
- Annual CSV export
recettes-YYYY.csvwith;separator
Public page accessible by the client via a tokenised link. Allows reviewing the quote and appending an electronic signature.
- Multi-page PDF preview via pdf.js
- Touch and mouse signature canvas (devicePixelRatio, resize handler)
- Format validation (PNG data URI, minimum size)
- PNG signature saved to disk
meta.jsonupdate (signed_at,sign_ip_hash)- Dual FR/EN confirmation email: client + issuer
- Protection against double signing
- Link expiry at 30 days
JSON endpoint called on form input. Searches quote archives by SIREN, SIRET, VAT number, email, name or quote number.
- Returns full client details, lang, currency, client quote list
- Returns quote lines for automatic invoice pre-fill
- Query normalisation (whitespace removal for SIREN/SIRET)
- Triple scan pass (contracts β exact quote β meta files)
Token-based PDF proxy. Serves a PDF without exposing its physical path on the server.
Email sending engine with attachment support. Used by all modules. No external SMTP dependency.
- Hardened PHP sessions:
httponly,secure,samesite=Strict - Brute-force protection: blocked after 10 failed attempts
session_regenerate_id()on every successful login- Signed tokens
bin2hex(random_bytes(32))for quotes - Strict regex validation of tokens (64-char hex)
- SHA256 hash of IP address (GDPR-safe, non-reversible)
- SHA256 hash of archived PDF
- All endpoints protected by session guard
X-Content-Type-Options: nosniffon all responsesCache-Control: no-storeon all authenticated pagesnoindex, nofollowon all internal interfaces
| Event | Recipient(s) | Content |
|---|---|---|
| Quote generation | Client | Signature link + PDF download link |
| Quote signed | Client + Issuer | Signature confirmation + PDF link |
| Invoice generation | Client | Invoice as attachment |
| Settlement | Client | Paid invoice as attachment |
All emails are bilingual FR/EN based on the document language.
- PHP 8.1 or higher
- Apache with
mod_rewrite - Composer
- GD extension (PNG logo conversion)
- Active
mail()function on the server (or SMTP configured via mailer) contracts/,data/,counters/,logs/directories writable by the web server
All data is stored as flat files. No database is required.
| Type | Location | Format |
|---|---|---|
| Quotes | contracts/YYYY-MM/{client_id}/ |
PDF + meta.json |
| Signatures | contracts/YYYY-MM/{client_id}/ |
PNG |
| Invoices | data/invoices/{client_id}/YYYY-MM/ |
PDF + meta.json |
| Paid invoices (pending) | data/invoices_state/{client_id}/YYYY-MM/ |
|
| Paid invoices (confirmed) | data/invoices_paid/{client_id}/YYYY-MM/ |
|
| Revenues | data/revenues/recettes-YYYY.csv |
CSV (; separator) |
| Counters | counters/invoice_seq_YYYY.txt |
Integer |
| Logs | logs/*.log |
Timestamped text |
Β© Palks Studio β see LICENSE.md
