- PHP 8.0+
- MySQL 8.0+ or MariaDB 10.6+
- Apache with mod_rewrite enabled (or Nginx)
- Composer (optional, for future packages)
Copy the entire optms_invoice/ folder into your web root:
/var/www/html/optms_invoice/ ← Linux/Apache
C:\xampp\htdocs\optms_invoice\ ← XAMPP Windows
/Applications/MAMP/htdocs/optms_invoice/ ← MAMP Mac
Open phpMyAdmin or MySQL CLI and run:
source /path/to/optms_invoice/config/schema.sqlOr paste the contents of config/schema.sql into phpMyAdmin SQL tab.
Edit config/db.php:
define('DB_HOST', 'localhost');
define('DB_NAME', 'optms_invoice');
define('DB_USER', 'your_mysql_username');
define('DB_PASS', 'your_mysql_password');
define('APP_URL', 'http://localhost/optms_invoice');From optms_invoice_manager_v6.html:
- Copy everything between
<style>and</style>→ paste intoassets/css/app.css - Copy everything between
<script>tags (the main app block) → paste intoindex.phpbefore the closing</body>, above theassets/js/app.jsscript tag
chmod 755 assets/uploads/
chmod 644 config/db.phphttp://localhost/optms_invoice/
You'll be redirected to the login page.
| Field | Value |
|---|---|
| admin@optmstech.in | |
| Password | Admin@1234 |
optms_invoice/
├── index.php ← Main app (requires login)
├── .htaccess ← Apache security rules
├── README.md
│
├── auth/
│ ├── login.php ← Login page
│ ├── logout.php ← Clears session, redirects
│ └── forgot_password.php ← Password reset request
│
├── config/
│ ├── db.php ← DB credentials + PDO connection
│ └── schema.sql ← Database tables + default data
│
├── includes/
│ └── auth.php ← Session, login, logout helpers
│
├── api/
│ ├── invoices.php ← GET/POST/PUT/DELETE invoices
│ ├── clients.php ← GET/POST/PUT/DELETE clients
│ ├── products.php ← GET/POST/PUT/DELETE products/services
│ ├── payments.php ← GET/POST payments
│ ├── reports.php ← GET report data (summary + charts)
│ ├── settings.php ← GET/POST company settings
│ └── upload.php ← POST file uploads (logo, signature)
│
└── assets/
├── css/
│ └── app.css ← Paste CSS from v6 HTML here
├── js/
│ └── app.js ← API override layer (already complete)
├── img/ ← Static images
└── uploads/ ← User-uploaded logos & signatures
Browser PHP/Apache MySQL
│ │ │
│── GET /index.php ─────────▶ requireLogin() │
│ │── SELECT user ───────▶│
│◀── HTML + SERVER{} ───────│ │
│ │ │
│── fetch('api/invoices')──▶│── SELECT invoices ───▶│
│◀── JSON [{...}] ──────────│◀── rows ──────────────│
│ │ │
│── saveInvoice() JS ───────│ │
│── fetch('api/invoices', │ │
│ POST, payload) ──▶│── INSERT invoice ────▶│
│◀── {success:true} ────────│◀── lastInsertId ──────│
index.phpgates the entire app behind PHP session auth- On load, JS calls all 4 API endpoints in parallel to populate STATE
- All create/edit/delete actions call the API which writes to MySQL
- The
assets/js/app.jsoverrides the in-memory save functions with API calls - Falls back gracefully if API fails (keeps working with in-memory data)
| Method | URL | Description |
|---|---|---|
| GET | api/invoices.php | List all invoices |
| GET | api/invoices.php?id=5 | Get single invoice with items |
| GET | api/invoices.php?status=Paid&from=2025-01-01 | Filter |
| POST | api/invoices.php | Create invoice (JSON body) |
| PUT | api/invoices.php?id=5 | Update invoice |
| DELETE | api/invoices.php?id=5 | Delete invoice |
| Method | URL | Description |
|---|---|---|
| GET | api/clients.php | List all clients |
| POST | api/clients.php | Create client |
| PUT | api/clients.php?id=3 | Update client |
| DELETE | api/clients.php?id=3 | Soft delete (is_active=0) |
| Method | URL | Description |
|---|---|---|
| GET | api/payments.php | List all payments |
| GET | api/payments.php?from=2025-03-01&to=2025-03-31 | Date filter |
| POST | api/payments.php | Record payment (also marks invoice Paid) |
| Method | URL | Description |
|---|---|---|
| POST | api/upload.php | Upload image file (multipart/form-data) |
| fields: file, type (logo/signature/qr/client_logo) |
- Passwords stored as bcrypt hashes (
password_hash()) - All DB queries use PDO prepared statements (SQL injection proof)
- Sessions regenerated on login (
session_regenerate_id) .htaccessblocks direct access toconfig/andincludes/- Upload directory blocks PHP execution
- Add CSRF token validation for production (token field exists in login form)
- Change default admin password
- Set
APP_URLto your live domain - Enable HTTPS and set
securecookie flag - Configure SMTP for email (update
email-setuppage settings) - Set
display_errors = Offin php.ini - Set up MySQL user with minimal privileges (not root)
- Configure regular database backups
- Set folder permissions: uploads 755, config 640