System Overview & Installation
Everything you need to install, configure, and deploy the MyntCart e-commerce platform and its Flutter mobile applications.
Prerequisites
Server Requirements
PHP 8.3+, MySQL 8.0+, Apache or Nginx, SSL certificate (production), a cron job running every minute, 2GB+ RAM, 10GB+ disk.
PHP Extensions
OpenSSL, PDO, Mbstring, Tokenizer, XML, GD Library, cURL, Fileinfo, BCMath, JSON, Zip, Ctype, Intl, MySQLi.
Detailed Server Requirements
| Requirement | Minimum | Recommended |
|---|---|---|
| PHP | 8.3 | 8.3 or newer |
| MySQL | 8.0 | 8.0 or newer |
| Web Server | Apache 2.4 or Nginx 1.18 | Latest stable |
| RAM | 2 GB | 4 GB+ |
| Disk Space | 10 GB | 20 GB+ (for product images & assets) |
| PHP Extensions | OpenSSL, PDO, Mbstring, Tokenizer, XML, GD, cURL, Fileinfo, BCMath, JSON, Zip, Ctype, Intl, MySQLi | |
| SSL Certificate | Required for production | Let's Encrypt (free) or commercial |
| Cron | One entry running php artisan schedule:run every minute — see Post-Installation | |
The RAM and disk figures are advisory sizing guidance for a growing catalogue. The only figure the installer actually enforces is 500 MB of free disk space, checked before it downloads the application packages.
JSON_TABLE function, which exists only in MySQL 8.0.4 and above and has no equivalent in MariaDB. On an older MySQL or on MariaDB the storefront installs but the shop filters fail.
npm run prod.
Verify your PHP version:
php -v
Installation
How to Purchase a MyntCart License
MyntCart itself is sold in two places, and the installer asks which one you used. The add-on modules are sold only through the CodeMynt licence portal.
Route A — Direct from CodeMynt
Visit the License Portal
Go to https://license.codemynt.in — the official CodeMynt licence portal. Create an account or log in.
Purchase MyntCart License
Select the MyntCart eCommerce CMS package and complete the payment. After purchase, you receive:
- Purchase Key — a licence key in four-character groups, e.g.
XXXX-XXXX-XXXX-XXXX. Paste it exactly as issued. - Buyer Username — the email your portal account is registered to (e.g.
you@email.com) - Project Files — the MyntCart zip, downloadable from the portal
You can find your purchase key anytime by logging into license.codemynt.in → My Purchases. In the installer, choose Direct as the purchase source.
Route B — From CodeCanyon (Envato)
Buy on CodeCanyon and download
Buy MyntCart on CodeCanyon as usual. The project zip is under Downloads on your Envato account.
Get your purchase code
- Purchase Code — on the Envato Downloads page, click Download → License certificate & purchase code. It is the long form, e.g.
8f2e1c40-9b7a-4d31-a5c2-6e0b93f4c118. - Buyer Username — your Envato username, not an email. The licence server checks that the code was bought by that account.
In the installer, leave CodeCanyon selected as the purchase source. Your licence is registered automatically on first verification; you do not need a CodeMynt portal account to install. When you want one — to see the licence, move it to another domain, or buy add-on modules — open Claim your account from the portal's sign-in page, enter your Envato username and purchase code, and choose the email and password you will sign in with.
Pre-Installation — Upload Files to Server
Localhost (WAMP / XAMPP / Laragon)
- Extract the MyntCart zip file
- Copy the project folder to your web server root:
# WAMP C:\wamp64\www\myntcart\ # XAMPP C:\xampp\htdocs\myntcart\ # Laragon C:\laragon\www\myntcart\
- Create an empty database named
myntcartin phpMyAdmin (collation:utf8mb4_unicode_ci) - Open your browser and go to:
http://localhost/myntcart/secure-install
cPanel / Shared Hosting
- Login to cPanel → File Manager → Navigate to
public_html - Upload the MyntCart zip and extract it
- Create MySQL database: cPanel → MySQL Databases → Create DB + User → Add user with ALL PRIVILEGES
- Open your browser and go to:
https://yourdomain.com/secure-install
VPS / Dedicated Server
- Install PHP 8.3+, MySQL 8.0+, Apache/Nginx, and required PHP extensions
- Upload/clone the project to your server (e.g.
/var/www/myntcart) - Point your virtual host / Nginx server block to the
publicdirectory - Set permissions:
chmod -R 775 storage bootstrap/cache - Configure SSL (Let's Encrypt recommended)
- Open your browser and go to:
https://yourdomain.com/secure-install
Create Database & Configure .env
Before running the installer wizard, create the database and configure the environment file.
Create an Empty MySQL Database
Open phpMyAdmin (or cPanel → MySQL Databases) and create a new database. Note down the credentials — you'll need them in the next step and during the installer wizard.
- Open phpMyAdmin (
http://localhost/phpmyadmin) - Click "New" in the left sidebar
- Enter database name:
myntcart - Select collation:
utf8mb4_unicode_ci - Click "Create"
- Login to cPanel → MySQL Databases
- Under "Create New Database" → enter name (e.g.
username_myntcart) → click Create Database - Under "MySQL Users" → create a new user with a strong password
- Under "Add User To Database" → select your user + database → grant ALL PRIVILEGES → click Make Changes
-- Login to MySQL mysql -u root -p -- Create database CREATE DATABASE myntcart CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- Create user (production only) CREATE USER 'myntcart_user'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT ALL PRIVILEGES ON myntcart.* TO 'myntcart_user'@'localhost'; FLUSH PRIVILEGES;
Configure the .env File
In the MyntCart project root, copy .env.example to .env and update the following values with your actual credentials:
.env file must exist before you reach the Database step. The installer writes your database credentials into the existing file — it does not create one. If .env is missing, the Database step fails without a clear error.
# Application APP_NAME="MyntCart" APP_ENV=local # Change to 'production' on live server APP_DEBUG=true # Change to 'false' on live server APP_URL=http://localhost/myntcart # Your domain on live server # Database — match the credentials you just created DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=myntcart DB_USERNAME=root # Your DB username DB_PASSWORD= # Your DB password (empty for localhost) # Leave APP_KEY empty — MyntCart writes one into this file the first time the installer is opened APP_KEY= # Licence signing key — already filled in, in the .env.example you copied. # Leave this line exactly as it came: do not clear it and do not type another value. HMAC_SIGNING_KEY=(as it came in .env.example) # Set to false when you are running on plain http:// (localhost) SESSION_SECURE_COOKIE=false # License — optional here; the installer asks for these on the License step PURCHASE_CODE=your_purchase_code BUYER_USERNAME=your@email.com
.env.example of the package you downloaded, so a .env copied from that file has it. Do not clear the line and do not replace its value: if it is missing, empty or changed, the License and Assets steps of the installer fail, and nothing else you configure will get you past them. If you wrote your .env by hand, copy this one line across from .env.example.
SESSION_SECURE_COOKIE=true, which tells the browser to send the session cookie over HTTPS only. On a http://localhost/... install the cookie is dropped and login appears to do nothing at all. Set it to false locally, and back to true once the live site has SSL.
cpaneluser_myntcart and cpaneluser_dbuser). Use the full prefixed names in .env.
Open the Installer
Now open your browser and navigate to the secure installer URL:
# Localhost http://localhost/myntcart/secure-install # Live server https://yourdomain.com/secure-install
Secure Installation Wizard (Step-by-Step)
The installer opens on a welcome page and then takes you through 6 steps, each on one screen, with the steps listed down the side. Do not close your browser during any step.
Welcome Screen
The welcome page says what the installer is about to do, in three parts:
- Checks your server — PHP version, extensions and folder permissions are checked first
- Verifies your license — your purchase code is confirmed, then the shop's files are fetched for it
- Builds your shop — the database, a demo catalogue and your admin account are set up for you
Under Have these ready it lists what you will be asked for: your purchase code and the user name or e-mail it was bought with, and an empty database with its name, user and password. It usually takes about five minutes in one sitting. Click "Start installation" to proceed.
System Requirements Check
This step is labelled "Server check" on its own screen. Your server is checked against what the shop needs to run, and each check is marked passed or failed:
- PHP version — 8.3.0 or higher, the floor MyntCart's Laravel 13 base needs; anything older fails the check
- PHP Extensions: OpenSSL, PDO, Mbstring, Tokenizer, XML, GD, cURL, Fileinfo, BCMath, JSON, Zip, Ctype
- Directory permissions: write access to
storage/andbootstrap/cache/ - Your
.envfile must also be writable — the installer rewrites it on the Database and Complete steps
All passed? → Click "Continue to license"
Any failed? → The screen says how to put each one right (choose a newer PHP, switch the missing extensions on, give the web server write access to the two folders). Fix it on the server, then click "Check again". The database is not checked here — MySQL 8.0 or newer is checked on the Database step.
License Verification
Enter the purchase code that came with your copy:
- Where did you buy it? — CodeCanyon or Direct purchase (from CodeMynt). CodeCanyon is pre-selected, so change it if you bought directly from CodeMynt.
- Purchase Code — exactly as issued to you. A direct purchase's code is in your licence e-mail, in the form
XXXX-XXXX-XXXX-XXXX; a CodeCanyon code is longer, and is on the licence certificate under Downloads. - Username — your Envato user name for a CodeCanyon purchase, or the e-mail your direct licence is registered to (e.g.
you@email.com) - Confirmation checkbox — you must tick the box confirming that the purchase code is legitimate and that you have the right to use it on this domain.
Click "Verify license". The installer verifies these against license.codemynt.in. On success → it goes on to the download. On failure → double-check what you entered and try again. A code works on one domain: to move a shop, deactivate the old installation first.
license.codemynt.in, and the HMAC_SIGNING_KEY line must be in .env as it came in .env.example (see above); without it this step and the Assets step cannot complete.
Download Files
The package you downloaded holds no database. Once your licence is verified, the installer fetches the files your shop is built from, from the CodeMynt licence server — they are released to a verified licence only:
- Four archives are downloaded — the database (the tables and the demo shop), the migrations and the schema (what keeps the database in step with the code), and the Composer files (the list of the shop's packages). Click "Start download"; the progress shows 0/4 → 4/4
- If one of them fails, click "Retry failed" — the ones already fetched are not fetched again. When all four are in, click "Continue to database"
- Requires a stable internet connection, and outbound access to
license.codemynt.in - May take 1–5 minutes depending on server speed
- Do NOT close your browser or navigate away
Database Setup
Enter your database connection details. The installer tests the connection before proceeding:
| Field | Value | Notes |
|---|---|---|
| Database Host | localhost | or 127.0.0.1 |
| Port | 3306 | Default MySQL port |
| Database Name | myntcart | The empty database you created earlier |
| Username | root | Your MySQL user with full privileges |
| Password | (your password) | Empty for localhost WAMP/XAMPP |
The installer writes these to your .env file automatically. Click "Test connection"; once the database answers, "Continue to import" opens the next step. The database must be MySQL 8.0 or newer and empty, and its user needs every right on it — the installer creates the tables.
Import — Database Import
This step is labelled "Import" in the installer's list of steps. Click "Start Database Import": it creates the complete database — 215 tables plus the demo shop — from the database archive downloaded on the Assets step. A progress bar tracks the import; when it ends, click "Complete Installation".
- Takes a few minutes depending on server performance
- Do NOT close your browser during import
- Do NOT press back or refresh
- A demo catalogue and one admin account come with it, so you can sign in straight away
- If the import stops, start it again. A second way in, Emergency Import, is offered only then
Your Shop Is Installed
The last screen says the shop is installed and shows:
- Admin sign-in — the e-mail and password of the account that came with the shop (below)
- Next steps — sign in and choose your own password, set up the shop's name, logo, payment methods and delivery, add your products or keep the demo ones, and place a test order
- Before you go live — sign in soon, mind the demo accounts, use HTTPS and keep backups
The installer is closed from this moment: a lock file is written and it cannot be run again on this shop. Two buttons lead on: "Admin login", which takes you to /login/admin, and "Visit website".
| Field | Value |
|---|---|
| Admin Panel URL | https://yourdomain.com/login/admin(or http://localhost/myntcart/login/admin) |
admin@admin.com | |
| Password | password |
/secure-install can no longer be opened. This is deliberate — it stops anyone re-running the wizard against a live store. If you genuinely need to run it again, add ALLOW_REINSTALL=true to your .env file; the wizard reopens without you deleting anything by hand. Remove the line again as soon as you are done.
Post-Installation
Complete these steps after the wizard finishes. The cron job and the queue worker matter on every install, not only on live servers.
Setup Cron Jobs
MyntCart needs one cron entry that runs Laravel's scheduler every minute; the scheduler then starts each job below at its own time. The scheduler is what keeps your licence verified — if it never runs, the store stops working once the grace period lapses. Add it in cPanel → Cron Jobs or via crontab -e:
# cPanel → Cron Jobs (every minute) * * * * * /usr/local/bin/php /home/username/public_html/artisan schedule:run >> /dev/null 2>&1 # VPS / dedicated server (crontab -e) * * * * * cd /path/to/myntcart && php artisan schedule:run >> /dev/null 2>&1
What runs from it. Jobs for an add-on module are only scheduled when that module is installed:
| Job | When | What it does |
|---|---|---|
pos:settle-online-payments | Every 5 min | Settles till sales left waiting on PhonePe, Razorpay or Tap to Pay — paid when the gateway confirms, stock given back when it refuses |
gateways:reconcile-webhooks | Every 5 min | Global Payment Gateways: applies payment webhooks that were received but not processed — a confirmed payment still becomes an order |
shadowfax:sync-shipments | Every 15 min | Re-reads live Shadowfax shipments, Courier and Hyperlocal |
shiprocket-quick:reconcile | Every 30 min | Shiprocket Local Quick tracking catch-up |
easyship:sync-shipments | Every 30 min | Re-reads live Easyship shipments |
shipengine:sync-shipments | Every 30 min | Re-reads live ShipEngine shipments — each label's tracking, and shipments labelled or cancelled in ShipEngine's own dashboard |
shiprocket:reconcile | Hourly | Shiprocket catch-up for webhooks that arrived but could not be applied |
sitemap:generate | Daily 03:30 | Rebuilds sitemap.xml |
currency:refresh-rates | Daily | Refreshes exchange rates — does nothing unless automatic rate updates are switched on (off by default) |
license:check | Daily | Re-verifies the MyntCart licence with the licence server |
store-management:verify-license 03:30, shiprocket:verify-license 03:40, shiprocket-quick:verify-license 03:50, shadowfax:verify-license 04:10, easyship:verify-license 04:20, shipengine:verify-license 04:30, global-payment-gateways:verify-license 04:40 | Daily | Module licence re-check. Only an explicit refusal from the licence server switches a module off — if the server is unreachable, nothing changes |
license:verify-modules, shiprocket:check-license-expiry, shiprocket-quick:check-license-expiry | Hourly | Licence status report to the log, and the recorded expiry date applied — no licence-server call for modules |
license:monitor-expiry / license:health-check | Daily 09:00 / Mondays 08:00 | Licence expiry notices and a weekly licence health report |
commercial-tax:verify-license / commercial-tax:report-usage | Every 6 hours / Daily 00:00 | The Commercial Tax module's own licence re-check and its daily usage report |
Run the Queue Worker
Order emails and notifications are queued rather than sent during the request. Without a worker they sit in the queue forever and no customer ever receives an email. Run it under a process manager such as Supervisor (or as a cPanel "always-on" task) so it restarts automatically:
php artisan queue:work --tries=3
Configure SSL
Set up HTTPS with an SSL certificate. Let's Encrypt (free) or your hosting provider's SSL. Update APP_URL in .env to https://.
Set Production Mode
Edit .env → set APP_ENV=production, APP_DEBUG=false and, now that the site is on HTTPS, SESSION_SECURE_COOKIE=true. This hides error details from users and enables caching.
Secure the Sign-ins
Two-factor authentication. Turn it on for the main admin account first: profile menu (top right) → Two-Factor Authentication → scan the QR code with any authenticator app (Google Authenticator, Microsoft Authenticator, Authy or any TOTP app) → enter the 6-digit code → Verify and turn on. Save the one-time recovery codes it shows you — each signs you in once if you lose your phone, and they are not shown again. Each person turns it on for their own account:
- Admins and employees — admin panel, profile menu → Two-Factor Authentication. The store app asks the same staff accounts for their code at sign-in and has its own two-factor setting; turning it off there asks for the password and a code.
- Vendors — vendor panel, profile menu → Two-Factor Authentication
- Customers — on the storefront under My Account → Two-Factor Authentication (every theme's account menu), or in the customer app's settings. Every customer login that proves an existing account asks for the code, social and OTP logins included.
Account lockout. Go to System Setup → Login Settings → OTP & Login Attempts. After Maximum Login Hit wrong passwords, an admin, employee or vendor account is refused for Temporary Login Block Time seconds, whatever IP address the attempts come from — the same limits the customer login uses. A delivery man's sign-in to the delivery app is held to the same two limits. A limit of 0 switches the lockout off. Wrong two-factor codes are counted per account as well, wherever they are entered.
Environment Settings
The .env file holds the settings the application needs before it can reach the database — the ones below, plus your licence signing key, the storefront theme and the operating mode. Everything else (payment gateway credentials, maps, reCAPTCHA, Firebase, SMS, WhatsApp) is configured from the admin panel and is not kept in .env at all. Copy from .env.example and update each section.
Database Configuration
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=myntcart DB_USERNAME=your_username DB_PASSWORD=your_password
Application Configuration
APP_NAME="MyntCart" APP_ENV=local APP_KEY= # leave empty — the installer generates it APP_DEBUG=true APP_URL=http://localhost APP_MODE=live # 'demo' makes the admin panel read-only WEB_THEME=classic # classic, modern or semi-classic DEFAULT_PAYMENT_GATEWAY=stripe # optional — used when no default is chosen under Business Setup → Payment Options
WEB_THEME is what actually decides which storefront your customers see — the theme screens in the admin panel show the setting, but this line governs it. APP_MODE set to demo blocks every settings change in the admin panel; leave it on live for a real store. DEFAULT_PAYMENT_GATEWAY only changes the order of the gateways, and only when no default is chosen under Business Setup → Payment Options: the one named here is then listed first on the storefront checkout and in the customer app. Its credentials are still entered in the admin panel.
Licence & Session
HMAC_SIGNING_KEY=(as it came in .env.example) # required — signs every licence call; leave it as it came LICENSE_GRACE_DAYS=7 # 1–30; how long the store keeps # working if the licence server is unreachable SESSION_SECURE_COOKIE=true # false on plain-http localhost
Mail Configuration
MAIL_MAILER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=your_email@gmail.com MAIL_PASSWORD=your_app_password MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=your_email@gmail.com MAIL_FROM_NAME="MyntCart"
.env lines at run time. Use the admin screen unless you have a reason not to.
File & Folder Permissions
| Path | Permission | Purpose |
|---|---|---|
storage/ | 775 | Cache, logs, sessions |
storage/app/public/ | 775 | Every uploaded file — product images, banners, documents |
bootstrap/cache/ | 775 | Framework bootstrap cache |
.env | 644 | Environment config (sensitive) — must also be writable by the PHP user while you install, because the installer rewrites it |
artisan | 755 | Laravel CLI entry point |
public/assets holds the stylesheets, scripts and images that ship with the product — nothing is ever uploaded into it, so it does not need loosening. Uploaded files go to storage/app/public and are served through a link the application creates for itself; you do not need to run php artisan storage:link by hand.
# Set permissions (Linux) chmod -R 775 storage bootstrap/cache chmod 644 .env chmod 755 artisan # Set ownership for Apache sudo chown -R www-data:www-data storage bootstrap/cache .env
Google Maps API Setup (Complete Guide)
Google Maps powers the store locator, delivery tracking, the live map, address autocomplete and delivery distance and time estimates across the MyntCart website and the Flutter apps. Distance-based shipping rates on the website are worked out from the stored coordinates without calling Google, so they keep working even if a map fails to load.
1. Create a Google Cloud Project
Go to Google Cloud Console
Open console.cloud.google.com → Sign in with your Google account.
Create New Project
Click "Select a Project" (top bar) → "New Project" → Enter name: MyntCart → Click Create. Wait for it to be created, then select it as the active project.
2. Enable Required APIs
Go to APIs & Services → Library in the left sidebar. Search for and enable each of these APIs one by one:
| API Name | Used For in MyntCart |
|---|---|
| Maps JavaScript API | Website — displaying maps (store locator, checkout address picker, admin delivery map) |
| Places API | Website — address autocomplete / search-as-you-type on checkout and address forms |
| Geocoding API | Website — converting addresses to lat/long coordinates and vice versa |
| Distance Matrix API | Website — delivery distance and time between the store and the delivery rider |
| Maps SDK for Android | Flutter apps only — maps in the Android builds (customer, vendor, store, delivery) |
| Maps SDK for iOS | Flutter apps only — maps in the iOS builds |
| Directions API | Flutter delivery app only — the route to the customer on the rider's live map. The app asks the Routes API instead when Directions is not enabled for the key |
3. Create an API Key
Generate Key
Go to APIs & Services → Credentials → Click "Create Credentials" → Select "API Key". A new key is generated instantly. Copy it.
4. Restrict the API Key (Important for Security)
Click "Edit API Key"
Click on your newly created API key → "Edit" or the pencil icon.
Application Restrictions
The website uses two keys. For the client key (the one the browser loads maps with): Select "HTTP referrers (websites)" → Add:
https://yourdomain.com/* http://localhost/*
Create a second key for the server key — the one MyntCart itself uses for geocoding, address lookups and distance calculations. Restrict that one by IP address (your server's outgoing IP), not by referrer: a referrer restriction will reject every call your server makes.
API Restrictions
Select "Restrict key" → Check only the APIs you enabled above. Click Save.
5. Enable Billing
Link a Billing Account
Go to Billing in Google Cloud Console → Link a billing account (credit card required). Google has historically included a free monthly allowance that covers typical e-commerce usage, but the amount and the terms change — check the current Google Maps Platform pricing page before you budget.
Set Budget Alerts
Go to Billing → Budgets & alerts → Create a budget (e.g. $50/month) to get notified before exceeding the free tier.
6. Configure in MyntCart
Website (Admin Panel)
Google Maps is configured entirely in the admin panel — there is nothing to add to .env. Go to Admin Panel → System Settings → 3rd Party & Other Configs → Google Map APIs and fill in:
| Field | What to enter | Required? |
|---|---|---|
| Map API Key (Client) | The referrer-restricted key. Used by the browser to draw maps on the storefront and in the admin panel. | Yes |
| Map API Key (Server) | The IP-restricted key. Used by MyntCart itself for geocoding, address autocomplete and distance calculations. | Yes |
| Map ID | A Map ID from Google Cloud, for advanced markers and cloud-based map styling. Leave blank for the default style. | Optional |
Then toggle the status to Active and click Save.
Flutter Apps (Android)
The key is not typed into the manifest. Add one line to android/local.properties in each app that has a map (customer, vendor, delivery); Gradle puts it into the manifest when it builds:
# myntcartapp (customer) MAPS_API_KEY=YOUR_ANDROID_MAPS_API_KEY # myntcart_vendor and myntcart_delivery GOOGLE_MAPS_API_KEY=YOUR_ANDROID_MAPS_API_KEY
Flutter Apps (iOS)
Copy ios/Flutter/Secrets.example.xcconfig to ios/Flutter/Secrets.xcconfig in each of the same three apps and set the key there; AppDelegate.swift reads it and needs no edit:
# myntcartapp (customer) MAPS_API_KEY=YOUR_IOS_MAPS_API_KEY # myntcart_vendor and myntcart_delivery GOOGLE_MAPS_API_KEY=YOUR_IOS_MAPS_API_KEY
Google Maps Config Summary
| Where | File / Location | Key Type |
|---|---|---|
| Website (browser) | Admin Panel → 3rd Party → Google Map APIs → Map API Key (Client) | HTTP referrer restricted key |
| Website (server) | Admin Panel → 3rd Party → Google Map APIs → Map API Key (Server) | IP address restricted key |
| Android apps (customer, vendor, delivery) | android/local.properties | Android apps restricted key |
| iOS apps (customer, vendor, delivery) | ios/Flutter/Secrets.xcconfig | iOS apps restricted key |
reCAPTCHA Setup (Complete Guide)
Google reCAPTCHA protects login, registration, contact, and checkout forms from spam bots.
1. Go to reCAPTCHA Console
Open reCAPTCHA Admin
Go to google.com/recaptcha/admin → Sign in with your Google account.
2. Create a New Site
Click "+" (Create)
Click the "+" button to register a new site.
Fill in Details
Enter:
- Label:
MyntCart(any descriptive name) - reCAPTCHA type: Select reCAPTCHA v2 → "I'm not a robot" Checkbox
- Domains: Add all your domains:
yourdomain.com www.yourdomain.com localhost staging.yourdomain.com
Accept Terms & Submit
Check "Accept the reCAPTCHA Terms of Service" → Click Submit.
3. Copy Your Keys
After submission, Google shows two keys:
| Key | Where It's Used | Example |
|---|---|---|
| Site Key | Frontend HTML — displayed to the user in the reCAPTCHA widget | 6LcXXXXXXXXXXXXXXXXXXXXXXX |
| Secret Key | Server-side — used to verify the response with Google's API (never expose publicly) | 6LcXXXXXXXXXXXXXXXXXXXXXXX |
4. Configure in MyntCart
Enable in Admin Panel
Both keys are entered in the admin panel. Nothing goes into .env.
- Go to Admin Panel → System Settings → 3rd Party & Other Configs → Recaptcha
- Enter Site Key and Secret Key
- Select status: Active
- Click Save
5. Manage & Monitor
Go back to reCAPTCHA Admin Console anytime to:
- View request statistics (pass/fail rates, suspicious traffic)
- Add or remove domains
- Regenerate keys if compromised
Firebase Setup (Complete Guide)
Firebase powers push notifications, OTP phone authentication and Google sign-in in MyntCart. You need one Firebase project for the website and all Flutter apps. Everything on the web side is entered in the admin panel — no Firebase value belongs in .env, and no file is uploaded to the server.
1. Create Firebase Project
Go to Firebase Console
Open console.firebase.google.com → Sign in with your Google account → Click "Create a project" (or "Add project").
Enter Project Name
Name your project (e.g. myntcart). Firebase auto-generates a Project ID below. Click Continue.
Google Analytics (optional)
Toggle Analytics on/off. If on, select or create an Analytics account. Click Create project. Wait 30–60 seconds.
2. Add a Web App (for MyntCart Backend)
Register Web App
In the project dashboard, click the Web icon (</>) → Enter nickname: MyntCart Web → Click Register app.
Copy the Firebase Config Object
Firebase shows a JavaScript config object. Copy these values — you will paste them into the admin panel in a moment.
3. Where to Find Each Config Value
Every Firebase config value has a specific location in the Firebase Console. Here's exactly where to find each one. All of them are fields on the Push Notifications Setup screen in the admin panel:
| Admin field | Where to Find in Firebase Console | Example Value |
|---|---|---|
| API Key | Project Settings (⚙ gear icon) → General tab → scroll to "Your apps" → Web app → apiKey | AIzaSyDSb3S-PbqQC-xxxxx |
| Auth Domain | Same location → authDomain | myntcart.firebaseapp.com |
| Project ID | Same location → projectId (also visible at top of Project Settings page) | myntcart |
| Storage Bucket | Same location → storageBucket | myntcart.firebasestorage.app |
| Messaging Sender ID | Same location → messagingSenderId (also shown in Cloud Messaging tab as "Sender ID") | 540949947647 |
| App ID | Same location → appId | 1:540949947647:web:abc123 |
| Measurement ID (optional) | Same location → measurementId. Only present if you turned Google Analytics on when creating the project; leave blank otherwise. | G-XXXXXXXXXX |
| Service Account Content | Project Settings → Service accounts tab → "Generate new private key" → the JSON file that downloads. See step 5. | The whole file, from its first { to its last } — its type is service_account |
4. Enter the Config in the Admin Panel
Go to Admin Panel → System Settings → 3rd Party & Other Configs → Push Notifications Setup and paste each value into the matching field. There is no Firebase block in .env — if you add one, nothing reads it.
5. Cloud Messaging (FCM) — Push Notifications
FCM sends push notifications to all MyntCart Flutter apps (Customer, Vendor, Store, Delivery). MyntCart uses the current Firebase Cloud Messaging API, which authenticates with a service account. There is no server key to copy and nothing to enable under "Cloud Messaging API (Legacy)".
Generate a Service Account Key
Go to Project Settings (⚙ gear) → Service accounts tab → Click "Generate new private key" → confirm with "Generate key". A JSON file downloads.
Paste the JSON into the Admin Panel
Open the downloaded file in a text editor, select everything, and paste it into the Service Account Content box at the top of Push Notifications Setup. Paste the whole file including the outer braces. You do not upload the file to your server and you do not put its path in .env.
Save
Click Save. Push notifications to the apps are now live.
6. Authentication — Enable Sign-in Methods
Navigate to Build → Authentication → Sign-in method in Firebase Console. Enable each method MyntCart needs:
| Method | Used For | How to Enable |
|---|---|---|
| Phone | OTP login in all Flutter apps | Click Phone → Enable toggle → Save. No extra config needed. |
| Google sign-in on customer app & website | Click Google → Enable → Select support email → Save. Add SHA-1 key for Android (see below). | |
| Email/Password | Email-based login (if enabled in admin) | Click Email/Password → Enable → Save. |
7. Phone OTP — Firebase Auth
OTP login is switched on separately, on its own screen. Go to Admin Panel → System Settings → 3rd Party & Other Configs → Firebase Auth. This screen holds exactly two things:
- Status — turns Firebase OTP verification on or off
- Web API Key — the same
apiKeyvalue from Project Settings → General → Your apps
Click Save. The rest of the Firebase web config (auth domain, project ID, sender ID and so on) belongs on the Push Notifications Setup screen, not here.
8. Register Flutter Apps in Firebase Console
Each Flutter app needs its own Android + iOS registration inside the same Firebase project. Repeat these steps for every app:
| App | Android Package Name | iOS Bundle ID |
|---|---|---|
| myntcartapp (Customer) | com.myntcart.app | com.myntcart.app |
| myntcart_vendor | com.myntcart_vendor.app | com.myntcart-vendor.app |
| myntcart_delivery | com.myntcart_delivery.app | com.myntcart-delivery.app |
Register Android App
Open Project Settings
In Firebase Console → Project Settings (⚙ gear) → General tab → scroll to "Your apps"
Add Android App
Click "Add app" → Select Android icon
Enter Package Name
Enter the Android package name from the table above (e.g. com.myntcart.app). Enter an app nickname (e.g. "MyntCart Customer Android").
Enter SHA-1 Fingerprint
Enter your SHA-1 fingerprint (required for Google Sign-In — see step 9 below)
Register & Download Config
Click Register app → Download google-services.json → Place at android/app/google-services.json in the Flutter project
Skip SDK Steps
Firebase shows "Add Firebase SDK" steps — skip these (Flutter already has it) → Click Continue to console
Register iOS App
Add iOS App
Click "Add app" → Select iOS icon
Enter Bundle ID
Enter the iOS Bundle ID from the table above (e.g. com.myntcart.app). Enter an app nickname (e.g. "MyntCart Customer iOS"). Click Register app.
Download Config
Download GoogleService-Info.plist → Place it in the Flutter project's ios folder (customer and vendor apps) or in ios/Runner (delivery app) — the exact paths are listed below
Skip & Finish
Skip the remaining SDK steps → Click Continue to console
google-services.json (Android) and GoogleService-Info.plist (iOS). The package name in the config file must match the applicationId in build.gradle and the Bundle ID in Xcode.
Config File Placement (per app)
# Customer App myntcartapp/android/app/google-services.json myntcartapp/ios/GoogleService-Info.plist # Vendor App myntcart_vendor/android/app/google-services.json myntcart_vendor/ios/GoogleService-Info.plist # Store App: none -- it carries no Firebase package # Delivery App myntcart_delivery/android/app/google-services.json myntcart_delivery/ios/Runner/GoogleService-Info.plist
9. SHA-1 Key (for Google Sign-In on Android)
Google Sign-In requires your app's SHA-1 fingerprint registered in Firebase. Get it with this command:
keytool -list -v -keystore %USERPROFILE%\.android\debug.keystore -alias androiddebugkey -storepass android -keypass android
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
# For release builds (Play Store), use your release keystore:
keytool -list -v -keystore /path/to/your-release-key.jks -alias your-key-alias
You'll be prompted for the keystore password.
- Copy the SHA1 fingerprint from the output (format:
XX:XX:XX:...:XX) - Go to Firebase Console → Project Settings → Your apps → select the Android app
- Click "Add fingerprint" → Paste the SHA-1 → Save
- For Play Store release, add the release keystore SHA-1 too
- After adding SHA-1, re-download
google-services.json— it now includes the fingerprint data
10. Where to Configure Firebase in MyntCart Web Admin
The Firebase values go in two places on the web side, and both of them are admin screens:
| Config | Where in Admin Panel | What to Enter |
|---|---|---|
| Push Notifications | System Settings → 3rd Party & Other Configs → Push Notifications Setup | Service Account JSON, API Key, Auth Domain, Project ID, Storage Bucket, Messaging Sender ID, App ID, Measurement ID (optional) |
| Firebase Auth | System Settings → 3rd Party & Other Configs → Firebase Auth | OTP on/off, and the Web API Key |
FIREBASE_* settings in the environment file, and no service-account file is stored on your server. If you have inherited a site with such lines in .env, they are doing nothing — the two admin screens above are the whole configuration.
Firebase Configuration Summary
| What | Where to Configure | Source in Firebase Console |
|---|---|---|
| Web API Key, Project ID, etc. | Admin Panel → Push Notifications Setup | Project Settings → General → Your apps → Web app config |
| Web API Key (for phone OTP) | Admin Panel → Firebase Auth | Project Settings → General → Your apps → Web app apiKey |
| Service Account JSON | Admin Panel → Push Notifications Setup → pasted into "Service Account Content" | Project Settings → Service accounts → Generate new private key |
| Auth methods | Firebase Console directly | Build → Authentication → Sign-in method |
| Android config (per app) | android/app/google-services.json | Project Settings → Your apps → Android app → Download |
| iOS config (per app) | ios/Runner/GoogleService-Info.plist | Project Settings → Your apps → iOS app → Download |
| SHA-1 fingerprint | Firebase Console → Android app → Add fingerprint | Generated from your keystore via keytool |
SMS API Setup
Configure SMS providers for OTP delivery and order notifications. MyntCart ships with 20 SMS gateways built in, each with its own credential fields.
Go to Admin Panel → System Settings → 3rd Party & Other Configs → SMS API Config. Every gateway has its own panel on that screen — fill in the credentials for the one you use, set it Active, and save. Only one gateway is active at a time.
| Supported SMS gateways | |
|---|---|
| 2Factor | 019 SMS |
| Bird | ClickSend |
| D7 Networks | Fast2SMS |
| Global SMS | Gupshup |
| Hubtel | Infobip |
| MSG91 | Nexmo (Vonage) |
| Paradox | Plivo |
| Signal Wire | Sinch |
| SMS To | Telesign |
| Telnyx | Twilio |
Related SMS Screens
Three more screens sit alongside SMS API Config under 3rd Party & Other Configs:
- SMS Order Notifications — choose which order events send an SMS, and to whom
- SMS Templates — the message wording for each event
- Advanced SMS Templates — richer per-gateway templates, with import and export
WhatsApp Integration via Twilio (Complete Guide)
MyntCart uses Twilio's WhatsApp Business API to send order updates, bulk store notifications, delivery alerts, invoice sharing, and customer communication directly via WhatsApp.
1. Create a Twilio Account
Sign Up
Go to twilio.com/try-twilio → Create a free account with your email and phone number. Verify your email and phone via OTP.
Get Your Account Credentials
After login, you land on the Twilio Console Dashboard. Your credentials are shown right on this page:
| Credential | Where to Find | Example |
|---|---|---|
| Account SID | Twilio Console → Dashboard → "Account SID" (shown at top) | ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Auth Token | Same page → Click "Show" next to Auth Token to reveal it | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
2. Enable WhatsApp Sandbox (for Testing)
Go to WhatsApp Sandbox
In Twilio Console, navigate to Messaging → Try it out → Send a WhatsApp message. Or go directly to Messaging → Settings → WhatsApp sandbox settings.
Join the Sandbox
Twilio shows a sandbox WhatsApp number (e.g. +1 415 523 8886) and a join code (e.g. join xxxxx-xxxxx). Send this join message from your personal WhatsApp to that number to activate the sandbox.
Note the Sandbox Number
The sandbox number is your temporary WhatsApp "from" number for testing. Use it in MyntCart config until you get a real WhatsApp Business number.
3. Get a WhatsApp Business Number (for Production)
Buy a Twilio Phone Number
In Twilio Console → Phone Numbers → Manage → Buy a number. Select a number with SMS and MMS capabilities in your country.
Register for WhatsApp Business
Go to Messaging → Senders → WhatsApp senders → Click "Register a WhatsApp sender". You need:
- A verified Facebook Business Manager account
- A Twilio phone number to link as WhatsApp sender
- Your business display name and description
WhatsApp/Meta reviews and approves your sender (takes 1–7 business days).
Note Your WhatsApp Number
Once approved, your Twilio number is a verified WhatsApp Business sender. Use this number (with country code, e.g. +919876543210) in MyntCart configuration.
4. Configure in MyntCart
Open Twilio WhatsApp Config
Go to Admin Panel → System Settings → 3rd Party & Other Configs → Twilio WhatsApp Config.
Enter Credentials
Fill in the following fields:
| Field | Value | Where to Get |
|---|---|---|
| Credentials Source | Own credentials or SMS gateway | Choose "SMS gateway" to reuse the Account SID and Auth Token you already saved under the Twilio SMS gateway, instead of entering them twice |
| Twilio Account SID | ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | Twilio Console → Dashboard (not needed if you picked "SMS gateway" above) |
| Twilio Auth Token | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | Twilio Console → Dashboard → Click "Show" (not needed if you picked "SMS gateway" above) |
| WhatsApp From Number | +919876543210 | Your approved WhatsApp Business number (or sandbox number for testing) |
| Content SID | HXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | Twilio Console → Content Template Builder. Meta requires an approved template for any message your business starts — without one Twilio refuses business-initiated messages. |
| Content Variables | JSON, e.g. {"1":"order_id"} | Optional. Maps values into the numbered placeholders of your approved template. |
Toggle Active & Save
Toggle the status to Active → Click Save. WhatsApp messaging is now enabled.
Decide Whether Stores Get Notified
A separate switch on the same screen — "Notify stores of new orders and status changes" — controls whether every new order and status change sends a WhatsApp message to the store that has to fulfil it. It is off by default and is deliberately separate from the Active toggle, so that turning WhatsApp on for invoice sharing does not start a paid message on every order.
With it on, orders are sent through Twilio in the background and an order is only marked as notified once Twilio accepts the message. With it off, the platform prepares a click-to-chat link instead and tells you so — nothing is sent automatically. Point-of-sale orders never notify the store, since the store rang them up itself.
5. Configure Store-Level WhatsApp Numbers
Each store branch can have its own WhatsApp number for receiving orders and customer messages.
- Go to Admin Panel → Store Management → Store Settings (or select a specific store)
- Find the WhatsApp Number field
- Enter the store's WhatsApp number with country code (e.g.
+919876543210) - Click Save
6. Test WhatsApp Messaging
- Go to Admin Panel → Store Management → Bulk WhatsApp
- Select a store with a configured WhatsApp number
- Enter a test message
- Click Preview to see the formatted WhatsApp message
- Click Send. The result is reported per store: sent where Twilio accepted the message, or link ready where Twilio is off and you get a click-to-chat link to open yourself.
WhatsApp Features in MyntCart
| Feature | Description | Where in Admin |
|---|---|---|
| Bulk WhatsApp Orders | Send orders to multiple stores at once via WhatsApp with customizable messages (Store Management module) | Store Management → Bulk WhatsApp |
| New Order Notification | Message to the fulfilling store with order ID, items, total, payment method and address when an order is placed | Automatic, once "Notify stores" is switched on |
| Order Status Updates | Message to the store when an order moves to packed, out for delivery, delivered or cancelled | Automatic, once "Notify stores" is switched on |
| Store Notification Templates | Single-brace placeholders: {store_name}, {order_id}, {customer_name}, {customer_phone}, {total}, {payment_method}, {address}, {timestamp} | Used by the automatic store notifications above |
| Customer WhatsApp Templates | Double-brace placeholders: {{customer_name}}, {{order_id}}, {{amount}}, {{store_name}}, {{store_address}} | Served to the Store mobile app; the nearest admin screen is Customer WhatsApp |
| Store-Level WhatsApp | Each branch has its own WhatsApp number for direct customer contact (Store Management module) | Store Management → Store Settings |
| Order on WhatsApp (storefront) | A button on product cards, on the product page and on a store's own page (Classic and Modern themes) opens the shopper's own WhatsApp on a ready-written order. The server decides who receives it: an order from a store's page goes to that store; a vendor's product goes to that vendor, at its shop's contact number; the shop's own product goes to the first open store that stocks it, and otherwise to the shop's own number. The message names the product, the size and quantity chosen and the price, and carries a map link to where the customer is when their browser shares it — browsers share a position on https only. The button is always shown; where nobody can be reached, pressing it says so | The store's WhatsApp number (Store form); a vendor's shop contact number; Social Media Settings → Social Media Chat, else the company phone |
| Invoice Sharing | Share order invoices and receipts directly to customer's WhatsApp | Order Details page |
| Chat Widget | Floating WhatsApp chat button on storefront for instant support | Social Media Settings → Social Media Chat |
Twilio Pricing
Payment Gateways & UPI
Payment credentials are entered in the admin panel, never in .env. MyntCart has 14 gateways built in — Stripe, Razorpay, PayPal, PhonePe, Paytm, Paystack, senangPay, Flutterwave, PayTabs, LiqPay, Mercado Pago, Paymob Accept, Cashfree and Instamojo — and six more in the Global Payment Gateways module. UPI to your own UPI ID needs no gateway at all.
Configure a Gateway
- Go to Admin Panel → System Settings → Payment Methods → Digital Payment Methods
- Fill in the gateway's credentials and choose the Mode: Test while you try it, Live for real payments
- Switch the gateway on and click Save
A gateway that is switched on but has no credentials is marked Not configured and hidden from checkout. Before switching one on, check under System Setup → Currency that your currency is one the gateway accepts. The gateway chosen under Business Setup → Payment Options → Default payment gateway at checkout is offered first, on the storefront and in the customer app; the rest keep the order they were set up in. With none chosen, DEFAULT_PAYMENT_GATEWAY in .env (see Environment Settings) still counts.
PhonePe (Standard Checkout v2)
PhonePe runs on its Standard Checkout v2 API through PhonePe's official SDK — on the web checkout, in the customer app (PhonePe's native SDK) and at the tills. The older v1 credentials (merchant ID plus salt key) are not used; you need PhonePe's v2 client credentials. PhonePe takes payments in Indian rupees only.
| Field | What to enter |
|---|---|
| Client Id / Client Secret | The Standard Checkout v2 client credentials PhonePe issues you. Both are required — without them PhonePe is not offered. |
| Client Version | The client version issued with them (treated as 1 when left blank) |
| Merchant Id | Your PhonePe merchant ID — the customer app's PhonePe SDK starts with it |
| Webhook Username / Webhook Password | The username and password you set on the webhook in your PhonePe account. PhonePe signs every notice with them, and a notice that does not match is refused. |
| Mode | Test uses PhonePe's sandbox; Live takes real payments |
Give PhonePe this webhook URL:
https://yourdomain.com/api/v1/phonepe/webhook
An order is marked paid only when PhonePe's Order Status API confirms it — the customer arriving back on your site proves nothing — and the webhook records payments that complete after the customer has left.
UPI Payments (Pay to Your UPI ID)
Customers pay from any UPI app straight into your bank account, and someone at the store confirms each payment. There is no gateway and no webhook. One UPI account serves the whole platform — storefront, customer app and every till.
Set it up
- Go to Admin Panel → System Settings → Payment Methods → UPI Payments
- Enter your UPI ID (a business UPI ID, not a personal one), the Payee name shown in the customer's UPI app and, optionally, a Note shown to customers
- Switch on Show Pay with UPI at checkout and click Save
How customers pay
- Storefront (all three themes) — signed-in customers choose Pay with UPI. The order is placed unpaid and a payment page shows a QR code for the exact amount (and a link that opens a UPI app on phones). After paying, the customer enters the UTR / transaction reference from their UPI app and can attach a screenshot (JPG, PNG or WEBP, up to 4 MB). Submissions are rate-limited, and a UTR already offered for another order is refused.
- Customer app — the same flow: place the order by UPI, pay as shown, submit the UTR. It uses the same service as the web checkout, so both accept and refuse the same proofs.
Verify or reject
Payments waiting to be checked are listed on the same UPI Payments screen, and its menu item shows a red badge with how many there are. Find the UTR and amount in your bank account, then press Verify — the order is marked paid and the customer is e-mailed — or Reject, which leaves the order unpaid so the customer can submit a corrected UTR from the same payment page. Two admins pressing Verify at once settle it only once.
UPI at the tills
| Till | Paid into | How the sale is recorded |
|---|---|---|
| Admin POS (web) | The platform's UPI ID | Payment type UPI shows a QR for the sale's amount in rupees. The cashier waits for the money to arrive, optionally types the customer's UTR, and completes the sale — recorded paid at once. |
| Vendor POS (web) | The platform's UPI ID — the admin collects it | The same dialog. The sale is settled with the vendor like a delivered online order: the commission is recorded and the vendor's share is credited to the vendor wallet for withdrawal. Cash and card-machine sales at a vendor's counter are not settled this way. |
| Store app POS | The platform's UPI ID | The app asks the server for the QR — priced from the catalogue on the server, never by the app — and the sale is recorded paid at the counter. |
| Vendor app POS | The platform's UPI ID | Server-priced QR; the sale is settled with the vendor (commission + vendor wallet), as at the vendor web POS. |
Wherever a UTR is entered — at checkout or at a till — it has to look like one: 10 to 24 letters and digits with at least 8 digits, never a UPI ID with "@". At a till the UTR is optional; when none is typed, the QR's own reference (starting POS) is kept on the order so the sale can be found on the bank statement.
Shipping Auto-Calculation
MyntCart features a smart shipping calculation engine that automatically determines shipping costs using a priority-based adapter system. Instead of manual rate entry, the system tries each enabled shipping provider in priority order and uses the first successful result.
How It Works
- Priority-Based Adapters — Each shipping provider (Shiprocket, Shiprocket Local Quick, Easyship, ShipEngine, Shadowfax Courier, Shadowfax Hyperlocal, Manual) is an adapter with a configurable priority (1–100)
- Automatic Fallback — If the highest-priority adapter fails, the system automatically tries the next adapter
- Manual Fallback — Manual shipping is always available as the last-resort fallback adapter
- Multi-Option Display — Show customers multiple shipping options from different providers so they can choose
- Category-wise Shipping — Set different shipping costs per product category
- Order-wise Shipping — Flat shipping rate per order
Configure Shipping Calculator
Access Settings
Go to Admin Panel → Order Management → Shipping Calculator to view all available adapters and their status.
Enable & Prioritize
Toggle each adapter on/off and set priority numbers (lower = higher priority). The system processes adapters in priority order.
Test Connection
Use the Test button for each adapter to verify API credentials and connectivity before going live.
| Adapter | Module required | Default priority |
|---|---|---|
| Shiprocket Local Quick | Shiprocket Local Quick | 5 |
| Shadowfax (Courier) | Shadowfax | 5 |
| Shadowfax Hyperlocal | Shadowfax — offered only when "Offer Shadowfax Hyperlocal at checkout" is on | 5 |
| Shiprocket | Shiprocket | 10 |
| Easyship | Easyship | 20 |
| ShipEngine | ShipEngine | 30 |
| Manual | None — always available | 100 (last resort) |
Courier Hand-off, Tracking & Cancellation
The calculator decides what the customer is charged. What happens to the parcel afterwards is set under Admin Panel → Order Management → Shipping Providers:
- Trigger status — under Trigger Status Settings → Order Status Trigger, pick Confirmed, Processing, Shipped (the default) or Out for Delivery. When an order reaches that status it is handed to its courier. The store app's shipping settings change the same value.
- Which courier — each order goes to the courier checkout priced it with. Only orders priced by Manual rates go to the Active Provider chosen on the same screen.
- Couriers that start at checkout — Shiprocket creates its order straight after checkout (Ship Now later assigns the AWB and books the pickup), and Shadowfax, Courier or Hyperlocal, takes cash-on-delivery and already-paid orders then; for both, the trigger status hands over whatever did not go at checkout. Shiprocket Local Quick always hands over at placement and ignores the trigger status, booking the rider at once only for cash-on-delivery or already-paid orders.
- Status updates move forward only — Shiprocket, Shiprocket Local Quick, Shadowfax, Easyship and ShipEngine advance the order (shipped → out for delivery → delivered, or returned / failed), never backwards and never out of a finished state. Shipped orders have their own tab in the order lists and count as ongoing, not completed.
- Cancellations reach the courier — an order cancelled anywhere (admin, vendor, customer or store app) is cancelled at Shiprocket, Shiprocket Local Quick, Shadowfax or Easyship as well.
- One tracking timeline — every courier feeds the same order-tracking timeline on every storefront theme and in the customer app, with the carrier's details and the courier's own tracking link.
- What a vendor may set — with admin shipping, a vendor can set an order to pending, confirmed or processing; with seller-wise shipping, also shipped, out for delivery, delivered, returned, failed or canceled. The vendor panel and the vendor app enforce the same list.
Courier Webhook URLs
Couriers report status changes to these addresses. Replace yourdomain.com with your live domain — a courier cannot reach localhost or a LAN address, however correct the rest of the setup is.
| Courier | Webhook URL | Where to register it |
|---|---|---|
| Shiprocket | https://yourdomain.com/api/parcel-tracking/webhook | Shiprocket dashboard → Settings → Webhooks, with the Webhook Secret (x-api-key) shown under Shiprocket Settings. The path avoids the word "shiprocket", which Shiprocket refuses in a webhook URL. |
| Shiprocket Local Quick | https://yourdomain.com/api/v1/local-delivery/webhook | A Shiprocket account takes one webhook URL. If both Shiprocket modules use the same account, register either module's URL and secret — each passes the other its shipments. |
| Shadowfax Courier | https://yourdomain.com/api/shadowfax/webhook/production( …/webhook/staging for staging) | Shadowfax Client Portal → Webhook tab, with the callback key you choose under Shadowfax Settings (one key per environment) |
| Shadowfax Hyperlocal | https://yourdomain.com/api/shadowfax/hyperlocal/webhook/production( …/webhook/staging for staging) | Give it to Shadowfax with the Hyperlocal callback key set under Shadowfax Settings |
| Easyship | https://yourdomain.com/api/easyship/webhook | Press Register Endpoint on Easyship Management → Webhooks — it registers the URL, switches the webhook on and saves its signing secret |
| ShipEngine | https://yourdomain.com/api/shipengine/webhook | ShipEngine Management → Webhooks: pick Tracking event and press Register — a webhook already registered for that event is moved to this address. There is no secret to paste — ShipEngine signs with published keys. |
The scheduled jobs under Post-Installation catch up what webhooks miss — Shadowfax, Easyship and Shiprocket Local Quick shipments are re-read from the courier, and Shiprocket updates that arrived but could not be applied are retried — so the cron entry matters here too.
Flutter Apps — Complete Setup Guide
MyntCart ships with four Flutter mobile applications. This guide covers everything from installing Flutter to building a release APK — nothing left out.
Required Versions
| Tool | Required Version | Notes |
|---|---|---|
| Flutter SDK | 3.47.0 or higher | Stable channel. One release builds all four apps |
| Dart SDK | Bundled with Flutter | Dart 3.13 comes with Flutter 3.47 — no separate install needed |
| Java JDK | JDK 17 | All four apps compile against Java 17 |
| Android Studio | Latest stable release | With Flutter & Dart plugins installed |
| Android SDK | Platform 37 (Android 17) | Install via Android Studio → SDK Manager → SDK Platforms. All four apps compile against it |
| Gradle, Android Gradle Plugin, Kotlin | Nothing to install | Each project names its own versions and the first build downloads them — they are listed in the table below |
| Xcode | 15.0+, 16 recommended (macOS only) | Required for iOS builds |
| CocoaPods | Latest (macOS only) | sudo gem install cocoapods. Not needed for the store app: its plugins come as Swift packages and it has no Podfile |
JAVA_HOME at it; building on JDK 11 fails in Gradle. An older Flutter release stops at flutter pub get.
| App | Flutter | Java | Gradle / Android Gradle Plugin / Kotlin | Android SDK: compile / target / minimum | iOS minimum |
|---|---|---|---|---|---|
| myntcartapp (Customer) | 3.47.0+ | JDK 17 | 9.3.1 / 9.1.1 / 2.3.21 | 37 / 37 / 24 (Android 7.0) | 15.0 |
| myntcart_vendor | 3.47.0+ | JDK 17 | 9.3.1 / 9.1.1 / 2.3.21 | 37 / 37 / 26 (Android 8.0) | 15.0 |
| myntcart_store | 3.47.0+ | JDK 17 | 9.3.1 / 9.1.1 / 2.3.21 | 37 / 37 / 26 (Android 8.0) | 15.0 |
| myntcart_delivery | 3.47.0+ | JDK 17 | 9.3.1 / 9.1.1 / 2.3.21 | 37 / 37 / 24 (Android 7.0) | 15.0 |
The vendor and store apps start at Android 8.0 because Stripe Terminal, which takes card payments at the point of sale, needs it. All four apps compile against and target Android 17.
Install Flutter (Windows)
Download Flutter SDK
Download the Flutter SDK zip from the official site. Extract it to a permanent location (e.g. C:\flutter). Do NOT place it inside Program Files (permission issues).
# Extract to C:\flutter (or your preferred path) # Then add to System PATH: C:\flutter\bin
Install Java JDK 17
Download and install Oracle JDK 17 or OpenJDK 17 (Adoptium Temurin recommended). After installation, set the JAVA_HOME environment variable to it.
# Set JAVA_HOME (System Variable) JAVA_HOME = C:\Program Files\Java\jdk-17 # Add to PATH (System Variable) %JAVA_HOME%\bin
Install Android Studio
Download Android Studio from the official site. During installation, ensure Android SDK, Android SDK Command-line Tools, and Android SDK Platform-Tools are selected.
Install Flutter & Dart Plugins
Open Android Studio → File → Settings → Plugins → Search "Flutter" → Install (it auto-installs the Dart plugin too). Restart Android Studio.
Configure System Environment Variables
Open System Properties → Environment Variables and add/update these:
| Variable | Value (example path) | Type |
|---|---|---|
JAVA_HOME | C:\Program Files\Java\jdk-17 | System Variable |
ANDROID_HOME | C:\Users\YourName\AppData\Local\Android\Sdk | System Variable |
PATH (append) | C:\flutter\bin | System Variable |
PATH (append) | %JAVA_HOME%\bin | System Variable |
PATH (append) | %ANDROID_HOME%\platform-tools | System Variable |
Verify Installation
Open a new terminal window (old ones don't see PATH changes) and run:
# Verify Flutter flutter --version # Flutter 3.47.x with Dart 3.13.x # Verify Java java -version # 17.x.x # Check everything at once flutter doctor # Fix any ✗ issues it reports
Install Flutter (macOS)
Download & Extract Flutter
Download Flutter SDK and extract to your home directory (e.g. ~/flutter). Add to PATH in your shell profile.
# Add Flutter to PATH export PATH="$HOME/flutter/bin:$PATH" # Set Java 17 export JAVA_HOME=$(/usr/libexec/java_home -v 17) # Android SDK export ANDROID_HOME="$HOME/Library/Android/sdk" export PATH="$ANDROID_HOME/platform-tools:$PATH"
Install Java JDK 17
Use Homebrew: brew install openjdk@17 — then symlink: sudo ln -sfn $(brew --prefix openjdk@17)/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk.
Install Xcode & CocoaPods
Xcode is required for building iOS apps. It's only available on macOS.
- Open the Mac App Store → Search "Xcode" → Click Get / Install (it's free, ~12 GB download)
- Wait for installation to complete (can take 20–40 minutes)
- Open Xcode once after installation → Accept the license agreement → Let it install additional components
- Set Xcode command line tools — open Terminal and run:
# Set Xcode command line tools path sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer # Accept license from terminal (if not done in GUI) sudo xcodebuild -license accept # Install CocoaPods (iOS dependency manager) sudo gem install cocoapods # If gem install fails on Apple Silicon (M1/M2/M3), use: brew install cocoapods # Setup CocoaPods master repo pod setup
- Verify Xcode installation:
# Check Xcode version xcodebuild -version # Should show: Xcode 15.x or higher # Check CocoaPods version pod --version # Should show: 1.x.x
brew install cocoapods) which works natively on ARM.
Install Android Studio + Plugins
Same as Windows — install Android Studio, then install Flutter & Dart plugins from Settings → Plugins.
Verify
Run source ~/.zshrc then flutter doctor — fix any issues it reports. Accept Android licenses: flutter doctor --android-licenses
Import Project into Android Studio
- Open Android Studio → File → Open
- Browse to the project folder (e.g.
E:\AppDevelopment\CodeMynt\myntcartapp) - Select the root folder that contains
pubspec.yaml— click OK - Android Studio detects it as a Flutter project and loads it
- Wait for "Running pub get..." to finish (bottom status bar)
- If prompted to configure Dart/Flutter SDK path → point to
C:\flutter - Connect a device or start an emulator → Click the green Run ▶ button
- Open Android Studio → File → Open
- Browse to the project folder (e.g.
~/Projects/myntcartapp) - Select the root folder that contains
pubspec.yaml— click Open - Android Studio detects it as a Flutter project and loads it
- Wait for "Running pub get..." to finish
- For iOS: run
cd ios && pod install && cd ..in the terminal (not for the store app, which has noPodfile) - Select target device (Android emulator or iOS Simulator) → Click Run ▶
flutter clean then flutter pub get and try again.
App Configuration — Step by Step
Step 1 — Install Dependencies and Create env.json
Open the app directory in your terminal and install all Dart packages.
# Navigate to app directory cd myntcartapp # Install dependencies flutter pub get # Customer, vendor and delivery apps: your values come from env.json (below) flutter run --dart-define-from-file=env.json # Store app: pass your backend on the command line, or put BASE_URL in its own env.json flutter run --dart-define=BASE_URL=https://yourdomain.com
The customer, vendor and delivery apps read their settings from one file, env.json, in the app's root folder. It is not part of the download — it holds your keys, so you create it. The vendor and delivery apps ship env.example.json to copy; the customer app lists the Firebase and Maps names in .env.example, to which you add BASE_URL. The store app needs one value only, BASE_URL: pass it on the command line as above, or copy its env.example.json to env.json and run with --dart-define-from-file=env.json.
{
"BASE_URL": "https://yourdomain.com",
"FIREBASE_API_KEY": "your-api-key",
"FIREBASE_PROJECT_ID": "your-project-id",
"FIREBASE_MESSAGING_SENDER_ID": "your-sender-id",
"FIREBASE_APP_ID": "your-app-id",
"MAPS_API_KEY": "your-maps-key"
}
The vendor app takes the same file without the MAPS_API_KEY line; the delivery app names that line GOOGLE_MAPS_API_KEY. The four Firebase values come from Step 6, the Maps key from Step 7. Keep env.json out of version control.
flutter run — or a release build with no BASE_URL — does not reach your store. Set BASE_URL in env.json (customer, vendor and delivery apps) or pass --dart-define=BASE_URL= (store app, which takes an env.json too) on every run and build, or edit the constant in the app as described in Step 2.
Step 2 — Configure App Constants
Every app has one constants file that carries its name, version and the backend URL it talks to. The file is not in the same place in all four, so start from this table.
| App | Config file | Class | Backend URL field |
|---|---|---|---|
| myntcartapp (Customer) | lib/utill/app_constants.dart | AppConstants | baseUrl |
| myntcart_vendor | lib/utill/app_config.dart | AppConfig | baseUrl (re-exported as AppConstants.baseUrl) |
| myntcart_store | lib/core/constants/myntcart_constants.dart | MyntcartConstants | baseUrl |
| myntcart_delivery | lib/utill/app_config.dart | AppConfig | baseUrl (re-exported as AppConstants.baseUri — note the spelling) |
In all four apps the backend URL is read from the build first and falls back to a built-in address:
class AppConstants { static const String appName = 'MyntCart'; // Display name shown in app static const String slogan = 'E-Commerce'; // Tagline on splash screen static const String appVersion = '1.0.1'; // App version number static const String baseUrl = String.fromEnvironment('BASE_URL', defaultValue: '...development address...'); }
So there are two ways to point an app at your site, and you must use one of them:
- Replace the
defaultValuewith your own URL (no trailing slash), or - Leave the file alone and give the app its address at build time:
BASE_URLinenv.jsonfor the customer, vendor and delivery apps,--dart-define=BASE_URL=https://yourdomain.com(orBASE_URLin its ownenv.json) for the store app, on everyflutter runandflutter build.
| Constant | What to Change | Notes |
|---|---|---|
appName | Your brand name displayed inside the app (splash screen, headers, about page) | Present in all four apps |
slogan | Short tagline shown below the logo on the splash screen | Customer app only. The vendor, store and delivery apps have no tagline constant |
appVersion | Current version — update on each release to match pubspec.yaml | Ships as 1.0.1 (customer), 1.0.2 (vendor), 1.0.0 (store), 1.0 (delivery) |
| Backend URL | Your MyntCart site address, no trailing slash | Field name and file differ per app — see the table above |
http://localhost — the emulator or device cannot reach your computer's localhost. Use your machine's local IP (e.g. http://192.168.0.102:8000) for development, and your live HTTPS domain for production. Release builds block plain HTTP, so a release build pointed at an http:// address fails to connect. Debug builds of all four apps allow plain HTTP only to the addresses listed in android/app/src/debug/res/xml/network_security_config.xml — add your machine's address there. On an Android 17 phone a debug build of any of the four also asks for access to the local network the first time it starts against such an address; allow it, or the calls to the server time out.
Step 3 — Change Logo & Assets
In the customer, vendor and delivery apps every image is named once in lib/utill/images.dart and the files live in assets/images/. The store app has no such file — its screens reference assets/images/… directly. The table below lists the customer app's main images. The other three share the logo.png name but differ elsewhere — the vendor and delivery apps use placeholder.jpg for the placeholder, the store app ships no placeholder picture at all, and their onboarding images are named differently again — so check the app's own assets/images/ folder before replacing files.
| Image | File Path | Usage |
|---|---|---|
| App Logo | assets/images/logo.png | Main logo used inside the app (splash, about, headers) |
| Placeholder (square) | assets/images/placeholder_1x1.png | Default placeholder for product images that haven't loaded yet |
| Placeholder (banner) | assets/images/placeholder_3x1.png | Placeholder for banners and wide images |
| Login / Signup | assets/images/login.png, signup.png | Illustrations on the login and registration screens |
| OTP | assets/images/otp_login.png | Illustration on the one-time code screen |
| Onboarding | assets/images/onboarding_one.png, onboarding_two.png, onboarding_three.png | The three first-run intro screens |
| Order Success | assets/images/purchase_success.png | Shown after an order is placed |
| Wallet | assets/images/wallet_bonus.png | Wallet bonus screen |
| Maintenance / Update | assets/images/maintenance.png, update.png | Shown when the server is in maintenance mode or a new version is required |
To replace: simply overwrite the files in assets/images/ with your own images, keeping the exact same file names. If you want to use different file names, update the paths in lib/utill/images.dart (or, in the store app, in the screen that references the image).
App Launcher Icon (Home Screen Icon)
The launcher icon is separate from the in-app logo. You need one high-resolution PNG (1024x1024px, no transparency for iOS) and it must be exported in multiple sizes for each platform.
assets/icon/appstore.png (1024x1024, no transparency; the store app keeps it at assets/images/appstore.png) and assets/icon/adaptive_foreground.png (the Android adaptive-icon foreground, already padded), then run dart run flutter_launcher_icons in the app folder. It writes all Android and iOS sizes, so the manual steps below are an alternative you do not need.
How to Generate App Icons
Create a 1024x1024 PNG icon
Design your icon at 1024x1024 pixels. Use PNG format. For iOS, do NOT use transparency (Apple rejects it). For Android, transparency is allowed.
Generate all sizes using AppIcon.co
Go to https://www.appicon.co/ — upload your 1024x1024 image → Select iPhone + Android → Click Generate → Download the zip file. It creates all required sizes for both platforms automatically.
Copy generated icons to the project
Extract the downloaded zip and copy the files to the correct folders:
# From the downloaded zip → android/ folder # Copy each ic_launcher.png into the matching mipmap folder: android/app/src/main/res/mipmap-mdpi/ic_launcher.png # 48x48 android/app/src/main/res/mipmap-hdpi/ic_launcher.png # 72x72 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png # 96x96 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png # 144x144 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png # 192x192
# From the downloaded zip → ios/ folder # Replace the entire AppIcon.appiconset folder: ios/Runner/Assets.xcassets/AppIcon.appiconset/ # This folder contains all required sizes (20x20 to 1024x1024) # plus the Contents.json manifest file
ic_launcher_round.png in each mipmap folder, or use ic_launcher_foreground.png and ic_launcher_background.png in mipmap-anydpi-v26/.
Step 4 — Change App Name
The app name displayed on the device home screen is set in platform-specific config files (not in Dart code).
Android
Edit android/app/src/main/AndroidManifest.xml — find the android:label attribute. The vendor app is the exception: its manifest holds a placeholder, and the name is set in android/local.properties (see the table below).
<application android:label="Your App Name" <!-- Change this --> ... >
iOS
Edit ios/Runner/Info.plist — find CFBundleDisplayName (or CFBundleName):
<key>CFBundleDisplayName</key> <string>Your App Name</string>
The names the apps ship with, so you know what you are replacing:
| App | Default home-screen name |
|---|---|
| myntcartapp (Customer) | Myntcart |
| myntcart_vendor | MyntCart Vendor — set once: APP_NAME in android/local.properties (launcher label), APP_DISPLAY_NAME in ios/Flutter/Secrets.xcconfig (iOS), and --dart-define=APP_NAME= for the name shown in-app |
| myntcart_store | Myntcart Store |
| myntcart_delivery | Myntcart Delivery |
Step 5 — Change Package Name (Bundle ID)
The package name uniquely identifies your app on Play Store / App Store. You must change it from the default before publishing.
Android — the app's Gradle file
Three apps use android/app/build.gradle; the store app uses the Kotlin form, android/app/build.gradle.kts. In either file, change both the namespace and the applicationId — they must match.
namespace = "com.yourcompany.yourapp" applicationId = "com.yourcompany.yourapp" // must match namespace
The package names the apps ship with:
| App | Gradle file | Android package name | iOS bundle identifier |
|---|---|---|---|
| myntcartapp (Customer) | android/app/build.gradle | com.myntcart.app | com.myntcart.app |
| myntcart_vendor | android/app/build.gradle | com.myntcart_vendor.app | com.myntcart-vendor.app |
| myntcart_store | android/app/build.gradle.kts | com.myntcart_store.app | com.myntcartstore.app |
| myntcart_delivery | android/app/build.gradle | com.myntcart_delivery.app | com.myntcart-delivery.app |
Then rename the folder structure inside android/app/src/main/kotlin/ (or java/) to match your new package path. For example: com/yourcompany/yourapp/MainActivity.kt
iOS — Xcode
Open ios/Runner.xcworkspace in Xcode → Select Runner target → General tab → Change Bundle Identifier to com.yourcompany.yourapp. An iOS identifier cannot contain an underscore, which is why three of the shipped ones differ from the Android package name.
change_app_package_name Flutter package to rename the Android package across all files automatically. Add it under dev_dependencies in pubspec.yaml, then run:dart run change_app_package_name:main com.yourcompany.yourapp
Step 6 — Firebase Configuration (Complete Guide)
Firebase powers push notifications, phone OTP verification and Google sign-in in the customer, vendor and delivery apps. You need one Firebase project, with those three apps registered in it.
myntcart_store carries no Firebase or Google Maps packages — it signs in against your MyntCart backend and needs no Firebase project entry, no google-services.json and no Maps key.
6.1 — Create a Google Account / Login
- You need a Google account (Gmail). If you don't have one, create at accounts.google.com/signup
- Go to console.firebase.google.com
- Sign in with your Google account
6.2 — Create a Firebase Project
Click "Create a project"
On the Firebase Console dashboard, click the Create a project button (or "Add project" if you already have projects).
Enter Project Name
Enter your project name (e.g. myntcart or yourstore-app). Firebase auto-generates a project ID below it. Click Continue.
Google Analytics (Optional)
Toggle Google Analytics on or off. If enabled, select or create a Google Analytics account. Click Create project.
Wait for Project Creation
Firebase takes 30–60 seconds to create the project. Once done, click Continue to enter the project dashboard.
6.3 — Register MyntCart Apps in Firebase
Register the three Firebase apps (or whichever ones you're deploying) in the same Firebase project — both Android and iOS versions. Register the package name you set in Step 5; the shipped defaults are below, and registering anything else gives you the silent failure described at the end of this step.
| App | Android Package Name (default) | iOS Bundle ID |
|---|---|---|
| myntcartapp (Customer) | com.myntcart.app | com.myntcart.app |
| myntcart_vendor | com.myntcart_vendor.app | com.myntcart-vendor.app |
| myntcart_delivery | com.myntcart_delivery.app | com.myntcart-delivery.app |
For each app, repeat these steps:
Register Android App
Click the Android icon
In your Firebase project dashboard, click "Add app" → Select the Android icon.
Enter Android package name
Enter the applicationId from your app's android/app/build.gradle (e.g. com.myntcart.app). Enter an app nickname (e.g. "MyntCart Customer Android"). You can skip the SHA-1 for now (needed later for Google Sign-In).
Download google-services.json
Click Download google-services.json. Save this file — you'll place it in your Flutter project next.
Skip the SDK setup steps
Firebase shows "Add Firebase SDK" steps — skip these. The Flutter projects already have the Firebase packages installed; what they still need from you is the config, covered in 6.5 and 6.6. Click Continue to console.
Register iOS App
Click "Add app" → iOS icon
Enter the iOS Bundle ID (same as your Xcode Bundle Identifier, e.g. com.myntcart.app). Enter an app nickname (e.g. "MyntCart Customer iOS"). Click Register app.
Download GoogleService-Info.plist
Click Download GoogleService-Info.plist. Save this file. Skip the remaining SDK steps and click Continue to console.
6.4 — Enable Required Firebase Services
In your Firebase project, enable these services (left sidebar menu):
| Service | Where to Enable | Why MyntCart Needs It |
|---|---|---|
| Authentication | Build → Authentication → Sign-in method | Phone OTP login, Google sign-in, email/password login |
| Cloud Messaging (FCM) | Project Settings → Cloud Messaging | Push notifications to all mobile apps |
| Crashlytics (optional) | Build → Crashlytics | Automatic crash reporting and error tracking |
Enable Authentication Methods
- Go to Build → Authentication → Sign-in method
- Enable Phone — required for OTP login in all apps
- Enable Google — for Google sign-in on customer app
- Enable Email/Password — for email-based login
- Click Save for each
Get the service account for push notifications
- Go to Project Settings (gear icon) → Service accounts tab
- Click Generate new private key and download the JSON file
- Paste the whole JSON into MyntCart Admin → System Settings → 3rd Party → Push Notifications Setup (Service Account Content). MyntCart sends through the current FCM API with this account; there is no legacy server key and no VAPID key to enter.
Get SHA-1 Key (for Google Sign-In)
Google Sign-In requires your app's SHA-1 fingerprint registered in Firebase.
# Windows keytool -list -v -keystore %USERPROFILE%\.android\debug.keystore -alias androiddebugkey -storepass android -keypass android # macOS / Linux keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
- Copy the SHA1 fingerprint from the output
- Go to Firebase Console → Project Settings → Your Android app → Add fingerprint
- Paste the SHA-1 and save
- For release builds, use your release keystore SHA-1 instead
6.5 — Place Firebase Config Files in Flutter Project
Android — google-services.json
Place the downloaded file at exactly this path:
myntcartapp/android/app/google-services.json
Open the file and verify package_name matches your applicationId from build.gradle:
{
"project_info": {
"project_id": "your-firebase-project-id",
"storage_bucket": "your-project.firebasestorage.app"
},
"client": [{
"client_info": {
"android_client_info": {
"package_name": "com.yourcompany.yourapp" ← must match applicationId
}
},
"api_key": [{ "current_key": "AIza..." }]
}]
}
iOS — GoogleService-Info.plist
Firebase Console → Your iOS app → Download GoogleService-Info.plist → Place at exactly this path. The folder is not the same in all three apps: the Xcode project of the customer and vendor apps lists the file in the ios folder itself, the delivery app's in ios/Runner.
myntcartapp/ios/GoogleService-Info.plist myntcart_vendor/ios/GoogleService-Info.plist myntcart_delivery/ios/Runner/GoogleService-Info.plist
The BUNDLE_ID inside this plist must match your iOS Bundle Identifier set in Xcode.
GoogleService-Info.plist. For an iOS build you must download your own from the Firebase Console and add it to every app you build.
package_name in google-services.json doesn't match your applicationId in the Gradle file, Firebase will fail silently — push notifications won't work, Google sign-in will crash, and phone auth will return errors. Always verify they match.
6.6 — Firebase values in env.json (customer, vendor and delivery apps)
The customer, vendor and delivery apps start Firebase from the four FIREBASE_… values in env.json when the build carries them, and from the platform file — google-services.json on Android, GoogleService-Info.plist on iOS — when it does not. Put both in place: the platform file is what the native side reads in any case. All four values come from Firebase Console → Project Settings → General → Your apps, and must belong to the same Firebase project as the platform file.
# env.json holds BASE_URL and the four FIREBASE_ values (Step 1)
flutter build apk --release --dart-define-from-file=env.json
Step 7 — Google Maps in Flutter
Maps are used by the customer, vendor and delivery apps (the store app has none). In all three the key is not typed into the manifest — the manifest holds a placeholder that Gradle fills from a properties file, so the key stays out of your source. Create the file if it does not exist; it is one line.
Add your key to android/local.properties. The property name differs between the apps:
# myntcartapp (customer) MAPS_API_KEY=your-android-maps-key # myntcart_vendor and myntcart_delivery GOOGLE_MAPS_API_KEY=your-android-maps-key
The delivery app needs the key a second time, as GOOGLE_MAPS_API_KEY in env.json: it draws the route on the live-tracking map with it when the admin panel's map settings give the apps no key.
For all three apps the key comes from ios/Flutter/Secrets.xcconfig, which Xcode feeds into Info.plist and from there into AppDelegate.swift. The file is not in the download: copy ios/Flutter/Secrets.example.xcconfig to Secrets.xcconfig and edit the one line:
# myntcartapp (customer) MAPS_API_KEY=your-ios-maps-key # myntcart_vendor and myntcart_delivery GOOGLE_MAPS_API_KEY=your-ios-maps-key
Step 8 — Update Version
Edit pubspec.yaml in the root of the app directory:
name: flutter_codemynt_myntcart version: 1.0.1+2 # format: version_name+build_number
The version before + is the display version. The number after + is the build number — increment it on every Play Store / App Store upload. The shipped values are 1.0.1+2 (customer), 1.0.2+2 (vendor), 1.0.0+1 (store) and 1.0.0+1 (delivery). Keep the appVersion constant from Step 2 in step with whatever you set here. In all four apps the iOS version and build number come from this line too, so there is nothing to change in Xcode.
Step 9 — Build & Release
# Build Android APK (direct install) flutter build apk --release --dart-define-from-file=env.json # Build Android App Bundle (Play Store upload) flutter build appbundle --release --dart-define-from-file=env.json # Build iOS for the App Store (requires macOS + Xcode) flutter build ipa --dart-define-from-file=env.json
flutter build apk --release --dart-define=BASE_URL=https://yourdomain.com flutter build appbundle --release --dart-define=BASE_URL=https://yourdomain.com flutter build ios --release --dart-define=BASE_URL=https://yourdomain.com
Sign the Android release
All four apps read the release signing key from android/key.properties, which is not in the download. Create a keystore once (keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload), keep it safe, and point the file at it:
storeFile=C:/keys/upload-keystore.jks storePassword=your-keystore-password keyAlias=upload keyPassword=your-key-password
Without this file all four apps sign the release with the debug key — it installs on your own phone, but Google Play rejects it. Use the same keystore for every later update of the app.
First iOS build
On the Mac, run flutter pub get, then cd ios && pod install --repo-update && cd .., then the build command above. The store app has no Podfile — its plugins come as Swift packages, which Xcode fetches during the build — so skip the pod install step for it. Set your Apple Developer team in Xcode (Runner → Signing & Capabilities) before you archive. Each of the four apps carries a step-by-step guide for this first build, including what to check on a device: docs/IOS_BUILD.md in the app folder. The iOS projects of the vendor, store and delivery apps were prepared on Windows and have not been compiled on a Mac yet; their guides list what to check.
myntcart.com in release builds. Your own domain is not pinned and works as it is; to pin it, follow the app's README.md (vendor, store and delivery apps) or docs/CERTIFICATE_PINNING_SETUP.md (customer app).Syncfusion licence. The vendor app's charts, date-range picker and PDF viewer are Syncfusion packages. They need a Syncfusion licence of your own — commercial or community — before you publish.
Tap to Pay on iPhone. Tap to Pay in the vendor and store apps needs an entitlement Apple grants per developer team;
docs/IOS_BUILD.md in each app explains it. On Android it needs nothing extra.
Configuration Summary per File
| What to Change | File Path |
|---|---|
| Backend URL, app name, version — customer; app name, version — delivery | lib/utill/app_constants.dart |
| Backend URL — vendor & delivery | lib/utill/app_config.dart |
| Backend URL, Firebase values, Maps key at build time — customer, vendor & delivery | env.json in the app's root folder (you create it) |
| Backend URL, app name, version — store | lib/core/constants/myntcart_constants.dart — backend URL at build time: --dart-define=BASE_URL=, or BASE_URL in env.json |
| Logo, placeholder, illustrations | lib/utill/images.dart + assets/images/ (store app: assets/images/ only) |
| Android app name (home screen) | android/app/src/main/AndroidManifest.xml — vendor app: APP_NAME in android/local.properties |
| Android package name | android/app/build.gradle — store app: android/app/build.gradle.kts |
| Launcher icon | assets/icon/ (store app: assets/images/appstore.png and assets/icon/adaptive_foreground.png), then dart run flutter_launcher_icons |
| Android Firebase | android/app/google-services.json — customer, vendor & delivery: also the FIREBASE_… values in env.json |
| Android release signing | android/key.properties (you create it) |
| Android Google Maps key | android/local.properties — delivery app: also GOOGLE_MAPS_API_KEY in env.json |
| iOS app name | ios/Runner/Info.plist — vendor app: APP_DISPLAY_NAME in ios/Flutter/Secrets.xcconfig |
| iOS bundle identifier | Xcode → Runner → General → Bundle Identifier |
| iOS launcher icon — store & delivery | ios/Runner/Assets.xcassets/AppIcon.appiconset/ |
| iOS Firebase | ios/GoogleService-Info.plist (customer, vendor) or ios/Runner/GoogleService-Info.plist (delivery) — download your own |
| iOS Google Maps key | ios/Flutter/Secrets.xcconfig |
| App version + build number | pubspec.yaml → version: |
App-Specific Notes
| App | Package | Key Features |
|---|---|---|
| myntcartapp | com.myntcart.app | Shopping, cart, checkout, wallet, order tracking |
| myntcart_store | com.myntcart_store.app | POS, inventory, employees and employee roles. Branches themselves are created in the admin panel, not in the app |
| myntcart_vendor | com.myntcart_vendor.app | Product listing, order processing, earnings, withdrawal |
| myntcart_delivery | com.myntcart_delivery.app | Order pickup, route navigation, delivery confirmation |
Add-on Modules
MyntCart supports premium add-on modules that extend the platform with additional shipping providers, payment gateways, tax systems, and store management capabilities. Each module requires a license key for activation.
Available Modules
There are eight add-on modules. Each is bought separately and only appears in your admin panel once it is installed.
| Module | Description | Key Features |
|---|---|---|
| Shiprocket | Domestic courier aggregation | Ship Now (AWB + pickup), labels, manifests and invoices, NDR status updates by webhook, COD reconciliation, cancellations synced |
| Shiprocket Local Quick | Hyperlocal same-day delivery for local businesses | Instant delivery, real-time tracking, local couriers, cancellations and refunds synced |
| Shadowfax | Two services: Courier and Hyperlocal | Courier: serviceability check, AWB, zone rate card, reverse pickup (returns). Hyperlocal: a rider straight to the customer, priced per trip by Shadowfax. Live tracking and cancellations synced for both |
| Easyship | Global multi-carrier shipping aggregator | Rate comparison, the checkout-quoted courier booked, customs, insurance, label buying and printing, pickups, reconciliation |
| ShipEngine | Multi-carrier shipping with label generation | Label printing, rate shopping, warehouses, reconciliation, tracking webhooks |
| Store Management | Multi-branch store operations with POS | Branch management, store managers, inventory, employees |
| Global Payment Gateways | 6 international payment providers | Adyen, Airwallex, Alipay, Authorize.Net, Checkout.com, Mollie (wallets such as Apple Pay and Google Pay through their hosted payment pages) |
| Commercial Tax | Tax engine for stores outside India — VAT, sales tax, GST/HST, SST | Tax classes with a rate per country, state/province/city rates, tax rules, exempt and reverse-charge customer groups, tax reports |
Courier Modules — What to Set Up
Every courier module follows the hand-off, forward-only status and cancellation rules in Shipping, and its webhook address is listed under Courier Webhook URLs. Each module's settings belong to the store — they are not on the vendor panel. Per module:
Shiprocket
- Orders are sent as Shiprocket's API documents them: a per-unit price with tax included, the weight of the cart items as checkout quoted it, and the box size and fallback pickup address from Shiprocket Settings.
- Ship Now assigns the AWB and books the pickup; labels, manifests and invoices are printed from the module.
- Only signed webhook events count, mapped by Shiprocket's status id. Cancelling an order or a single item cancels it in Shiprocket, and item refunds go to the right customer.
php artisan shiprocket:cancel-orphanslists Shiprocket orders whose order here was deleted; add--cancelto cancel them in Shiprocket.- Vendors see their own orders, store staff their store's.
Shiprocket Local Quick
- Shares one order, pickup and status core with Shiprocket, and sends the order from the pickup it was quoted from.
- A failed delivery fails the order; a cancelled order or item is cancelled in Shiprocket and refunded.
- Store staff see their own store's orders only.
Shadowfax — Courier and Hyperlocal
- Courier uses the Shadowfax Unified API: an AWB per parcel, priced at checkout from the zone rate card under Shadowfax Settings.
- Hyperlocal sends a rider from the pickup straight to the customer, priced per trip by Shadowfax from the map coordinates — or at a Flat Hyperlocal fee you set. It is a separate Shadowfax API: under Shadowfax Management → Shadowfax Settings, enter for each environment the Client code and either a Token or an OAuth client id and secret (Shadowfax issues them when it onboards you for Hyperlocal, and whitelists your server's IP address), save the pickup's Latitude and Longitude (orders filed under a store use that store's position), and switch on Offer Shadowfax Hyperlocal at checkout. Test Hyperlocal connection checks the credentials.
- Both follow the one Environment switch (staging or production), and nothing is sent unless Push orders to Shadowfax is on — on production every push spends Shadowfax credit.
- A cancellation is sent to Shadowfax, and queued if the parcel is already moving. No token or callback key is shown again once saved, and every one of them — courier and Hyperlocal — is stored encrypted. The settings are for the super admin only; staff see their own store.
Easyship
- Handing an order over creates the Easyship shipment with the courier checkout charged for — the cheapest of the couriers you selected.
- The label spends Easyship credit, so by default it is bought by hand: Buy label on Easyship Management → Easyship Orders, then Label to print it. To buy it automatically on hand-over, switch on Buy the label when an order is handed over under Easyship Settings → Default Settings (off by default).
- Cancelling deletes the shipment before a label is bought and cancels it after; once the parcel has left, Easyship refuses.
- Webhooks: Register Endpoint on Easyship Management → Webhooks registers the shipment events, switches the webhook on and saves its signing secret (stored encrypted). Shipments are also re-read every 30 minutes.
- Item values are declared, and quotes asked, in the store's currency; one box per parcel (the fallback box is entered in kg/cm or lb/in and converted); quotes are cached for 10 minutes. The access token is write-only and stored encrypted.
- Account screens (settings, couriers, webhooks, pickup addresses, reconciliation) are for the super admin only; staff see their store's orders and vendors their own shipments.
ShipEngine
- Checkout quotes with ShipEngine's rate estimates, from the warehouse the order will ship from, and charges the cheapest of your selected carriers — the full price, in the store's currency.
- Handing an order over creates the ShipEngine shipment with the carrier and service checkout charged for.
- The label charges your carrier account, so by default it is bought by hand: Buy label on ShipEngine Management → ShipEngine Orders, then Label to print it. To buy it automatically on hand-over, switch on Buy the label when an order is handed over under ShipEngine Settings → Default Shipping Options (off by default).
- Cancelling voids the label (asking the carrier for a refund) and cancels the shipment; once the carrier has the parcel, neither is possible. An order cancelled in MyntCart is withdrawn from ShipEngine too.
- Tracking webhooks — register the Tracking event on ShipEngine Management → Webhooks — move the order forward, out for delivery and returned or lost parcels included. Shipments are also re-read every 30 minutes.
- Shipments are sent in kilograms and centimetres (the fallback box is entered in either unit and converted). The API key is write-only and stored encrypted.
- Account screens (settings, carriers, webhooks, warehouses, reconciliation) are for the super admin only; staff see their store's orders and vendors their own.
How to Install a Module (from Addons Page)
Modules are installed via the Addons page in the admin panel — not by manually copying files. Uploading, publishing and removing a module are for the super admin only.
upload_max_filesize and post_max_size of 20M or more. The Software Update page is stricter and asks for 180M / 200M — setting those once covers both.
Navigate to Addons Page
Go to Admin Panel → MyntCart Addons → Addons. You will see a drag-and-drop upload area and a list of already installed modules below.
Upload Module Zip File
Drag & drop the module .zip file into the upload area, or click "browse file" to select it. Click the Upload button. The system extracts and installs the module into the Modules/ directory automatically.
Publish (Activate) the Module
After upload, the module appears in the installed modules list below. Click the ✓ (checkmark) button to publish/activate the module. This enables its routes and service provider in the application.
php artisan route:cache yourself — run it once more after publishing, or the module's pages are not found.
Module Appears in Sidebar
After publishing, the module's own section appears in the admin sidebar (e.g. Shiprocket Management, Store Management, Commercial Tax Management). The first sub-item is always "Module Activation" with a yellow Required badge — all other features are locked until the license is activated.
Activate License from the Module's Sidebar
Click the module's "Module Activation" menu item in the sidebar → enter the licence key from your CodeMynt purchase email → click Activate. Modules are sold and licensed by CodeMynt only, even when the main application was bought on CodeCanyon; a CodeCanyon purchase code does not activate a module. The key is verified against license.codemynt.in. On success, all locked features unlock immediately and the yellow badge disappears.
After installation, the module files are placed at:
myntcart/
├── Modules/
│ ├── Shiprocket/
│ ├── ShiprocketLocalQuick/
│ ├── Shadowfax/
│ ├── Easyship/
│ ├── ShipEngine/
│ ├── StoreManagement/
│ ├── GlobalPaymentGateways/
│ ├── CommercialTax/
│ └── modules_statuses.json # which modules are switched on
How to Activate a Module License
Installing a module and activating its license are two separate steps. Installation makes the module available; license activation unlocks its features.
Option A — From the MyntCart Modules Page
Navigate to MyntCart Modules
Go to Admin Panel → MyntCart Addons → MyntCart Modules. Every module is listed with its status — installed or not, licensed or not. The number on the menu item is how many modules are currently licensed, so on a fresh install it reads 0 and rises as you activate.
Click "Activate" on the Module
Click the Activate button on the module you want to license. This opens that module's activation page.
Enter the Licence Key
Enter the licence key from your CodeMynt purchase email and click Activate. Modules are licensed by CodeMynt only; the CodeCanyon / Direct choice applies to the main application alone. The key is sent to the CodeMynt licence server at license.codemynt.in, which checks it and binds it to your domain.
Activation Complete
Once the licence server accepts the key, the module is switched on and its licence is recorded on your install. Its sidebar section unlocks and its features become accessible. If the server refuses the key, the page tells you why and nothing is switched on.
.env file's APP_URL — not the address you happen to be browsing. If APP_URL is still the old value after a domain change, or is missing the https://, the licence binds to the wrong name and later health checks fail. Set APP_URL to your live address before activating anything.
Option B — From the Module's Own Sidebar Section
Every installed module also has its own Module Activation menu item inside its sidebar section. For example:
- Store Management section → first item is "Module Activation" — if not licensed, it shows a yellow
Requiredbadge. All other items (Dashboard, Branch Management, etc.) showLicense Requiredand are locked. - Commercial Tax Management section → first item is "Module Activation" — sub-items like Tax Dashboard, Tax Classes show locked until licensed.
- Shiprocket Management section → "Module Activation" with green ✓ (if active) or yellow warning (if not).
Click the Module Activation item → enter your CodeMynt licence key → same activation flow as above.
| Module | Sidebar Section | Activation Path |
|---|---|---|
| Shiprocket | Shiprocket Management | Shiprocket Management → Module Activation |
| Shiprocket Local Quick | Shiprocket Local Quick | Shiprocket Local Quick → Module Activation |
| Shadowfax | Shadowfax Management | Shadowfax Management → Module Activation |
| Easyship | Easyship Management | Easyship Management → Module Activation |
| ShipEngine | ShipEngine Management | ShipEngine Management → Module Activation |
| Store Management | Store Management | Store Management → Module Activation |
| Global Payment Gateways | Global Payment Gateways | Global Payment Gateways → Module Activation |
| Commercial Tax | Commercial Tax Management | Commercial Tax Management → Module Activation |
license.codemynt.in for activation and for the periodic health check. That health check is a scheduled command, so the one-minute cron entry described under Post-Installation must be running — without it the checks never happen. Store Management, Shiprocket, Shiprocket Local Quick, Shadowfax and Easyship are re-checked with the licence server once a day; their screens read the licence recorded on your install, and only an explicit refusal from the licence server switches a module off — a timeout or an outage changes nothing.
How to Deactivate a Module License
Go to MyntCart Modules
Navigate to Admin Panel → MyntCart Addons → MyntCart Modules and open the licensed module with the Manage button.
Click "Deactivate License"
Confirm when asked. The module is switched off on this site straight away and its sidebar items revert to "License Required" locks.
How to Delete / Remove a Module
Option A — From Addons Page (Recommended)
Deactivate License First
Go to MyntCart Modules → Manage → Deactivate License (see above).
Delete from Addons Page
Go to MyntCart Addons → Addons. Find the module in the installed modules list. Click the 🗑️ (delete/trash) icon next to the module name. Confirm the deletion.
Nothing Else to Clear
The page switches the module off and clears the application's cache itself when it removes it. Only if your server runs with a cached route list — you ran php artisan route:cache yourself — run it once more, so the removed module's addresses are dropped.
Option B — Manual Deletion (Server Access)
Deactivate license first
Always deactivate the module license before removing files.
Delete the module folder via terminal
Remove the directory from your server:
# Example: remove Easyship module rm -rf Modules/Easyship # Clear what the framework had cached of it php artisan optimize:clear
Also open Modules/modules_statuses.json and remove that module's line, so the file stops listing a module that is no longer there.
Production Deployment Checklist
- Set
APP_ENV=productionandAPP_DEBUG=false - Set
APP_URLto your live address — module licences bind to this value, not to the address you browse - Configure SSL certificate (HTTPS required)
- Change all default passwords (admin, database)
- Set proper file permissions (644 for files, 755 for directories)
- Add the one-minute scheduler cron —
* * * * * cd /path/to/myntcart && php artisan schedule:run >> /dev/null 2>&1. Licence re-checks, POS online-payment settlement, courier status sync, the sitemap and exchange rates all run from it (the full list is under Post-Installation) - Turn on two-factor authentication for the main admin account and set the login lockout under System Setup → Login Settings → OTP & Login Attempts (see Secure the Sign-ins)
- Set up backup procedures
- Enable proper error logging (disable display_errors)
- Confirm the installer is locked —
/secure-installmust return an error once installation is complete - Configure payment gateway live keys and switch each gateway's mode to Live — PhonePe needs its Standard Checkout v2 credentials and webhook (see PhonePe)
- If you take UPI, set your business UPI ID under Payment Methods → UPI Payments and make sure someone checks the payments queue
- Set the courier hand-off trigger status (Order Management → Shipping Providers) and register each courier's webhook against your live domain (see Courier Webhook URLs)
- Test all SMS and email notifications
- Rebuild each mobile app with your own backend URL, Firebase values and Google Maps key — a release build made without them points at the wrong site
- Verify Firebase push notifications on the customer, vendor and delivery apps
- Test Google Maps in the apps that use it and in the admin panel
Update Guide (Version Upgrade)
How to safely update MyntCart from one version to the next without losing data, settings, or customizations.
Backup Everything
Before touching anything, create a full backup:
# Backup database mysqldump -u root -p myntcart > myntcart_backup_$(date +%Y%m%d).sql # Backup files tar -czf myntcart_files_backup_$(date +%Y%m%d).tar.gz /path/to/myntcart/
Enable Maintenance Mode
Switch maintenance mode on in the admin panel — System Settings → Business Setup → General Settings, the maintenance mode switch — so customers don't see errors during the update. It closes the storefront and the vendor panel to visitors while the admin panel stays open, which the next step needs.
php artisan downUpload the Package on the Software Update Page
Go to Admin Panel → System Settings → Software Update and upload the update zip. The page is for the super admin only. It does the whole update, in this order:
- Verifies the licence you type with the licence server.
- Fetches what the package does not carry — the new version's database migrations, its schema file and its Composer files — from the licence server, for that licence. They are released to a verified licence only, which is why no package holds them.
- Unpacks the package over your installation.
- Runs the migrations and clears the caches.
If the second step cannot be done — your server has no outbound access to license.codemynt.in, or the licence is refused — the update is refused with the licence server's own reason and nothing is changed, so you can put it right and try again.
What the package does and does not replace:
.env— not in the package; your environment configuration stays as it isModules/— not in the package; your installed add-on modules stay as they arestorage/— the package carries only the demo shop's own pictures there. Your uploaded product images and files are not in it and are left alone- Everything else is the product's own code and is replaced,
public/assets/included — keep a copy of any shipped file you changed yourself
php artisan migrate then finds nothing new to run, and pages that need a new column fail. Only the Software Update page fetches the migrations that belong to the package.
Using the Software Update page
The form asks for four things before it will accept a package:
| Field | What to enter |
|---|---|
| Purchase source | CodeCanyon or Direct — where you bought MyntCart |
| Username | Your CodeCanyon username, or the email your direct licence is registered to |
| Purchase key | A CodeCanyon purchase code (the long 8-4-4-4-12 form), or a direct licence key written in four-character groups such as XXXX-XXXX-XXXX-XXXX. Anything else is rejected by the form before verification runs |
| Update package | The .zip you downloaded for the new version |
The page also checks two PHP limits and will not let you submit until both pass — it shows your current values next to the requirement:
upload_max_filesize— 180M or morepost_max_size— 200M or more
Update history
The Software Update page keeps the last 20 attempts — successful and refused alike — with the version it moved from and to, the package name, the files it extracted and the migrations it ran. Expand an entry to see the detail. It is the quickest way to answer "did that update actually apply?" and worth reading before contacting support.
Rebuild the Route Cache, If You Use One
The Software Update page has already run the migrations and cleared the application, view and configuration caches — there is nothing to migrate by hand. One thing it does not rebuild: if your server runs with a cached route list (you ran php artisan route:cache when deploying), run it again now, or the new version's pages are not found:
php artisan route:cache
Disable Maintenance Mode
Bring the site back online: switch maintenance mode off again under System Settings → Business Setup → General Settings.
Verify
Check the admin dashboard — the version number should show the new version. Test key flows: login, product listing, cart, checkout, payment, order processing.
License Information
Regular License
- Use for a single end product (one website/domain)
- A lifetime license — it does not expire
- End product is free for end users (no paid access/subscription)
- Includes all source code, Flutter apps, and documentation
- Includes 6 months of support from CodeMynt, by e-mail or support ticket
- Lifetime updates for the purchased version
Extended License
- Use for a single end product where end users are charged (SaaS, subscription, paid marketplace)
- Everything in Regular License, plus:
- Permission to charge end users for access to the product
localhost install and an install in a subdirectory are each a separate activation, not a free extra. To work on a staging site as well as a live one, either buy a second licence or release the staging activation before activating the live domain. Releasing is done in the licence portal: open the licence, find the activation and release it — the slot is then free for another domain.
What's Included
| Item | Regular | Extended |
|---|---|---|
| Full Laravel source code | ✓ | ✓ |
| 4 Flutter app source code | ✓ | ✓ |
| Admin panel | ✓ | ✓ |
| Add-on modules (8 available) | Sold separately by CodeMynt (not on CodeCanyon) — buy only the ones you need, each with its own lifetime licence key | |
| Documentation | ✓ | ✓ |
| Lifetime license | ✓ | ✓ |
| Lifetime updates | ✓ | ✓ |
| 6 months support, by e-mail or ticket | ✓ | ✓ |
| Charge end users | ✗ | ✓ |
| SaaS / subscription use | ✗ | ✓ |
Support Policy
What's Included in Support
- Bug fixes and troubleshooting for the product as-is
- Help with installation and configuration issues
- Guidance on product features and built-in functionality
- Assistance with updating to the latest version
- Module activation and license issues
What's NOT Included in Support
- Custom feature development or modifications
- Third-party plugin/service integration beyond what's built-in
- Server setup, hosting configuration, or domain management
- Design customization (CSS, theme modifications, custom layouts)
- Data migration from non-WooCommerce platforms
- Issues caused by modifying the source code
How to Get Support
| Channel | Details | Response Time |
|---|---|---|
| support@codemynt.in | Within 24–48 hours (business days) | |
| License Portal | license.codemynt.in → Support Ticket | Within 24 hours |
| Documentation | This documentation site | Self-service (instant) |
Demo Access
| Panel / App | URL / Access | Credentials |
|---|---|---|
| Admin Panel | https://yourdomain.com/login/admin | Email: admin@admin.com / Password: password |
| Customer Website | https://yourdomain.com | Register a new account or use demo credentials |
| Vendor Panel | https://yourdomain.com/vendor/auth/login | Register as vendor or contact admin for credentials |
| Customer App | myntcartapp (Flutter) | Register via app or use website credentials |
| Vendor App | myntcart_vendor (Flutter) | Use vendor panel credentials |
| Store App | myntcart_store (Flutter) | Assigned by admin (store manager account) |
| Delivery App | myntcart_delivery (Flutter) | Assigned by admin (delivery man account) |
admin@admin.com / password) do not open the panel: the first sign-in takes you to a page that asks for a password of your own, and you then sign in with that one. Do it straight after installing — until you have, anyone who knows the shipped password can do it in your place. The demo vendor (seller@example.com) and demo customer (customer@example.com) ship with the same password; each asks for a new one the first time it is used, and only in a browser where you are signed in to the admin panel. The apps refuse the shipped password. A demo site (APP_MODE=demo) is the exception: there these accounts sign in as shipped.
Frequently Asked Questions
Can I use MyntCart on multiple domains?
No. A licence key activates against one domain at a time, and a subdomain or a localhost install counts as a separate domain. For a second live site, buy a second licence; to move an existing licence, release the old activation in the licence portal first.
Do I get the full source code?
Yes. You receive complete unencrypted source code for the Laravel backend, admin panel, user website, and all 4 Flutter mobile apps.
Are updates free?
Yes. All future updates for the version you purchased are free and lifetime. Download new versions from license.codemynt.in.
Can I customize the code?
Yes. You have full access to the source code and can modify it freely. However, support does not cover issues caused by custom code modifications.
What PHP version is required?
PHP 8.3 or newer. MyntCart is built on Laravel 13, which needs PHP 8.3, and the installer's requirements check rejects anything below 8.3.0. All four apps require Flutter SDK 3.47.0+ with JDK 17.
Does it work on shared hosting?
Yes. MyntCart works on shared hosting (cPanel) as long as your host supports PHP 8.3+ and MySQL 8.0 (not MariaDB), lets you add a cron job that runs every minute, and allows SSH/terminal access for artisan commands. VPS or dedicated hosting is recommended for better performance.
What is MyntCart built with?
A Laravel 13 backend on PHP 8.3+ and MySQL 8. The admin and vendor panels use Bootstrap 5.3.3 with jQuery 4 and DataTables 3; the storefront themes are on Bootstrap 5 too (Classic and Modern load jQuery 3.7.1, Semi-Classic loads no jQuery at all). Every stylesheet and script ships pre-built — there is no Laravel Mix or webpack build, and you never need to run npm.
Do I need a cron job?
Yes — one entry that runs php artisan schedule:run every minute. Licence re-checks, settling POS online payments, courier status catch-up, the sitemap and exchange rates all run from it; without it none of them happen, and the store stops working once the licence grace period lapses. See Post-Installation for the line to add and the full list of jobs.
How do I turn on two-factor sign-in?
Each person turns it on for their own account with any authenticator app: admins and employees from the admin panel's profile menu → Two-Factor Authentication, vendors from the vendor panel's profile menu, customers under My Account → Two-Factor Authentication on the storefront or in the customer app's settings. Save the recovery codes it shows — each works once if the phone is lost. See Secure the Sign-ins.
Can customers pay by UPI without a payment gateway?
Yes. Switch on System Settings → Payment Methods → UPI Payments with your business UPI ID. Customers pay from any UPI app into your bank account and submit the UTR; you verify it on the UPI Payments screen. The same UPI ID works at the admin, vendor, store app and vendor app tills. UPI is in Indian rupees only. See UPI Payments.
How do I publish the Flutter apps to Play Store / App Store?
Follow the Flutter app configuration guide above (backend URL, package name, app name, icons, Firebase, Maps key), build the release APK/IPA, then upload to Google Play Console or Apple App Store Connect. Standard store submission process applies.
Is RTL (right-to-left) language supported?
Yes on the web — the storefront and admin panel mirror their layout for RTL languages (Arabic, Hebrew, Urdu, etc.). Add RTL languages via System Settings → Language. In the Flutter apps RTL is supported per screen rather than as a full mirrored layout, so expect to adjust some screens for an RTL-first audience.
Can I migrate from WooCommerce?
Partly. The built-in importer reads WooCommerce's CSV exports and brings in products — including variations — and the categories they belong to. Customer accounts are not imported. See Data Import Tools documentation.
How do I get my license key if I lost it?
Log into license.codemynt.in → My Purchases. Your license key is always available there. If you can't access your account, email support@codemynt.in with your purchase email.