Travelio App

One Flutter app for Android & iOS — customer, agent, tour guide and staff in a single build
App version: 1.7.0 (Stable)
Tech Stack: Laravel 13 · PHP 8.3+ · MySQL 8.0+ · Flutter 3.x
License: Envato Market – Regular / Extended

Developed By: BugBuild Labs

Overview

The Travelio App is a native Flutter app for Android and iOS. It is one app, not several: after sign-in it reads the account's role and opens the matching experience — customer, agent, tour guide or staff. There is one codebase to configure, one package ID to set, one binary to sign and one listing to publish.

RoleWhat the app opens
CustomerBrowse and request tours, hotels, flights and transport; apply for visas and track them; register for Hajj & Umrah; pay online or by bank transfer; use promo codes and loyalty points; track bookings, invoices and the wallet. See Customer Role.
AgentOwn production only — create bookings for clients, customers brought in, commission, wallet and withdrawals, invoices and reports. See Agent Role.
Tour guideAssigned tours with start / complete actions. See Tour Guide Role.
StaffSigns in with the same build and gets a customer-style shell (Home, Explore, Services, Profile); the panel remains the main workspace. See How the Role Is Decided.

The app runs against the same backend and database as the admin panel, so anything done in the app appears instantly in the panel and vice-versa.

Setup is shared. Requirements, source layout, API host, branding and release build are identical for every role, so they are documented once under Getting Started below. Only the screens differ per role.

Scope of the app. Travelio is a travel-agency ERP with a companion mobile app: customers send booking and fare requests that your team prices and confirms, agents sell on behalf of clients, and the agency's own rules (gateways, loyalty, policies) live in the admin panel. It is not a self-service marketplace that confirms live inventory on its own.

Role scoping is enforced on the server, not in the app. An agent cannot reach another agent's bookings or customers even by crafting a request.

Requirements

ToolVersion
Flutter SDK3.x (Dart SDK 3.12+)
Android Studio / VS CodeLatest, with the Flutter and Dart plugins
Android SDKAPI 24+ (Android 7.0 and above)
Xcode (iOS builds only)15+ on macOS; the app targets iOS 15.0 and above (Podfile)
A running Travelio backendInstalled and reachable over the network

Verify your toolchain before opening the project:

flutter --version
flutter doctor

Package & Source Code

Try it before you build. One APK is linked from the item description on CodeCanyon — there is a single build, so install it once and sign in with either account to see both experiences:

[email protected] / 12345678  →  the customer experience
[email protected] / 12345678  →  the agent dashboard

Sign out and back in with the other account to switch. The APK points at our demo server, so it needs no setup of yours.

The Flutter source is in AppSourceCode/ inside Main_Files.zip — one project, covering every role. There is no second project and no second APK: an account with the Agent role simply lands on the agent dashboard instead of the customer home screen. Open the folder and pull the dependencies:

cd AppSourceCode
flutter pub get
flutter run

The layout that matters:

lib/
├─ main.dart              App entry point
├─ screens/               Customer screens, plus agent/ and guide/
├─ controllers/           GetX controllers — one per feature
├─ services/urls.dart     API base URL and every endpoint (host comes from env/*.json)
├─ models/                Response models
├─ widgets/               Shared UI components
└─ utils/                 Theme, colours, image paths, helpers
assets/images/            App images and illustrations
assets/fonts/             Kumbh Sans font family
env/                      API host and keys per environment
test/                     flutter test: SVG assets, brand logo, bank transfer

App Configuration (API URL)

The app talks to your Laravel backend over /api/v1. You do not edit Dart code to set it — the host lives in an environment file, so the same source builds against a local server or a live one:

env/
├─ dev.json     <-- your machine while developing
├─ prod.json    <-- your live server; edit this before building for the stores
└─ README.md

Each file holds the host and the app key:

// env/prod.json
{
  "API_HOST": "https://yourdomain.com",
  "APP_API_KEY": "travelio-app-key-7c2e9a4d1f8b6035",
  "GOOGLE_SERVER_CLIENT_ID": "",
  "FACEBOOK_APP_ID": "",
  "FACEBOOK_CLIENT_TOKEN": ""
}

If a file is missing, copy the matching template (env/dev.example.json, env/prod.example.json) — the real files are normally kept out of version control.

KeyMeaning
API_HOSTBackend base URL, required. No /api/v1 suffix.
APP_API_KEYSent as the X-App-Key header on every request. An empty value sends no header, which is only right when the key check is switched off in the panel.
GOOGLE_SERVER_CLIENT_ID, FACEBOOK_APP_ID, FACEBOOK_CLIENT_TOKENPublic identifiers for social sign-in — see Social Sign-in Keys. Leave empty if you do not offer social login.

APP_API_KEY is the shared X-App-Key the app sends on every request. It ships with the same fixed value a fresh backend seeds under Settings → API Security, so a new install and a stock build work together with nothing to configure. Only change it if you press Generate in that settings page — then put the new key here and rebuild; otherwise every request answers 401. The key ships inside the app and can be extracted, so it is a filter against casual scraping and a rotation kill-switch, not authentication — real access control is the login token.

Pass the file to Flutter when you run or build:

flutter run --dart-define-from-file=env/dev.json

flutter build apk       --release --dart-define-from-file=env/prod.json
flutter build appbundle --release --dart-define-from-file=env/prod.json
flutter build ipa       --release --dart-define-from-file=env/prod.json

--dart-define-from-file is built into Flutter — there is no package to install, and the value is compiled in rather than shipped as a readable file inside the APK. A single --dart-define=API_HOST=https://yourdomain.com still works if you prefer it.

Do not include /api/v1 in the value; the app appends it. A plain flutter run in debug needs no flag: it falls back to 10.0.2.2:8000 on an Android emulator and localhost:8000 elsewhere. A release build never falls back to localhost; with no env file it uses the placeholder https://your-domain.com, so always pass env/prod.json. Each request times out after 12 seconds.

Where you run itHost to use
Live serverhttps://yourdomain.com
Physical Android phone on your LANhttp://<your-computer-ip>:8000 — and start Laravel with php artisan serve --host=0.0.0.0
Android emulatorhttp://10.0.2.2:8000
iOS simulator / desktophttp://127.0.0.1:8000

127.0.0.1 inside an Android emulator means the emulated phone itself, not your computer — that is why every list comes back empty if you leave it as the default. Use 10.0.2.2 on the emulator and your LAN IP on a real device.

On a live server always use https. Plain http to a public domain is blocked by default on both Android and iOS unless you weaken the platform network settings — do not.

Social Sign-in Keys (Google & Facebook)

The login buttons appear only when the provider is enabled under Settings → Social Login in the admin panel (the app asks the server for the enabled flags). The app uses the native Google / Facebook sign-in and exchanges the result with your server, so the secrets stay on the server; the app carries only public identifiers. The web redirect URIs described in Common Setup are for the website, not the app.

Google

  • In the same Google Cloud project, create an Android OAuth client (package com.bugbuild.travelio, or your own ID, plus the SHA-1 of your signing key), an iOS client for the bundle ID, and keep the Web client.
  • GOOGLE_SERVER_CLIENT_ID = the Web client ID (….apps.googleusercontent.com). If you leave it empty the app uses the web client ID your server publishes (Settings → Social Login → Google client ID). Android cannot return an ID token without one of the two.
  • iOS: in ios/Runner/Info.plist replace GIDClientID with the iOS client ID and REPLACE_WITH_GOOGLE_REVERSED_CLIENT_ID (a URL scheme) with its reversed ID.

Facebook

  • FACEBOOK_APP_ID and FACEBOOK_CLIENT_TOKEN (Meta console → Settings → Advanced; the client token, not the App Secret). Android reads them at build time from the env file; with nothing set, Facebook login reports a configuration error instead of crashing.
  • iOS: in ios/Runner/Info.plist replace FacebookAppID, FacebookClientToken and the fbREPLACE_WITH_FACEBOOK_APP_ID URL scheme (fb + the App ID).

If you change the package / bundle ID, update it in the Google and Facebook consoles too, and add the signing certificate of every build you test with (debug, upload key and, if you use Play App Signing, Google's app-signing key).

App Name, Package ID & Icon

App name — Android: android/app/src/main/AndroidManifest.xml → android:label="Travelio". iOS: ios/Runner/Info.plist → CFBundleDisplayName.

The logo comes from the website, not the app. Whatever you upload under Settings → General → Logos & Favicon in the admin panel is what the app shows — on the splash screen, the onboarding slides and every sign-in screen. One brand, one place to change it, and no rebuild needed.

Two backgrounds, two files. The app draws its logo on white screens (splash, onboarding, OTP) and on the coloured sign-in header. A dark wordmark on that header is unreadable, so upload a white or light version for the dark slot and your normal full-colour one for the light slot. The app never substitutes one for the other — a wrong-contrast logo looks broken, so it shows your agency name instead.

Want different artwork in the app than on the website? Settings → General → App Branding has two optional slots — App Logo (light backgrounds) and App Logo (coloured header). Fill either and the app uses it; leave them empty and the app falls back to the website Light and Dark logos, so there is nothing to configure unless you want app-specific branding.

The app ships no logo of its own. There is no image file in the package to replace and nothing to rebuild — every logo the app draws is fetched from your admin panel. If none has been uploaded, the sign-in header falls back to your agency name as text and the splash screen stays blank until one is set. That is deliberate: a missing upload should be obvious rather than silently replaced with someone else's mark. Uploading a logo is the first item on the go-live checklist.

Visible version text. The Profile menu and the Settings screen show appVersion from lib/utils/app_version.dart; when you change version: in pubspec.yaml, change it there too (the part before the +). The Android app name is set in the manifest label and in res/values/strings.xml (app_name); on iOS also FacebookDisplayName in Info.plist if you use Facebook login.

Package / bundle ID — ships as com.bugbuild.travelio. Change it to your own before publishing:

  • Android — applicationId (and namespace) in android/app/build.gradle.kts; also update the Google and Facebook consoles (see Social Sign-in Keys).
  • iOS — open ios/Runner.xcworkspace in Xcode → Runner target → Signing & Capabilities → Bundle Identifier.
  • The travelio:// link scheme used to return from a payment page is registered in both the Android manifest and Info.plist; it does not depend on the package ID and should be left alone.

App icon — replace the icon sets:

  • Android — android/app/src/main/res/mipmap-*/ (one image per density).
  • iOS — ios/Runner/Assets.xcassets/AppIcon.appiconset/.

Colours and fonts — the theme lives in lib/utils/; the bundled font family is Kumbh Sans, declared at the bottom of pubspec.yaml.

Change the package ID before your first Play Store or App Store upload. It cannot be changed after the app is published.

Want a separate listing for agents? It is not required — one listing serves every role, and that is how Travelio is meant to ship. If your business really needs a second store entry, use Flutter build flavors rather than copying the project: one codebase, a second applicationId, two listings. Two builds installed on one device must have different package IDs, or one overwrites the other.

Build & Release

Debug builds need no keystore — plug in a device and run (a real phone needs your server address, see the table above):

flutter pub get
flutter run --dart-define-from-file=env/dev.json

Release builds

flutter build appbundle --release --obfuscate --split-debug-info=build/symbols --dart-define-from-file=env/prod.json   # .aab — Google Play
flutter build apk       --release --obfuscate --split-debug-info=build/symbols --dart-define-from-file=env/prod.json   # .apk — direct install
flutter build ipa       --release --dart-define-from-file=env/prod.json          # iOS — macOS with Xcode only

1. Sign with your own key (Android). A release build refuses to run until android/key.properties exists — there is no silent fall-back to the debug key, because Google Play rejects a debug-signed upload. Debug builds and flutter run need no keystore.

# once: generate a keystore and keep it safe — losing it means you can never update the app
keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

# then: copy android/key.properties.example to android/key.properties and fill in
storeFile=/absolute/path/to/upload-keystore.jks
storePassword=your-keystore-password
keyAlias=upload
keyPassword=your-key-password

Never commit key.properties or the .jks file — both are already in android/.gitignore. Verify a built APK with keytool -printcert -jarfile app-release.apk.

2. Shrinking and obfuscation. Release builds run R8 (isMinifyEnabled, isShrinkResources, rules in android/app/proguard-rules.pro). --obfuscate --split-debug-info=build/symbols additionally renames Dart symbols. Keep the build/symbols folder of every build you publish — it is the only way to read a crash report from that build.

3. Your own identifier. Change the package / bundle ID from com.bugbuild.travelio before the first store upload — see App Name, Package ID & Icon. It cannot be changed after publishing.

4. Push notifications (optional). Firebase is wired in but switched off until you add your own project files: android/app/google-services.json and ios/Runner/GoogleService-Info.plist from the Firebase console. Without them the app builds and runs normally, just without push. On the server, paste the Firebase service-account JSON under Settings → Push Notifications and switch it on. After login the app registers the phone's FCM token with your server and removes it again on logout; booking, payment and visa updates are then mirrored to the phone. The app asks for notification permission on first launch (Android 13+ included). Foreground pushes show as an in-app banner. On iOS also enable the Push Notifications capability and upload your APNs key to Firebase.

5. iOS. The deployment target is iOS 15.0. The Face ID, camera and photo-library usage texts are in Info.plist. On a Mac, open ios/Runner.xcworkspace, set your team and bundle identifier under Signing & Capabilities, run flutter build ipa --release, then upload the archive from Xcode (Product → Archive → Distribute) or Transporter to App Store Connect and test through TestFlight. Apple and Google developer accounts and their fees are yours.

Before you uploadWhere
Point the app at your live HTTPS APIApp Configuration — env/prod.json
Set your own package / bundle identifierApp Name, Package ID & Icon
Set the app name and launcher iconApp Name, Package ID & Icon
Configure push, if you want itStep 4 above
Bump version: in pubspec.yamlStores reject a build number that was used before
Sign with your own release keyStep 1 above
Keep build/symbols for this releaseStep 2 above

Customer Role

What a signed-in customer sees. Same build, same configuration as above — only the screens below are role-specific.

Onboarding, Sign Up & Login

First launch shows a splash screen (your logo from the admin panel), a short onboarding carousel (Skip / Next) and a welcome screen with Login and Sign up. There is no guest mode: a traveller has to sign in or register before the home screen opens. On later launches a stored session goes straight to the right home screen.

Sign up — Welcome → Sign up

FieldNotes
Full nameRequired.
EmailRequired by the server — the verification code is emailed, so an account without an address could never be verified or recovered. Must be unique.
PhoneCountry picker (defaults to Bangladesh). Stored in international format; unique, and usable later as a login identifier.
Password / Confirm passwordAt least 6 characters.
GenderMale / Female / Other — required.
Date of birthOptional; must be between 10 and 100 years ago.

Registering does not sign the traveller in. The server creates a customer account and emails a 6-digit code (valid for 10 minutes); the Verify OTP screen takes it, and a correct code is what logs the traveller in. Resend OTP issues a fresh code. The account then appears in the admin panel under Customers.

Login

  • Email or phone + password — one box accepts either. The server checks customer accounts first, then staff/agent/guide users. The returned account type decides which experience opens (see How the role is decided).
  • Continue with Google / Continue with Facebook — native sign-in. Each button appears only when that provider is enabled in the admin panel (Settings → Social Login); the app asks the server which are on. The provider credential is exchanged once for a normal Travelio session; cancelling the provider screen simply returns to Login. Build-time values (GOOGLE_SERVER_CLIENT_ID, FACEBOOK_APP_ID, FACEBOOK_CLIENT_TOKEN) are covered under Social sign-in keys.
  • Forgot password — enter the account email; a 6-digit code is emailed (valid 10 minutes); enter the code and a new password (min. 6 characters, confirmed). Then log in. This recovery flow looks up customer accounts only; an agent, guide or staff password is reset by an administrator in the panel.
  • Change password — Profile → Change Password: current password, new password, confirm, with a Show passwords switch. Minimum 6 characters.
  • Session — the token is kept in the device's secure storage (Keychain / EncryptedSharedPreferences). If the server answers 401 the session is cleared and the app returns to onboarding. Logout (Profile → Logout) also unregisters the device for push.

The verification and reset codes go out through the SMTP settings configured in the admin panel (Mail setup). If mail is not configured, the code never arrives and nobody can finish registering.

Onboarding
Onboarding
Welcome
Welcome
Sign up
Sign up
Login
Login
Forgot password
Forgot password
OTP by email
OTP by email
Change password
Change password

Home, Explore & Services

A customer's bottom navigation has five tabs: Home, Explore, Services, Bookings and Profile.

The app follows Settings → Modules. Each time it opens, the app reads which services the agency offers (/settings → modules). A switched-off module's tab, home shortcuts, rails, Services entries and menu items are hidden — for example with Tours off the Explore tab disappears and Home opens on the Hajj & Umrah rail. No new build is needed. See Modules.

  • Home — greeting with the traveller's name and a notifications bell; a search box; four summary cards (Bookings, Upcoming, Wallet balance, Visa count — the same counters as the customer web portal, each tapping through to its screen); the hero slider; a Special Offers carousel (your Promotions set to show in the app — tapping one opens the tour, Hajj/Umrah package, visa services, hotel or link it points to); a Services row (Tours, Hotels, Flights, Transport, Visa, Track Visa, Hajj, Umrah); tour categories; Featured Tours (packages you marked Featured come first, with a badge); a Hajj & Umrah rail (featured first); and Latest Tours. Sliders, promotions, categories and packages are whatever you publish in the admin panel.
  • Explore — search and filter tour packages (filter by category, sort by Newest, Price low-to-high or Price high-to-low). At the bottom, Plan my custom trip opens the Custom Tour Request form (From, To, departure and return date, travellers, name, phone, email, details); it is sent to your team as a service enquiry.
  • Services — the full menu in four groups: Travel (Tours, Hotels, Flights, Transport), Visa (Visa Services, Track Visa), Hajj & Umrah, and Help (Contact Us, Support, Help & FAQ).
Home
Home
Explore
Explore
Services
Services

Tours, Flights, Hotels & Transport

The customer app is built around requesting trips: tours, hotels and transport create a booking that your staff confirm in the admin panel, and flights are fare requests that your desk prices. Online payment is a separate step — see Paying for a booking.

Tours — Home / Explore → a package

  • The detail screen shows the gallery, price, duration, Overview, What's included, Not included, Day-by-day itinerary, Your tour guide (when one is assigned), Departures, Traveller reviews (with any reply from your team) and You may also like. Ask a question (headset button) opens Contact Us with this tour already mentioned in the message.
  • Book Now opens the Request booking sheet: full name and phone (required), email, travel date (required), number of travellers, Promo code, Redeem points (only when the customer has enough points) and an I need visa assistance for this trip tick-box. Submitting creates a booking with a reference such as the one shown in the confirmation message; it starts as pending and your team confirm it. No payment is taken at this step.
  • Promo code and points. Every change asks the server for a fresh quote (POST /bookings/quote) from the same code that will write the booking, so the total shown is the total charged. If a quote request fails the sheet keeps its last good total; the booking is priced again on submit. A code that cannot be used (unknown, expired, used up, below its minimum spend) never blocks the booking — it is priced without the discount and the reason is shown under the box. If a discount falls away between quote and save (the last use of a code going to someone else), the confirmation says so. Points: Use max fills in the most that can be spent; points cover at most the share of the trip price set by your loyalty rules.

Hotels — Services → Hotels (tabs Stays and My Bookings)

  • Search by destination (city, country or hotel name) and star rating; featured stays are listed first. Open a hotel for its description, rooms and rates.
  • Book a room: choose check-in and check-out; the number of nights and price are calculated, then Confirm Booking reserves the room as pending.
  • Enquire sends a tailored-quote enquiry instead (destination, hotel preference, dates, guests, name, phone, email, details). No payment is needed to enquire.
  • Every stay that is not cancelled shows a downloadable hotel voucher in My Bookings.

Flights — Services → Flights (tabs Fare Deals and My Requests)

  • Fare Deals lists the routes and fares you publish. Book on a deal, Search flights, or Request opens a request form: from, to, departure, optional return, travellers, name, phone, email, details (cabin, airline, baggage). It is sent as an enquiry and your desk replies with a quote.
  • My Requests lists the customer's flight requests with status; once the desk has issued a ticket (a PNR is recorded), an e-ticket PDF can be downloaded from My Bookings.
  • Live fares — in the flight search sheet, Live fares searches every flight provider you enabled under Settings → Flight API (Amadeus, Sabre, Travelport, Duffel, TBO Air, Kiwi.com). Each offer shows the price, airline, times, stops and the provider. Picking one opens the request form with the fare details filled in, so your desk confirms and tickets it as usual. With no provider configured a message explains it and Request fares still works.

Transport — Services → Transport (tabs Services and My Bookings)

  • Types are Bus, Train, Launch, Car and Airport (taken from the server, which can change the list). Book now on a service, or Book for a free-form request: type, route, preferred vehicle, date.
  • Quick transport enquiry (pickup, drop-off, date, vehicle, contact details) asks for a quote without booking.
  • In My Bookings a transport booking shows Pay Now while it is payable, and Cancel.
Tour packages
Tour packages
Tour details
Tour details
Flights
Flights
Hotels
Hotels
Transport
Transport

Paying for a Booking

My Bookings → a booking → Pay Now, and the same Pay Now button on a hotel stay or a transport booking. The button shows the amount and opens Choose a payment method with eight options:

MethodWhat happens
bKash, JazzCash, Easypaisa, CardIf your agency has that gateway switched on and its credentials filled in (Settings → Payment Gateways), the app opens the provider's hosted checkout in the phone's browser. The money is taken on the provider's page, so the app never sees card or wallet details. When the payer finishes, the result page returns to the app through the travelio://payment-result link, the booking lists refresh by themselves, and a Payment confirmed or Payment not completed message appears. The booking is marked paid by the provider's confirmed callback, not by the app. Card uses SSLCOMMERZ.
Bank transferOpens the bank-transfer sheet (below). Nothing is marked paid until your team verifies the transfer.
Wallet, Cash, Nagad, or any gateway that is not switched onRecorded as a payment claim: the customer is declaring a payment and the desk confirms it. The app says “We will confirm it shortly”. A wallet claim is refused up front when the balance does not cover the amount.

Bank transfer sheet (new since 1.1.0)

  1. The sheet lists your agency's bank accounts (bank name, account title, account number, IBAN, branch and any instructions you entered). Account numbers can be selected and copied.
  2. The customer sends the money from their own banking app, then fills in: Account you paid into, Transaction / reference number, Payment date and, optionally, Attach payment receipt (a photo from the gallery or camera). Either a reference or a receipt is required.
  3. Submit for verification sends it. The booking now shows payment Pending verification and the Pay Now button is hidden.
  4. Your team checks the proof in the admin panel. If it is rejected the card says “Your last payment could not be verified. Please pay again.” and Pay Now returns.

The bank accounts shown are the ones you maintain in the admin panel; if none exist the customer cannot pick an account to pay into. Test each gateway in its sandbox before enabling it — see Payment gateways. Visa applications and Hajj/Umrah registrations show their payment status in the app but are not paid from it.

Status chips on a tour booking (new since 1.1.0). Beside the main status the card shows two independent chips: Payment (unpaid, pending verification, paid, rejected, ...) and, when your office buys the service from a supplier, Supplier (e.g. pending, confirmed). A booking can be confirmed and paid while its supplier is still pending, so they are tracked separately. Colours are consistent everywhere: green for paid/confirmed/completed, amber for pending/partial/unpaid, red for cancelled/rejected/overdue/failed, blue for information such as refunded.

Cancelling — Cancel on a booking asks for confirmation. A paid booking is refunded to the customer's wallet; the rule that applies comes from Settings → General → Booking Policy.

Visa & Hajj / Umrah

Visa — Services → Visa Services (tabs Destinations and My Applications; a toolbar button opens Track Visa)

  • Destinations — a short “Your visa in 4 simple steps” strip (editable copy from the CMS, visa_steps), then the visa services you publish. Search by country and filter by visa type. Each card shows fee, processing time and a Requirements list, with Apply now.
  • Apply — the Visa Application sheet takes applicant name, destination country and visa type (both required) and creates an application that your team processes.
  • My Applications — each application with status, applied date, appointment date, documents status and visa expiry, plus Track status.
  • Track Visa — Services → Track Visa: enter the reference (for example VISA-3297) to see the live status you set in the admin panel. This lookup is public and works by reference alone; an unknown reference says “No application found”.

Hajj & Umrah — Services → Hajj or Umrah (tabs Packages and My Registrations)

  • Packages — package number, duration, price, seats left, active status and a “Most popular” badge, with an included-services block from the CMS (hajj_includes / umrah_includes). Register now is replaced by Sold out when no seats remain.
  • Register — package preference (Economy, Standard, Premium), number of pilgrims, preferred month, room sharing (Quad, Triple, Double), passport number (required), optional group name, then name and phone (required), email and details. Your team contacts the customer for documents and payment.
  • My Registrations — passport, group, payment status, documents status and package price.
Visa services
Visa services
Visa applications
Visa applications
Track visa
Track visa
Hajj packages
Hajj packages
Umrah packages
Umrah packages
Hajj registrations
Hajj registrations
Umrah registrations
Umrah registrations

My Bookings

The Bookings tab (also Profile → My Bookings) is one list for everything the customer has with the agency, with a filter chip per service and a count on each: All, Tours, Hotels, Flights, Transport, Hajj & Umrah, Visa. Pull down to refresh; the wallet icon in the top bar opens the Wallet.

  • Tour bookings — the full card: reference, package, travel date, travellers, amount, status, the Payment and Supplier chips, and the actions Pay Now (only while the booking is pending or confirmed, unpaid, and not awaiting bank-transfer verification) and Cancel (hidden once cancelled).
  • Other services — a compact card with reference, title, date and amount. Hotel vouchers and flight e-tickets show a download icon once they exist (voucher: any stay not cancelled; e-ticket: once a PNR is recorded).
  • Discount shown per booking — where a promo code or points were used, the original price is struck through and the saving is named underneath (for example “SUMMER20 + 200 points — saved”).
  • Tour guide — when a guide is assigned, the card shows their name and a call button; once the tour is completed, Rate Your Guide takes 1-5 stars and an optional comment.
  • Review this tour — appears once the booking is paid and the travel date has passed, and only for a booking that has not been reviewed yet. The sheet takes a star rating, an optional headline and a comment, and the review carries a verified badge. Afterwards the card shows “Your n★ review is awaiting approval” or “You rated this trip n★”. Reviews are published after your team approves them unless Settings → Integrations → Reviews → auto-approve is on.
Bookings
Bookings
My bookings
My bookings
Booked flights
Booked flights
Booked hotels
Booked hotels
Booked transport
Booked transport

Wallet, Invoices & Documents

  • Wallet — Profile → Wallet: the available balance and the transaction history (credits and debits). It is read-only. There is no top-up button: a customer wallet is funded only by refunds and payments the agency records, never by the customer crediting themselves (the old top-up action was removed in 1.1.0).
  • Invoices & Payments — Profile → Invoices & Payments: tab Invoices (totals for Invoiced and Outstanding; each invoice with number, issue and due dates, amount, status such as paid, partial, overdue or refunded, the amount due, and a Download PDF icon) and tab Payments (total paid; each receipt with number, amount and a Download receipt icon). PDFs are saved and opened with the phone's own viewer.
  • My Documents — Profile → My Documents: files the agency holds for the customer (passports, visas and so on) with counts for Total, Verified, Pending and Rejected. It is read-only; the agency uploads and verifies documents in the panel.

Travelers & Passports

  • Saved Travelers — Profile → Saved Travelers: add, edit and remove people the customer books for (full name, relation such as Spouse, passport number, nationality, date of birth).
  • My Passports — Profile → My Passports: add, edit and delete passports (holder name, passport number, nationality, issue date, expiry date, status Valid / Expiring / Expired).

Points, Rewards & AI Trip Planner

Profile → AI Planner & Rewards (screen title Trip Planner & Rewards).

  • AI itinerary — enter destination, number of days and interests, then Generate AI itinerary. Generated plans are saved and listed underneath. The itinerary is produced by an OpenAI-compatible model that you connect in the admin panel (API key, model and optional base URL); with no key set, generation fails with an error. Each customer can generate up to 10 per minute, and the plan starts the day after the request.
  • Points — balance, referral code, what the points are worth in money, and the earning and redemption history. Points are spent as a discount when booking a tour (the Redeem points box) and never paid into the wallet. Until the customer reaches the minimum, the screen shows how many points are needed and the rate (1 point = amount). The earning rate, redemption rate, minimum to redeem, maximum share of a trip and referral bonus are loyalty settings in the admin panel.

Profile, Notifications, Support & Settings

The Profile tab shows the photo, name and email at the top, then a menu: Edit Profile, My Bookings, Saved Travelers, My Passports, Visa Status, My Documents, Invoices & Payments, Wallet, AI Planner & Rewards, Notifications, Support, Help & FAQ, Contact Us, Become an Agent, Language, App Version, Change Password and Logout.

  • Edit Profile — full name, phone, email and address, plus the profile photo (camera or gallery).
  • Notifications — booking confirmations, payment and visa updates and announcements; tap one to mark it read, or use Mark all read. With push configured (see Push notifications) the same messages also arrive as phone notifications; in the foreground they appear as an in-app banner.
  • Support — New Ticket: describe the issue and choose a priority (Low, Medium, High). The list shows your tickets and status; the same tickets are in the panel under Support Center.
  • Help & FAQ — FAQs grouped by category (uncategorised ones fall under General), from the CMS.
  • Contact Us — agency address, phone, email and WhatsApp (each taps through to the map, dialler, mail or chat) from your general settings, plus a message form (name, email, phone, subject, message) answered by your team.
  • Become an Agent — a form (name and phone required, email and business description optional). It is sent as an application to your admin panel; there is no automatic upgrade, the agency creates the agent account. The entry is shown only while Agent registration is open in Settings → Modules. Visa Status and Support are likewise hidden when their modules are off.
  • Language — English or বাংলা (Bangla), saved on the account (so the web portal agrees) and kept on the device for offline use. The language phrases used on the onboarding, welcome and login screens, and the bottom-navigation labels, come from System → Language → App Language in the admin panel and refresh in the background every 10 minutes; see Language setup. Most other screens are English text compiled into the app. The app does not set its own text direction or locale, so right-to-left layout is not switched on by the language picker.
  • Biometric app lock — More → Settings → Biometric App Lock (shown on phones that support fingerprint or Face ID). Turning it on asks for one successful verification first; afterwards, opening the app with a saved session asks for fingerprint, face or the device PIN. It is a per-device choice and nothing about it is sent to the server. The Settings screen is reachable only from the agent and guide More tab, so the lock switch is available to agents and guides; the customer Profile menu has the Language and Change Password entries directly but no lock switch.
  • Dark mode — not provided; the app has a single light theme.
  • Wishlist — not provided in the app.
Profile
Profile
Notifications
Notifications
Support
Support
Help & FAQ
Help & FAQ
Contact us
Contact us
Become an agent
Become an agent

Agent Role

What a signed-in agent sees in the very same app. Nothing extra to install, configure or publish — the role on the account decides which experience opens (see How the role is decided). An agent works only with their own production; the server scopes every list to that agent.

Agent Sign-in & Access

The agent signs in on the same Login screen with the email or phone and password created for them in the admin panel under Users (a role whose name contains Agent), or set up after approving a Become an Agent application.

While the Agents module is switched off (Settings → Modules), an agent's sign-in is refused with “Agent accounts are currently disabled”. In the agent app, New Booking offers only the services whose modules are on, and Support follows its module.

  • Onboarding and Welcome — the same intro as customers on first launch.
  • Login — the server returns the agent account type and the app opens the agent dashboard. The login screen itself notes that agents and staff sign in here too.
  • Forgot password — the emailed-code recovery works for customer accounts only. For an agent, reset the password in the panel under Users.
  • Change password — More → Settings → Change Password, or Change Password on My Profile.
Onboarding
Onboarding
Welcome
Welcome
Login
Login
Forgot password
Forgot password
OTP by email
OTP by email
Change password
Change password

Dashboard, Bookings & Customers

The agent's bottom navigation has five tabs: Dashboard, Bookings, Customers, Finance and More.

  • Dashboard — a header with the wallet balance and pending commission, then Performance: Total Commission, Pending, Paid and Total Sales, with counts for Bookings, Commissions and My Customers, and the most recent bookings (View all).
  • Bookings — every booking the agent created, with reference, client, travel date, travellers, amount and status. Tap one for the detail screen.
  • New Booking (button on the Bookings tab) — the agent sells on behalf of a client. Pick the service:
    • Tour Package — tour, client name and phone, travel date, travellers.
    • Hotel — hotel and room, client name and phone, check-in and check-out. The price is quoted from the room rate.
    • Transport — type (for Airport: Pickup or Drop), route, optional vehicle and driver, client details. It opens pending and the desk prices the fare.
    • Flight — From and To (airport picker), optional airline, passenger name as it should appear on the ticket, client details. It opens pending and the desk prices it and issues the ticket.
    These use the same actions as the agent portal on the web, so the booking appears in the panel at once.
  • Booking detail — client, phone, email, travel date, travellers, amount and notes; a Billing block (invoice number, status, invoiced and paid) that reads “Not invoiced yet” until the office raises it; and My commission (reference, status, rate, amount), worked out once the booking is paid. While the booking is still pending the agent can Amend booking (new travel date or travellers; the fare is re-quoted from the package) or Cancel booking. Once the office has confirmed it or taken money, those buttons disappear, because unwinding it moves money and reverses a commission.
  • Customers — the customers brought in by this agent: name, phone, email, tier, number of bookings and total spend. The list is read-only; a new customer is created by making a booking for them.
Dashboard
Dashboard
Bookings
Bookings
Customers
Customers

Finance — Commissions, Wallet, Transactions & Invoices

The Finance tab is one screen with four segments, matching what your accounts team sees under Finance → Agent Finance in the admin panel.

  • Commissions — Earned, Pending, Paid out and the agent's average rate, then each commission with its status (Paid or Pending).
  • Wallet — wallet balance, the amount available to withdraw, Withdrawn and Awaiting approval, the list of Withdrawal requests with their status, and the wallet transactions. Request withdrawal: amount, method (Bank, Cash, bKash, Nagad by default; the list comes from the server), where to send it (account or number) and an optional note. The button is disabled with “Nothing to withdraw yet” when nothing is available. The office reviews each request; commission reaches the wallet only after it is approved.
  • Transactions — the full money-movement log.
  • Invoices — invoices raised for the agent's bookings with issue date, due date, amount and settlement status.
Wallet
Wallet
Commission
Commission
Transactions
Transactions
Invoices
Invoices

Reports, Profile & Support

The More tab holds Reports, Support, My Profile, Settings and Logout.

  • Reports — the agent's own Total Sales, Bookings, Commission and Customers, with Bookings by status and Invoices by status breakdowns. There is no date-range picker; the figures cover the agent's whole history.
  • My Profile — name, email, phone, address and photo, with Edit Profile and Change Password.
  • Settings — Edit Profile, Change Password, Language (English or Bangla), Notifications, and the Biometric App Lock where the phone supports it. There is no theme setting.
  • Notifications — the bell in the header; booking updates, commission approvals and announcements.
  • Support — Raise a ticket (description and priority Low, Medium, High). The list shows tickets the agent raised or was assigned, and any that their clients raised; they appear in the panel's Support Center.
Reports
Reports
More menu
More menu
Edit profile
Edit profile
Settings
Settings
Notifications
Notifications
Support
Support

Tour Guide Role

A user whose role name contains Guide, or who is linked to a tour-guide record, opens the guide experience: two tabs, My Tours and More.

  • My Tours — the tours the office has assigned: package photo, title, destination, dates and notes. Start Tour appears when the assignment can be started and marks it in progress; Complete Tour appears once it is in progress. Both ask for confirmation. With nothing assigned it reads “No tours assigned yet”.
  • More — the guide's name and email, Settings (language, password) and Logout.
  • Customers on a guided tour see the guide on their booking card and can rate them after completion (see My Bookings).

Assign guides in the admin panel under Operations → Tour Management; the guide's login is a Users record with a Guide role.

Vendor Role (multi-vendor marketplace)

A user with the Vendor role opens the vendor home. It exists only while the admin has switched the marketplace on (Settings → General → Marketplace); the app learns this from multi_vendor_enabled in /settings. Five tabs:

  • Home — earned, available and held balances, listings awaiting approval, counts per service and the latest earnings. A negative available balance (a refund or penalty after the vendor was paid) is explained and is netted against future sales.
  • Listings — tours, hotels, transport, Hajj & Umrah and visa services. Add listing and edit open a form built from the field definitions the server sends, so new fields appear without an app update; hotels and tours take a photo from the gallery. Every new or edited listing returns to the office for approval.
  • Bookings — tours, hotel stays, transport trips, visa cases and pilgrims of the vendor's services, with Confirm / Decline for tours, stays and trips. Declining tells the office; no money moves from the app.
  • Earnings — available, held, commission (percentage or flat fee), tax withheld, the minimum payout and holding period, Request payout (prefilled from the saved payout account; shows the tax withheld and net), payouts, balance adjustments and the earnings ledger.
  • More — Business profile (contact details, logo, payout method and account), Reviews (read and reply), Settings and Logout.

Customers see the marketplace too: Services → Our vendors (a list and a storefront per vendor with their tours and hotels), and Sold by on a vendor's tour. Customers can also pay a visa fee from Visa Services (Pay on an application).

Languages: the vendor screens are translated into English, Bangla and Arabic (the phrases arrive with the app texts as vendor_phrases; a language without a translation shows English). Photos are sent from their bytes, so picking and uploading works on Android, iOS and web.

Vendors sign up on the website (/become-a-vendor) or through POST /become-a-vendor, then wait for approval. The full settlement rules (commission, holding period, VAT, tax, automatic payouts) are in Common Setup → Multi-Vendor Marketplace.

How the Role Is Decided

The server returns an account_type at login and the app opens:

AccountBecomesApp opens
Row in the Customers table (self sign-up, social login)customerCustomer tabs, including Bookings
User whose role name contains AgentagentAgent dashboard
User whose role name contains Guide, or who is linked to a tour guideguideGuide home (checked before agent)
User with the Vendor rolevendorVendor home (only while the marketplace is on)
Any other user (admin, accountant, ...)staffCustomer-style shell with Home, Explore, Services and Profile only (no Bookings tab). The admin panel stays the working tool for staff.

So an agent whose role is named, for example, “Sales” will land in the staff shell. Name the role so it contains the word Agent. Note the match is on the word anywhere in the role name, so a role such as “Support Agent” also opens the agent dashboard.

What Each Feature Depends On

Most “it does not work” reports are a missing admin-panel setting, not an app fault.

App featureNeeds (admin panel / server)
Every requestMatching API key: Settings → API Security and APP_API_KEY in the app build (App Configuration)
A service's tab, shortcuts and screensIts module switched on in Settings → Modules
Special Offers carouselMarketing → Promotions that are active, in schedule and set to show in the app (Marketing module on)
Live fares (flights)At least one provider enabled and configured in Settings → Flight API
Sign-up code, password resetWorking SMTP (Mail)
Google / Facebook buttonsProvider enabled and keys saved in Settings → Social Login; app-side identifiers in Social sign-in keys
Logo on splash and sign-inSettings → General → Logos & Favicon (optionally App Branding)
Online payment (bKash, JazzCash, Easypaisa, Card)That gateway enabled with credentials in Settings → Payment Gateways
Bank transferAt least one bank account in the panel; staff verify the submitted proof
Promo codesCoupons created and active (Marketing)
Redeem points, referral codeLoyalty settings (earning rate, redemption rate, minimum, maximum share, referral bonus)
Reviews on tour pagesReviews approved by staff, or auto-approve switched on
AI trip plannerOpenAI-compatible API key, model and optional URL in the panel's integration settings
Push notificationsFirebase files in the app and the service-account JSON in Settings → Push Notifications (Push)
Phrases on onboarding / login / tabsSystem → Language → App Language
Contact Us details, currency symbol, app nameSettings → General
Refund on cancelling a paid bookingSettings → General → Booking Policy
Help & FAQ, visa steps, Hajj/Umrah inclusionsCMS (FAQs and content blocks)
Guide assignmentsTour guide assigned to the tour in Tour Management

Not in the app: a vendor/marketplace storefront (the API has public vendor endpoints, but no vendor screens are included), a wishlist, wallet top-up, dark mode, paying a visa application or Hajj/Umrah registration, and live airline fare search.

Release Notes

1.7.0 (needs web 1.7.0 for the new screens; older servers simply hide them)

  • Two-factor sign-in: an account with an authenticator app set up (web Profile → Two-factor sign-in) is asked for its 6-digit code, or a recovery code, after the password or Google/Facebook sign-in.
  • Settings → Currency: show tour, hotel, Hajj, transport, visa, flight, activity and marketplace prices in another currency the agency has a rate for. Bookings, bills and wallets stay in the agency currency, which is what is charged.
  • Card (Stripe) and PayPal appear among the payment methods when the agency switches them on; they open in the browser like the other online gateways.
  • Agent home: credit used against the agency's limit and the commission earned per service. A booking past the limit is refused with the reason. More → Team lets the agency's main account add and remove staff logins.
  • Become an agent: an optional company name and password create a partner account that signs in once approved.
  • Services → Activities: excursions with live dates and places left, adult/child/group prices, guide language and pickup point; booking opens the QR voucher.

1.6.0

  • Live chat with the agency from Support: new messages appear while the screen is open, and a staff reply sends a push notice that opens the chat. Shown only while the agency has live chat switched on (needs web 1.6.0).
  • Messenger on the Contact screen when the agency has added its Facebook page.
  • Signing in with an email that is not verified yet opens the code screen (a new code is emailed) instead of failing.
  • Internal clean-up: large screens split into smaller widgets and unused template files removed — no visible change.

1.5.0

  • Follows the agency's Settings → Modules: hidden tabs (Explore when Tours is off), Home shortcuts, rails, Services groups, profile entries and agent New Booking options for switched-off services. Older servers without the setting show everything as before.
  • Become an Agent shown only while agent registration is open.
  • Special Offers carousel from Promotions, a Hajj & Umrah rail, and Featured badges on tours.
  • Live fares in the flight search sheet, across all enabled flight providers, with the provider on each offer.

1.1.0 – 1.4.0 (the full list per version is in the app project's CHANGELOG.md; the source's pubspec.yaml is at 1.7.0+8):

  • Bank-transfer payment sheet with the agency's bank accounts, reference, payment date and receipt upload; payment status Pending verification and a clear message when a transfer is rejected.
  • JazzCash and Easypaisa alongside bKash and Card (SSLCOMMERZ) as hosted online checkouts; return to the app through travelio://payment-result with automatic list refresh.
  • Payment and Supplier status chips on tour bookings, with one consistent colour scheme for statuses.
  • Promo code and loyalty-points redemption on the tour booking sheet, priced by the server (/bookings/quote); discount shown per booking.
  • Verified reviews (“Review this tour”), traveller reviews on tour pages, and guide rating after a completed tour.
  • Unified My Bookings list with a filter per service, hotel voucher and flight e-ticket downloads, invoice and receipt PDFs.
  • Google and Facebook sign-in; sign-up with an emailed verification code; sign-in by email or phone.
  • Biometric app lock; secure token storage; AI trip planner and points screen; Documents, Passports and Saved Travelers.
  • Agent: create tour, hotel, transport and flight bookings for clients, amend or cancel pending bookings, commission summary, withdrawal requests, invoices, reports. New tour-guide experience (My Tours with start / complete).
  • Services tab and Contact Us, Help & FAQ, Become an Agent, custom tour and enquiry forms.

1.1.0 — 2026-09-10 (changes made after the CodeCanyon review of 1.0.1)

  • Removed the wallet top-up action: the endpoint it called credited money with no payment taken and has been removed.
  • Release builds now fail immediately with a clear message when android/key.properties is missing or incomplete, instead of shipping a debug-signed build that Google Play rejects.
  • R8 shrinking enabled with proguard-rules.pro; --obfuscate --split-debug-info=build/symbols documented.
  • APP_API_KEY defaults to the key a fresh backend seeds under Settings → API Security, so a stock build works with a new install; rotate in the panel, then rebuild.
  • All debug logging removed (the HTTP client used to write every request, response and the auth token to the device log).
  • The packaging script strips build caches and asserts that no build output or debug print survived.

1.0.1 — initial release

  • One app, one login: the account's role opens the customer, agent or tour-guide experience.
  • Browse and book tours, flights, hotels and transport (bus, train, launch, car rental, airport transfer).
  • Visa services, applications and live tracking by reference number.
  • Hajj & Umrah packages with registration, documents and payment progress.
  • My Bookings, profile, travelers, passports, notifications and support tickets.
  • Agent dashboard: sales, commission and wallet balance, customers, finance, reports.
  • Firebase push notifications for booking, payment and support updates (optional).
  • Multi-language, connected to the backend over the REST API.

Troubleshooting

Covers every role — the first rows apply to any sign-in, the last few are agent-specific.

SymptomCause and fix
Every list is emptyThe app cannot reach the API. Check API_HOST in the env file you built with, and confirm https://yourdomain.com/api/v1 answers in a browser.
Works on the emulator, not on a real phoneThe emulator address 10.0.2.2 does not exist on a device. Use your LAN IP or the live domain.
Connection refused on the LANLaravel is bound to localhost. Start it with php artisan serve --host=0.0.0.0 and open the port in your firewall.
Login fails with a valid passwordThe account's role has no portal permission, or the account is suspended — check it under Users in the admin panel.
Images do not loadAPP_URL in the backend .env does not match the real domain.
Reset code never arrivesSMTP is not configured, or the queue worker / cron is not running.
Build fails after changing the package IDRun flutter clean && flutter pub get, and make sure the ID matches in Gradle and in Xcode signing.
Agent logs in but sees the customer app (no Bookings tab)The role name does not contain the word Agent, so the account is treated as staff. Rename or change the role under Users → Roles. See How the Role Is Decided.
Dashboard shows zerosNo bookings are attributed to this agent yet, or the bookings were created without selecting the agent.
Commission looks wrongCheck the agent's commission rate under Finance → Agent Finance → Agents.
Every request fails with 401 / the app keeps returning to the welcome screenAPP_API_KEY in the build does not match Settings → API Security (rotated or regenerated), or the login token expired. Rebuild with the current key.
Sign-up works but no code arrivesVerification codes are emailed. Check the SMTP settings; the account is already created, so Resend OTP once mail works.
Forgot password does nothing for an agent or guideThe emailed-code reset covers customer accounts only; reset staff, agent and guide passwords in the admin panel.
No Google / Facebook button on the login screenThe provider is not enabled in Settings → Social Login.
Google sign-in fails on AndroidNo Web client ID (GOOGLE_SERVER_CLIENT_ID or the server's Google client ID), or the Android OAuth client's package name / SHA-1 does not match the build you installed. See Social Sign-in Keys.
Facebook login reports a configuration errorFACEBOOK_APP_ID / FACEBOOK_CLIENT_TOKEN were empty at build time (Android) or the Info.plist placeholders were not replaced (iOS).
A payment method just says “We will confirm it shortly”That is the normal result for Wallet, Cash, Nagad, Bank and for any gateway that is not enabled with credentials: the payment is recorded as a claim for your team to confirm. Enable the gateway under Settings → Payment Gateways for hosted checkout.
After paying in the browser the app does not come backThe travelio:// scheme is registered in the manifest and Info.plist; make sure neither was removed and that the payment page is the one served by your backend. The booking is still marked paid by the provider's callback; pull to refresh.
Bank transfer sheet shows no accountsNo bank account has been added in the admin panel.
Booking stays “Pending verification”The transfer is waiting for your team to verify the proof; if it is rejected the customer is asked to pay again.
Promo code or points ignoredThe server priced the booking without them: the code is invalid, expired, used up or below its minimum spend, or the points are below the minimum / over the maximum share. The reason is shown under the box.
“Review this tour” missingThe booking must be paid, its travel date must have passed, and it must not already have a review. A submitted review waits for approval unless auto-approve is on.
AI itinerary failsNo OpenAI-compatible API key is configured in the admin panel, or the provider rejected the request.
No push notificationsFirebase config files missing from the build, no service account in Settings → Push Notifications, or notification permission was declined on the phone.
Release build blocked with “key.properties is missing”Expected: create android/key.properties from the example (see Build & Release).
Wallet balance does not match the panelPull to refresh; the app caches the last response until the next fetch.