Setup & deployment
This guide walks through installing esimScan locally and preparing it for production.
Prefer a browser-based setup? After uploading the code and creating an empty database, you can run the web installer at
/install— it checks requirements, tests the database, creates your admin account, runs migrations, and optionally imports demo data, no command line needed. The manual steps below reach the same result.
Production deployment
For production installs (builds, queue worker, scheduler, Nginx, SSL):
- Production deployment overview — builds, root
.env, PHP-FPM, queue/scheduler, hosting - Deployment on aaPanel — full aaPanel walkthrough (PHP, MySQL, Nginx, queue worker, Let’s Encrypt)
- aaPanel quick reference — paths, commands, checklist
The repository also ships README.md (overview & install), README_DEPLOYMENT.md (production), and docs/ESIM_GUIDE.md — the guides on this site are the maintained, web-friendly versions aligned with the current codebase.
Prerequisites
- PHP 8.2 or newer (with the usual Laravel extensions:
pdo_mysql,mbstring,openssl,bcmath,ctype,fileinfo,tokenizer,xml,curl,gd/imagick) - Composer 2
- Node.js 18+ and npm
- MySQL 8+ (or SQLite for quick local runs)
- Git
Optional: Redis (for cache/queue; esimScan falls back to the database when Redis is absent).
1. Clone and install
git clone <repository-url>
cd eSim-Scan
composer install
npm install
2. Environment file
Configuration lives in a single .env file at the repository root. Copy the template and generate the app key:
cp .env.example .env
php artisan key:generate
On Windows PowerShell use Copy-Item .env.example .env.
Keep
APP_KEYstable. Provider API credentials (Airalo, eSIM Access, etc.) are stored encrypted in the database. ChangingAPP_KEYafter credentials are saved makes them unreadable.
Required for a working install
| Variable | Purpose |
|---|---|
APP_KEY | Laravel encryption key (set by php artisan key:generate) |
APP_URL | Base URL of the app, e.g. http://localhost:8000 |
DB_CONNECTION, DB_* | Database connection (see Database below) |
Strongly recommended
| Variable | Purpose |
|---|---|
MAIL_* | Outbound email. Required to deliver eSIM/QR emails — without an active mail config, orders still fulfill but no email is sent (it is logged, never breaks checkout). SMTP can also be managed in Admin → Email System. |
ESIM_PROVISIONING_DRIVER | How a paid order becomes a delivered eSIM: manual (default), stub, or live. See eSIM fulfillment. |
APP_DEMO_MODE | When true, blocks all create/update/delete in the admin back-office so visitors can explore safely. See Demo mode. |
Optional
| Variable | Purpose |
|---|---|
CACHE_STORE, QUEUE_CONNECTION | Set to redis when Redis is available; otherwise leave as database. |
OPENAI_API_KEY, ANTHROPIC_API_KEY, DEEPSEEK_API_KEY | Optional fallback keys for the AI assistant (eSIM Advisor + support reply drafting). Normally set in Admin → AI Settings (encrypted), which takes priority. See the AI assistant guide. |
STRIPE_*, PAYPAL_* | Storefront checkout payment credentials (can also be configured in Admin → Payment Gateways). |
MASTER_ESIM_SYNC_MAX_SECONDS | Time budget for provider catalog syncs (default 1800). |
Vite only exposes variables prefixed with VITE_ to the browser.
3. Database
MySQL (recommended)
Create a database and set DB_* in .env:
CREATE DATABASE esim CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=esim
DB_USERNAME=root
DB_PASSWORD=
SQLite (quick local)
DB_CONNECTION=sqlite
Then create the file: touch database/database.sqlite (PowerShell: New-Item database/database.sqlite -ItemType File).
Run migrations and seeders
php artisan migrate --seed
Seeding creates roles, permissions, the default admin and customer accounts, demo destinations, catalog, and orders.
Default demo logins (change in production):
| Side | URL | Password | |
|---|---|---|---|
| Admin back-office | /admin/login | admin@spagreen.net (or ADMIN_SEED_EMAIL) | 123456 (or ADMIN_SEED_PASSWORD) |
| Customer account | /login | client@spagreen.net (or CUSTOMER_SEED_EMAIL) | 123456 (or CUSTOMER_SEED_PASSWORD) |
| Storefront | / | (guest checkout — no login required) | — |
4. Build the frontend
npm run dev # development (Vite dev server with HMR)
# or
npm run build # production assets
5. Multilingual (i18n)
Translations are stored in resources/js/locales/{code}.json (e.g. en.json, bn.json, ar.json, hi.json) and served via GET /i18n/{locale}.
After migrations, seed the default languages and their JSON files:
php artisan i18n:seed-defaults
This seeds four locales (English, Bangla, Arabic, Hindi) and creates/updates the JSON files. Adding a new language in Admin → Languages creates a new {code}.json (copied from English). To pull new keys discovered from t('...') calls in JS/Blade:
php artisan i18n:scan --sync
RTL locales (e.g. Arabic) flip the layout automatically. i18n dictionary responses are cached (Redis or file).
6. eSIM fulfillment mode
A paid order becomes a delivered eSIM according to ESIM_PROVISIONING_DRIVER:
| Mode | What happens | When to use |
|---|---|---|
manual (default) | The order waits; staff enter the eSIM details (activation code / QR) and deliver from the panel. No provider account needed. | Getting started, or selling eSIMs you source manually. |
stub | The system auto-generates realistic demo eSIM data instantly and emails it. Not a real eSIM. | Demos and evaluation. |
live | The system calls the connected provider API to auto-issue a real eSIM on payment. | Production with provider credentials configured. |
Related settings:
ESIM_PROVISIONING_DRIVER=manual # manual | stub | live
ESIM_AUTO_PROVISION=true # attempt provisioning on successful payment
ESIM_SEND_DELIVERY_EMAIL=true # email the QR + details when an order is fulfilled
The current mode is shown as a badge on the Admin dashboard. If live provisioning fails, the order is flagged failed and can be fulfilled manually — nothing is lost.
7. Demo mode
If APP_DEMO_MODE=true in .env, all create/update/delete requests in the admin back-office are blocked (403 / redirect with an error). Login and logout still work, and a banner is shown. Use demo mode for public demo deployments where you want to prevent any data changes.
8. Run
php artisan serve
Open http://localhost:8000:
- Storefront:
/ - Customer account:
/login→/account - Admin:
/admin/login→/admin
For background work (eSIM provisioning, emails, catalog syncs) in development, also run the queue worker:
php artisan queue:work
9. Production checklist
- Set a strong, unique
APP_KEY(and never change it once provider credentials are saved) - Set
APP_ENV=productionandAPP_DEBUG=false - Set
APP_URLto your real HTTPS domain - Configure mail (or Admin → Email System → SMTP) so eSIM delivery emails send
- Run
npm run build; serve over PHP-FPM + Nginx (see Production deployment) - Run a queue worker and the scheduler as persistent processes
- Ensure
storage/andbootstrap/cache/are writable by the web user
10. Troubleshooting
- Cannot connect to database: Confirm MySQL is running, the database exists, and
DB_*matches user, password, host, and port. 500after deploy: Checkstorage/logs/laravel.log; ensureAPP_KEYis set andstorage/is writable.- eSIM emails not arriving: Confirm an active SMTP config (Admin → Email System),
ESIM_SEND_DELIVERY_EMAIL=true, and that the queue worker is running. - Catalog is empty: Connect a provider and Sync (Admin → eSIM Providers), or run
php artisan db:seedfor demo data. - Provider credentials stopped working:
APP_KEYlikely changed — re-enter the credentials.
Documentation site (this site)
To run these docs locally with VuePress, from the docs folder run npm install and npm run dev (default URL http://localhost:8080). To build static files for production, run npm run build and deploy the docs/.vuepress/dist output (for example to docs.yourdomain.com).