Common Setup

Travelio — shared configuration for the web app and both mobile apps
Version: 1.0.0 (Stable)
Tech Stack: Laravel 13 · PHP 8.2+ · MySQL 8.0+ · Flutter 3.x
License: Envato Market – Regular / Extended

Developed By: BugBuild Labs

Common Setup

The configuration shared by the web application and both mobile apps. Do these once, after the install, and every part of Travelio behaves the way you expect.

API & Mobile App Connection

The mobile apps read and write through the Laravel REST API at https://yourdomain.com/api/v1. Nothing extra to install — the API ships with the backend and is live as soon as the site is.

Point the app at it in lib/services/urls.dart, or pass the host at build time:

flutter run --dart-define=API_HOST=https://yourdomain.com
EnvironmentAPI_HOST
Live serverhttps://yourdomain.com
Physical Android phone on your LANhttp://<your-computer-ip>:8000
Android emulatorhttp://10.0.2.2:8000
iOS simulator / desktophttp://127.0.0.1:8000

Check it quickly in a browser — the API should answer, not 404:

https://yourdomain.com/api/v1/home

For local testing over the LAN, run the backend as php artisan serve --host=0.0.0.0, otherwise it only listens on localhost and the phone cannot reach it.

Mail (SMTP)

Mail drives password resets, booking confirmations and OTP codes on the website, the portals and both apps. Nothing email-related works until this is set.

Set it in .env, or from Settings → Mail in the admin panel:

MAIL_MAILER=smtp
MAIL_HOST=smtp.yourprovider.com
MAIL_PORT=587
[email protected]
MAIL_PASSWORD=your_password
MAIL_ENCRYPTION=tls
[email protected]
MAIL_FROM_NAME="Travelio"

Port 587 with tls, or port 465 with ssl. Gmail needs an App Password, not your account password. After changing .env, run php artisan optimize:clear.

Queue the mail so users are not left waiting on the SMTP handshake:

QUEUE_CONNECTION=database
php artisan queue:work --tries=3 --timeout=90

reCAPTCHA

Protects the public forms — signup, contact, booking enquiry — from bots.

  1. Create a site at google.com/recaptcha/admin.
  2. Add your domain, and localhost if you test locally.
  3. Paste the site key and secret key into Settings → reCAPTCHA and enable it.

Keep it disabled while you are still testing forms — a wrong key silently blocks every submission.

Social Login

Lets customers sign in with Google or Facebook instead of a password.

  • Google — create OAuth credentials in Google Cloud Console, add the redirect URI https://yourdomain.com/auth/google/callback.
  • Facebook — create an app at developers.facebook.com, add Facebook Login, set the redirect URI https://yourdomain.com/auth/facebook/callback.

Paste the client IDs and secrets into Settings → Social Login and enable the providers you want.

Both providers require the callback URL to match exactly, including https and any trailing slash.

Payment Gateways (online booking payments)

Customers can pay for tour, hotel and transport bookings online from the mobile app and the customer portal. Two gateways are built in, each calling the provider's own REST API (no SDK or plugin):

GatewayCredentials
bKash (Tokenized Checkout)App Key, App Secret, Username, Password
SSLCOMMERZ (hosted checkout — cards, mobile banking, net banking)Store ID, Store Password

Credentials are entered in the admin panel under Settings → Payment Gateways, not in .env, so going live needs no redeploy. Each gateway has a Sandbox switch and an Enable switch: a gateway is offered to customers only when its credentials are filled in and it is switched on.

Every payment goes through a payment_intents record. The provider's redirect and IPN both land on payment/callback/{gateway}/{reference}; nothing in the callback is trusted — the gateway re-validates the transaction with the provider and checks the amount and currency against the intent before the booking is marked paid and the invoice and receipt are raised. A repeated callback is a no-op.

Test each gateway against the provider's sandbox first, then make one small live transaction before announcing online payment to customers. Gateway fees and merchant onboarding are between you and the provider.

With no gateway enabled, bookings are still recorded and paid at the desk (cash, bank, card, mobile banking) or settled from the customer's wallet — exactly as before.

File Storage

Uploads — package photos, passport scans, visa documents, blog images — are written to storage/app/public and served through a symlink:

php artisan storage:link

If your host blocks symlinks, create the link from cPanel's File Manager, or ask support to run the command.

Broken images almost always mean the symlink is missing, or APP_URL in .env does not match the real domain (including https).

Languages

Travelio ships with English and Bangla. Every phrase is editable from System → Language in the admin panel — you do not need to touch the translation files.

To add a language: create it on that screen, then translate the phrase list. Users switch language from the top bar; the mobile apps follow the same setting.

Right-to-left languages (Arabic, Urdu) are supported by the layout.

Database Backups

Settings → Database Backup takes a backup on demand and lets you download it. To have backups run on their own, make sure the scheduler cron is installed:

* * * * * cd /home/youruser/yourapp && php artisan schedule:run >> /dev/null 2>&1

Download backups off the server regularly. A backup that only exists on the machine it is backing up is not a backup.

Go-Live Checklist

Check
APP_DEBUG=false and APP_ENV=production in .env
APP_URL matches the real domain, with https
Every demo account password changed, unused accounts deleted
SSL certificate installed and http redirects to https
SMTP configured and a test email actually received
Queue worker or the scheduler cron running
Agency name, logo, favicon, currency and timezone set
Demo content replaced with your own pages, packages and sliders
Payment gateway credentials entered and taken out of sandbox
reCAPTCHA enabled on the public forms
A database backup taken and downloaded off the server
Mobile apps rebuilt against the live API_HOST, with your own package ID
php artisan optimize run after the final .env change