A complete financial system deployed on your own domain in just a few clicks.
Not a SaaS.
No subscription.
No critical dependencies.
The system runs on your own hosting.
Quotes → online signature → invoicing → payment confirmation → revenue journal.
Everything is semi-automated.
Quote / contract
Simple interface:
- your fixed company details
- client information
- service lines
- currency / VAT
- your fixed banking details
The PDF is generated directly in the browser and sent to the client by email.
No data is sent to the server before validation.
Once the quote is sent:
- a secure link is sent to the client
- the client can view and sign the quote online
- the quote is archived
- you receive a confirmation email
The quote then becomes a signed contract.
Invoicing
The system includes a smart client lookup.
You only need to enter a single piece of information:
- SIRET / SIREN
- client name
and the system automatically retrieves:
- the client’s details
- their existing quotes (a list is suggested in the quote field)
The most recent quote is automatically suggested.
You simply select the correct quote from the list.
The system retrieves:
- service lines
- amounts
- client information
If no quote exists, the invoice can be generated directly with a free service description.
Once validated, the system immediately generates:
- the invoice
- the stamped invoice (pre-generated)
The invoice is sent to the client and archived.
The stamped version is stored while waiting for payment.
Payment confirmation
The interface lists all pending invoices.
One click is enough to:
- mark the invoice as paid
- send the stamped invoice
- add the entry to the revenue journal
The system also allows:
- monthly invoice export (ZIP)
- monthly revenue export (CSV)
- annual revenue journal export
All data is stored in simple files.
No database.
This system is designed to be:
- autonomous
- installable on any PHP hosting
- bilingual FR / EN
- fully documented
The data stays with the client.
This is the type of systems I design at Palks Studio:
simple tools that automate complete business processes.
If you want to install this system on your own infrastructure:
Overview
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.
Features
- 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
Project Structure
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
│ │
│ ├── 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)
│
├── config.php → Central configuration for issuer and bank details
├── 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 → Usage documentation (client version)
The Three Modules
1. Quote Generator (quote-generator.php)
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
2. Direct Invoicing (invoice-engine.php)
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
3. Settlement & Payment Tracking (mark-paid.php)
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
Supporting Modules
Electronic Signature (signer.php)
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
Client Auto-fill (lookup.php)
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)
Secured PDF Access (pdf-proxy.php)
Token-based PDF proxy. Serves a PDF without exposing its physical path on the server.
Internal Mailer (mailer.php)
Email sending engine with attachment support. Used by all modules. No external SMTP dependency.
Security
- 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 responses -
Cache-Control: no-storeon all authenticated pages -
noindex, nofollowon all internal interfaces
Automatic Emails
| 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.
Technical Requirements
- 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
Archiving & Data
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
Top comments (0)