No Docker · No Node.js

Setup Guide

Complete step-by-step installation — straight PHP, Composer, and MySQL. No containers, no npm build step.

System Requirements

Server

  • PHP 8.2 or higher
  • Composer 2.x
  • MySQL 5.7+
  • Apache, Nginx, or PHP's built-in server
  • Node.js is not required
  • Docker is not required

PHP Extensions

  • pdo_mysql
  • mbstring, openssl, tokenizer
  • xml, ctype, json, fileinfo, bcmath
  • GD or Imagick (image uploads)
  • cURL (payment gateways & AI calls)
No build step, ever. Tailwind, Alpine.js, and Livewire's front-end assets all load via CDN. There's no npm install, no webpack, and nothing to compile.

Installation

1

Unzip the project

unzip invoro.zip cd invoro
2

Install PHP dependencies

composer install
3

Copy the environment file

cp .env.example .env
4

Generate the application key

php artisan key:generate

Environment Configuration

Open .env and set at minimum:

KeyExampleNotes
APP_NAMEInvoroShown in emails and browser titles
APP_URLhttps://yourdomain.comNo trailing slash, no /public
APP_ENVproductionUse local for development
APP_DEBUGfalseAlways false in production
DB_CONNECTIONmysqlSee Database Setup below
OPENAI_API_KEY / ANTHROPIC_API_KEYsk-...Optional — only for AI features

APP_URL by deployment type

# Local — PHP built-in server APP_URL=http://localhost:8000 # XAMPP / WAMP subfolder APP_URL=http://localhost/invoro/public # Shared hosting subfolder APP_URL=https://yourdomain.com/billing/public # VPS / dedicated (document root = public/) APP_URL=https://yourdomain.com

Database Setup

Create the database first:

mysql -u root -p -e "CREATE DATABASE invoro CHARACTER SET utf8mb4;"

Update .env:

DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=invoro DB_USERNAME=root DB_PASSWORD=your_password

Migrate and seed:

php artisan migrate --seed
What --seed does: creates default subscription plans, seeds the AI feature toggle rows (all off by default), and adds default email templates. Every new business signup also automatically gets India's real GST slabs (or common VAT rates for other countries) and 10 standard expense categories — safe to run once on a fresh database.

File Permissions

This app writes to storage/, bootstrap/cache/, and public/uploads/ (logos, receipts, invoice PDFs):

chmod -R 775 storage bootstrap/cache public/uploads # If your web server runs as www-data: sudo chown -R $USER:www-data storage bootstrap/cache public/uploads

Running the Application

Local development

php artisan serve

Visit http://127.0.0.1:8000

After changing .env or config files

php artisan config:clear php artisan cache:clear php artisan view:clear

Production optimization

php artisan config:cache php artisan route:cache php artisan view:cache

Two Background Processes You Must Run

Easy to miss, and half the automation in this app silently depends on them:

A. The scheduler — recurring invoices, reminders, currency rates

These jobs are defined but do nothing on their own. Add exactly one cron entry:

crontab -e # add this line: * * * * * cd /full/path/to/invoro && php artisan schedule:run >> /dev/null 2>&1

Windows: use Task Scheduler to run php artisan schedule:run every minute from the project directory.

B. The queue worker — outbound emails

php artisan queue:work --tries=3

To keep it running natively without Docker:

OSTool
macOSlaunchd — a user LaunchAgent plist running php artisan queue:work
Linuxsystemd — a .service unit with Restart=always
WindowsNSSM — wraps the command as a native Windows service
Full copy-pasteable configs for all three are in deploy/LOCAL_SETUP.md inside the codebase.

AI Features Setup

AI is off by default for every feature. The system works completely without it — nothing needs to be configured unless you want AI features specifically.
1

Get an API key

From platform.openai.com or console.anthropic.com — pick either provider, per feature.

2

Enable from the admin panel

Go to Business Owner Panel → AI Settings. Flip the master switch on, then enable individual features and paste in an API key for each. Keys are encrypted before they're stored.

3

Verify it's working

Try the AI invoice generator from the invoice builder, or check the dashboard's financial insights card if that feature is on.

After Registering

There are no pre-seeded demo logins — registering at /register creates your tenant, your first business, and an owner account together, then walks you through a 3-step onboarding wizard (add a client → add a product/service → create your first invoice).

👑 Owner Account

Created via/register
Roleowner
Redirects to/onboarding

💼 Client Portal

AccessSigned link
PasswordNone needed
Sent viaInvoice email

Shared Hosting Deployment

1

Upload via FTP / File Manager

Upload the entire project to your server (e.g. public_html/billing/).

2

Set APP_URL

APP_URL=https://yourdomain.com/billing/public
3

Run via SSH

composer install --no-dev --optimize-autoloader php artisan key:generate php artisan migrate --seed php artisan config:cache php artisan route:cache
4

Fix permissions

chmod -R 775 storage/ public/uploads/ bootstrap/cache/
PHP-FPM hosts: upload size limits need to be set in your hosting control panel's PHP settings, not just .htaccess.

Troubleshooting

  1. Confirm public/uploads/ is writable (chmod 775).
  2. Check APP_URL in .env — don't include /public if your document root already points there.
  3. Clear config cache: php artisan config:clear.
  1. Confirm both the master switch and the specific feature are ON in AI Settings.
  2. Verify the API key is saved and valid with your provider.
  3. Check storage/logs/laravel.log for the exact error.
  4. Ensure the curl PHP extension is enabled.

This almost always means the cron entry for php artisan schedule:run was never added — see "Two Background Processes You Must Run" above. Nothing in this app polls on its own.

The queue worker (php artisan queue:work) isn't running. Set it up as a native service (launchd/systemd/NSSM) so it survives reboots.

  1. Temporarily set APP_DEBUG=true to see the real error.
  2. Check storage/logs/laravel.log.
  3. Confirm vendor/ exists — run composer install.
  4. Confirm storage/ and bootstrap/cache/ are writable.

Confirm the gateway's webhook URL is registered in that gateway's dashboard and points at /webhooks/payments/{gateway} on your live domain — webhooks can't reach localhost.

Need the full feature reference?

Feature walkthroughs, database schema, and the complete AI feature list are in the documentation.

View Full Documentation →