A clean, self-hosted invoice management app built with PHP + MySQL. Create, edit, and share professional A4-sized invoices with live preview, PDF export, QR codes, and shareable links.
This project's editor UX and invoice templates are inspired by EasyInvoicePDF by Vlad Sazonau — a fantastic browser-only invoice generator. If you want a no-sign-up, client-side alternative, check it out. InvoiceApp takes the same "live preview + instant PDF" approach and adds a server-side backend (PHP + MySQL) so you can store, search, duplicate, and share invoices with your team.
Differences from EasyInvoicePDF:
- Persistent storage — invoices are saved to MySQL, not just held in browser state
- Multi-invoice management — dashboard, search, filter, status tracking, duplicate
- Shareable links — tokenized public URLs to send clients
- Your own data — self-hosted, no third-party services required
- Live preview editor — see changes as you type (split-screen 33/67 layout)
- Two invoice templates — Classic (light, clean) and Modern (gradient header)
- A4-sized PDF output — print-ready, single-page
- Shareable links — generate tokenized URLs to share invoices with anyone
- QR codes — opt-in QR on invoice for payments/links
- Custom logo upload — with size slider, removable
- Custom footer text — per invoice
- 80+ currencies — with proper symbols and names
- Amount in words — auto-generated from total
- Discount + tax — % or fixed discount, applied before tax
- Payment tracking — To pay / Paid / Left to pay
- Search + filter — by invoice number, client, or status
- Duplicate invoice — clone any invoice as a new draft
- Backend: PHP 8+ (no framework, plain PHP)
- Database: MySQL 5.7+ / MariaDB
- Frontend: Vanilla JS, CSS, no build step
- Server: Apache (LAMP/WAMP/MAMP)
- PDF: Browser print-to-PDF (no extra libraries)
- PHP 8.0 or higher (with
pdo_mysqlextension) - MySQL 5.7+ or MariaDB 10.3+
- Apache with
mod_rewrite(for clean URLs) - ~10 MB disk space
git clone https://github.com/yourusername/invoice-app.git
cd invoice-appmysql -u root -p < setup.sqlThis creates the invoice database with two tables: invoices and invoice_items.
cp config.example.php config.phpEdit config.php and fill in your database credentials:
define('DB_HOST', 'localhost');
define('DB_NAME', 'invoice');
define('DB_USER', 'your_user');
define('DB_PASS', 'your_password');The uploads/ directory needs to be writable by the web server:
chmod 755 uploads/
chown www-data:www-data uploads/ # Apache on Debian/UbuntuApache — Make sure mod_rewrite is enabled and .htaccess is allowed. The included .htaccess handles clean URLs (no .php extension needed).
Nginx — Add this to your server config:
location / {
try_files $uri $uri/ $uri.php?$query_string;
}Navigate to http://localhost/invoice-app/ in your browser. You should see the dashboard with no invoices yet. Click + New Invoice to create your first one.
- Currency list — edit the
currenciesarray increate.php(search forconst currenciesorlet currencies) - Templates — each template is a JavaScript template literal in
create.php(search forif (currentTemplate === 'modern')) - Logo directory — change
uploads/path in the file upload handler increate.php
Instead of editing config.php, the app reads these env vars (used automatically by config.php):
| Variable | Default | Notes |
|---|---|---|
DB_HOST |
none — required for env mode | MySQL host |
DB_PORT |
3306 |
MySQL port |
DB_NAME |
invoice |
Database name |
DB_USER |
root |
Database user |
DB_PASS |
empty | Database password |
If any of these are set, config.php uses them. Otherwise it falls back to config.example.php.
InfinityFree is a great way to get a free, permanent public URL for your invoice app — no credit card, no trial limits, free subdomain included. Live demo: invoice.great-site.net
- Sign up free at infinityfree.com (no card required)
- From the client area, click Add Account and pick a free subdomain (e.g.
yourname.great-site.netoryourname.infinityfreeapp.com) - Wait a few seconds for the account to be provisioned
- Open the cPanel for your new account
- Go to MySQL Databases
- Create a new database (e.g.
invoice) and a database user with a strong password - Add the user to the database with All Privileges
- Note down these values — you'll need them:
- MySQL Hostname (usually
localhoston newer accounts, orsqlXXX.infinityfree.com) - Database Name (e.g.
if0_12345678_invoice) - Username (e.g.
if0_12345678) - Password (the one you set)
- Port (
3306)
- MySQL Hostname (usually
- In cPanel, open phpMyAdmin
- Select your
if0_xxx_invoicedatabase from the left sidebar - Click the Import tab
- Choose
setup.sqlfrom the project root - Click Go — you should see "Import has been successfully finished" with 2 tables (
invoices,invoice_items)
- In cPanel, open File Manager and navigate to
htdocs/ - Upload
config.example.phpfrom the project, then rename the copy toconfig.php(or upload a pre-filledconfig.phpfrom your local machine) - Edit
config.phpand fill in the 5 values from step 2:
define('DB_HOST', 'localhost');
define('DB_NAME', 'if0_12345678_invoice');
define('DB_USER', 'if0_12345678');
define('DB_PASS', 'your_strong_password');
define('DB_PORT', '3306');In cPanel → File Manager → htdocs/, upload all files from the project root EXCEPT:
.git/(git history)Dockerfile,docker-entrypoint.sh,nginx.conf(Docker-only, not needed).dockerignore
The fastest way: zip the project on your computer (excluding the above), upload the zip, then Extract in cPanel.
- In File Manager, right-click the
uploads/folder → Permissions - Set to
755(or775if uploads fail)
Visit https://yourname.great-site.net/ — you should see the dashboard. Click + New Invoice to create your first one.
InfinityFree notes:
- No shell/SSH access — all DB operations go through phpMyAdmin
- Env vars are not reliably supported, so use
config.phpwith hardcoded values- PHP 7.4+ and MySQL are available
- The
htdocs/folder is your project root (not the folder above it)- Free forever, no credit card, no trial expiry
- Ad are not shown on free subdomains, but resource limits apply (50k hits/day, 5GB disk)
- Click + New Invoice
- Fill in invoice details, your info (From), client info (To)
- Add line items
- Optionally enable QR code, set discount, tax, payment details
- Watch the live preview on the right
- Click Save Invoice
- Open any invoice
- Click Share in the actions bar
- Click Generate Shareable Link
- Copy the link and send it to your client
- Anyone with the link can view and download the invoice (no login required)
- Click Revoke Link to disable access
- From the editor: click Download PDF (opens print dialog → Save as PDF)
- From the invoice view: click Print / PDF
- From the share link: click Download PDF
The output is a single A4 page (210mm × 297mm) with all colors preserved.
.
├── .htaccess # Apache clean-URL rewrite rules
├── LICENSE # MIT license
├── README.md # This file
├── config.example.php # Database config template
├── setup.sql # Database schema
├── create.php # Editor page (split-screen)
├── index.php # Dashboard (invoice list)
├── view.php # Invoice detail view (auth)
├── view-public.php # Public invoice view (token-based)
├── share.php # API for generating/revoking share links
├── duplicate.php # Clone invoice handler
├── delete.php # Delete invoice handler
├── style.css # All app styles
├── favicon.svg # App icon
├── uploads/ # Logo storage (gitignored)
│ └── .gitkeep
This app is designed for self-hosted, single-user use (e.g., a freelancer or small business owner). It does not include:
- User authentication / multi-tenancy
- CSRF protection
- Rate limiting
- Input sanitization beyond
htmlspecialcharson output
If you want to expose this to the public internet, you should:
- Add authentication (e.g., HTTP Basic Auth, or a proper login system)
- Add CSRF tokens to all forms
- Add rate limiting on
share.phpandview-public.php - Use HTTPS (Let's Encrypt)
- Move
uploads/outside the web root and serve via PHP - Restrict
view.phpand the actions to authenticated users only
The public share link is intentionally token-based and read-only, so it's safe to share.
- EasyInvoicePDF by Vlad Sazonau — inspiration for the editor UX, live preview, and invoice template design. Licensed under AGPL-3.0.
- QR code generation powered by goqr.me API.
- Deployed on InfinityFree (free PHP + MySQL hosting, no credit card, free subdomain). The live demo at invoice.great-site.net runs on their platform.
Pull requests welcome! For major changes, please open an issue first to discuss.
MIT — see LICENSE for details.