v1.0.0

Prerequisites

Important
Please ensure all prerequisites are met before proceeding with the installation.

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

RequirementMinimumRecommended
PHP8.38.3 or newer
MySQL8.08.0 or newer
Web ServerApache 2.4 or Nginx 1.18Latest stable
RAM2 GB4 GB+
Disk Space10 GB20 GB+ (for product images & assets)
PHP ExtensionsOpenSSL, PDO, Mbstring, Tokenizer, XML, GD, cURL, Fileinfo, BCMath, JSON, Zip, Ctype, Intl, MySQLi
SSL CertificateRequired for productionLet's Encrypt (free) or commercial
CronOne 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.

MySQL 8.0 is a hard requirement — MariaDB is not supported
Product and shop filtering is built on the 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.
You do not need Composer or Node.js
The download ships with its PHP dependencies already in place and with every stylesheet and script pre-built, so there is nothing to compile — no theme, stylesheet or panel script is built on your server, and there is no Laravel Mix or webpack step. Composer matters only to a developer changing PHP dependencies, and Node.js only to one rebuilding the admin and vendor panels' bundled library file with npm run prod.

Verify your PHP version:

Terminal
php -v

Installation

Install MyntCart, verify your licence and configure Business Settings
Video walkthrough coming soon. The written steps below cover everything the video will show.

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

1

Visit the License Portal

Go to https://license.codemynt.in — the official CodeMynt licence portal. Create an account or log in.

2

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)

1

Buy on CodeCanyon and download

Buy MyntCart on CodeCanyon as usual. The project zip is under Downloads on your Envato account.

2

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.

Add-on modules are a CodeMynt purchase either way
Whichever route you bought MyntCart through, every add-on module (Shiprocket, Easyship, Store Management and the rest) is bought and licensed on license.codemynt.in, each with its own licence key. A CodeCanyon purchase code does not activate a module.
Keep Your License Key Safe
Your purchase key is required during installation. Direct buyers can re-read it under My Purchases on the portal; CodeCanyon buyers can re-read it on their Envato Downloads page. Store it securely all the same.

Pre-Installation — Upload Files to Server

Localhost (WAMP / XAMPP / Laragon)

  1. Extract the MyntCart zip file
  2. Copy the project folder to your web server root:
Paths
# WAMP
C:\wamp64\www\myntcart\

# XAMPP
C:\xampp\htdocs\myntcart\

# Laragon
C:\laragon\www\myntcart\
  1. Create an empty database named myntcart in phpMyAdmin (collation: utf8mb4_unicode_ci)
  2. Open your browser and go to: http://localhost/myntcart/secure-install

cPanel / Shared Hosting

  1. Login to cPanel → File Manager → Navigate to public_html
  2. Upload the MyntCart zip and extract it
  3. Create MySQL database: cPanel → MySQL Databases → Create DB + User → Add user with ALL PRIVILEGES
  4. Open your browser and go to: https://yourdomain.com/secure-install

VPS / Dedicated Server

  1. Install PHP 8.3+, MySQL 8.0+, Apache/Nginx, and required PHP extensions
  2. Upload/clone the project to your server (e.g. /var/www/myntcart)
  3. Point your virtual host / Nginx server block to the public directory
  4. Set permissions: chmod -R 775 storage bootstrap/cache
  5. Configure SSL (Let's Encrypt recommended)
  6. 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.

A

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.

  1. Open phpMyAdmin (http://localhost/phpmyadmin)
  2. Click "New" in the left sidebar
  3. Enter database name: myntcart
  4. Select collation: utf8mb4_unicode_ci
  5. Click "Create"
  1. Login to cPanel → MySQL Databases
  2. Under "Create New Database" → enter name (e.g. username_myntcart) → click Create Database
  3. Under "MySQL Users" → create a new user with a strong password
  4. Under "Add User To Database" → select your user + database → grant ALL PRIVILEGES → click Make Changes
MySQL
-- 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;
B

Configure the .env File

In the MyntCart project root, copy .env.example to .env and update the following values with your actual credentials:

This step is mandatory, not optional
The .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.
.env
# 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
Leave HMAC_SIGNING_KEY as it came
Every call MyntCart makes to the licence server is signed with this key. It comes already filled in, in the .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.
Installing on plain HTTP
The sample file ships 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.
cPanel users
On shared hosting, the database name and username are prefixed with your cPanel username (e.g. cpaneluser_myntcart and cpaneluser_dbuser). Use the full prefixed names in .env.
C

Open the Installer

Now open your browser and navigate to the secure installer URL:

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.

The installer session expires after 1 hour
Each installation session is valid for 60 minutes counted from the moment you start — working steadily does not extend it. If it expires you are returned to the start, although the License step will quietly start a fresh session for you rather than failing. Have your licence key and database credentials ready before you begin.

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/ and bootstrap/cache/
  • Your .env file 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.

Security
Verification happens on the CodeMynt licence server — it decides whether a code is genuine, so there is nothing to bypass locally. Your server must have outbound internet access to 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
Disk Space
The installer checks available disk space before downloading. Ensure you have at least 500MB free on your server.

Database Setup

Enter your database connection details. The installer tests the connection before proceeding:

FieldValueNotes
Database Hostlocalhostor 127.0.0.1
Port3306Default MySQL port
Database NamemyntcartThe empty database you created earlier
UsernamerootYour 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
Important
This step writes all 215 tables into your database. It does not clear what is already there — on a database that already has tables the import collides with them and fails or leaves duplicated rows behind. Always use a fresh, empty database.

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".

FieldValue
Admin Panel URLhttps://yourdomain.com/login/admin
(or http://localhost/myntcart/login/admin)
Emailadmin@admin.com
Passwordpassword
First thing to do
Sign in. The password above does not open the panel — it takes you to a page where you choose your own, and you then sign in with that one.
Re-running the installer
On completion the installer writes a lock file and terminates the installation session, so /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.

A

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:

Cron
# 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:

JobWhenWhat it does
pos:settle-online-paymentsEvery 5 minSettles till sales left waiting on PhonePe, Razorpay or Tap to Pay — paid when the gateway confirms, stock given back when it refuses
gateways:reconcile-webhooksEvery 5 minGlobal Payment Gateways: applies payment webhooks that were received but not processed — a confirmed payment still becomes an order
shadowfax:sync-shipmentsEvery 15 minRe-reads live Shadowfax shipments, Courier and Hyperlocal
shiprocket-quick:reconcileEvery 30 minShiprocket Local Quick tracking catch-up
easyship:sync-shipmentsEvery 30 minRe-reads live Easyship shipments
shipengine:sync-shipmentsEvery 30 minRe-reads live ShipEngine shipments — each label's tracking, and shipments labelled or cancelled in ShipEngine's own dashboard
shiprocket:reconcileHourlyShiprocket catch-up for webhooks that arrived but could not be applied
sitemap:generateDaily 03:30Rebuilds sitemap.xml
currency:refresh-ratesDailyRefreshes exchange rates — does nothing unless automatic rate updates are switched on (off by default)
license:checkDailyRe-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:40DailyModule 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-expiryHourlyLicence status report to the log, and the recorded expiry date applied — no licence-server call for modules
license:monitor-expiry / license:health-checkDaily 09:00 / Mondays 08:00Licence expiry notices and a weekly licence health report
commercial-tax:verify-license / commercial-tax:report-usageEvery 6 hours / Daily 00:00The Commercial Tax module's own licence re-check and its daily usage report
B

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:

Terminal
php artisan queue:work --tries=3
C

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://.

D

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.

E

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.

Configure MyntCart: environment, Firebase, Google Maps, reCAPTCHA, SMS, WhatsApp, shipping and add-ons
Video walkthrough coming soon. The written steps below cover everything the video will show.

Database Configuration

.env
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

.env
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
Three keys that surprise people
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

.env
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

.env
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"
Mail is normally set from the admin panel
Admin Panel → System Settings → 3rd Party & Other Configs → Mail Config holds the same SMTP details, and what you save there takes precedence over these .env lines at run time. Use the admin screen unless you have a reason not to.

File & Folder Permissions

Never use 777 permissions
This is a major security vulnerability. Use the recommended permissions below.
PathPermissionPurpose
storage/775Cache, logs, sessions
storage/app/public/775Every uploaded file — product images, banners, documents
bootstrap/cache/775Framework bootstrap cache
.env644Environment config (sensitive) — must also be writable by the PHP user while you install, because the installer rewrites it
artisan755Laravel CLI entry point
Uploads do not live in public/assets
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.
Terminal
# 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

1

Go to Google Cloud Console

Open console.cloud.google.com → Sign in with your Google account.

2

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 NameUsed For in MyntCart
Maps JavaScript APIWebsite — displaying maps (store locator, checkout address picker, admin delivery map)
Places APIWebsite — address autocomplete / search-as-you-type on checkout and address forms
Geocoding APIWebsite — converting addresses to lat/long coordinates and vice versa
Distance Matrix APIWebsite — delivery distance and time between the store and the delivery rider
Maps SDK for AndroidFlutter apps only — maps in the Android builds (customer, vendor, store, delivery)
Maps SDK for iOSFlutter apps only — maps in the iOS builds
Directions APIFlutter 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
Enable the four the website needs
The website uses Maps JavaScript, Places, Geocoding and Distance Matrix — enable all four, or the related feature breaks silently: maps won't load, autocomplete won't work, or delivery estimates fail. Add the Android and iOS SDKs and the Directions API only if you are also shipping the mobile apps. There is no need for the Geolocation API: when the site asks for a visitor's current position it uses the browser's own location permission, not a Google call.

3. Create an API Key

1

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)

1

Click "Edit API Key"

Click on your newly created API key → "Edit" or the pencil icon.

2

Application Restrictions

The website uses two keys. For the client key (the one the browser loads maps with): Select "HTTP referrers (websites)" → Add:

Allowed Referrers
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.

3

API Restrictions

Select "Restrict key" → Check only the APIs you enabled above. Click Save.

Separate key for Flutter apps
For Flutter apps, create a second API key restricted to "Android apps" (by package name) and a third key restricted to "iOS apps" (by bundle ID). This is more secure than using one unrestricted key everywhere.

5. Enable Billing

1

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.

2

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:

FieldWhat to enterRequired?
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 IDA 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.

Do not leave the server key blank
Maps will still appear if only the client key is filled in, so an empty server key is easy to miss. But address autocomplete, address-to-coordinate lookups and delivery distance all run from the server key and will quietly return nothing without it.

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:

android/local.properties
# 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:

ios/Flutter/Secrets.xcconfig
# 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

WhereFile / LocationKey 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.propertiesAndroid apps restricted key
iOS apps (customer, vendor, delivery)ios/Flutter/Secrets.xcconfigiOS apps restricted key

reCAPTCHA Setup (Complete Guide)

Google reCAPTCHA protects login, registration, contact, and checkout forms from spam bots.

1. Go to reCAPTCHA Console

1

Open reCAPTCHA Admin

Go to google.com/recaptcha/admin → Sign in with your Google account.

2. Create a New Site

1

Click "+" (Create)

Click the "+" button to register a new site.

2

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:
Domains
yourdomain.com
www.yourdomain.com
localhost
staging.yourdomain.com
3

Accept Terms & Submit

Check "Accept the reCAPTCHA Terms of Service" → Click Submit.

3. Copy Your Keys

After submission, Google shows two keys:

KeyWhere It's UsedExample
Site KeyFrontend HTML — displayed to the user in the reCAPTCHA widget6LcXXXXXXXXXXXXXXXXXXXXXXX
Secret KeyServer-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.

  1. Go to Admin Panel → System Settings → 3rd Party & Other Configs → Recaptcha
  2. Enter Site Key and Secret Key
  3. Select status: Active
  4. Click Save
Where reCAPTCHA appears
Once enabled, the "I'm not a robot" checkbox appears on: customer login, customer registration, vendor registration, contact us form, forgot password page, and the admin and vendor panel login pages. No code changes needed — it's automatic.

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
Stay on reCAPTCHA v2
MyntCart works with the v2 "I'm not a robot" checkbox only. Swapping in a v3 key from the Google console breaks the widget — the box stops appearing and the forms it protects stop submitting.

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

1

Go to Firebase Console

Open console.firebase.google.com → Sign in with your Google account → Click "Create a project" (or "Add project").

2

Enter Project Name

Name your project (e.g. myntcart). Firebase auto-generates a Project ID below. Click Continue.

3

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)

1

Register Web App

In the project dashboard, click the Web icon (</>) → Enter nickname: MyntCart Web → Click Register app.

2

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 fieldWhere to Find in Firebase ConsoleExample Value
API KeyProject Settings (⚙ gear icon) → General tab → scroll to "Your apps" → Web app → apiKeyAIzaSyDSb3S-PbqQC-xxxxx
Auth DomainSame location → authDomainmyntcart.firebaseapp.com
Project IDSame location → projectId (also visible at top of Project Settings page)myntcart
Storage BucketSame location → storageBucketmyntcart.firebasestorage.app
Messaging Sender IDSame location → messagingSenderId (also shown in Cloud Messaging tab as "Sender ID")540949947647
App IDSame location → appId1: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 ContentProject 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.

If you cannot find the menu item
Push Notifications Setup sits behind the Promotion Management permission. An admin employee whose role does not include it will not see the menu item at all — sign in as an administrator with that permission.

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)".

1

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.

2

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.

3

Save

Click Save. Push notifications to the apps are now live.

Keep the service account key secure
That JSON grants full access to your Firebase project. Never commit it to Git, never expose it publicly, and never share it. Delete the downloaded copy from your computer once it is saved in the admin panel.

6. Authentication — Enable Sign-in Methods

Navigate to Build → Authentication → Sign-in method in Firebase Console. Enable each method MyntCart needs:

MethodUsed ForHow to Enable
PhoneOTP login in all Flutter appsClick Phone → Enable toggle → Save. No extra config needed.
GoogleGoogle sign-in on customer app & websiteClick Google → Enable → Select support email → Save. Add SHA-1 key for Android (see below).
Email/PasswordEmail-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 apiKey value 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:

AppAndroid Package NameiOS Bundle ID
myntcartapp (Customer)com.myntcart.appcom.myntcart.app
myntcart_vendorcom.myntcart_vendor.appcom.myntcart-vendor.app
myntcart_deliverycom.myntcart_delivery.appcom.myntcart-delivery.app

Register Android App

1

Open Project Settings

In Firebase Console → Project Settings (⚙ gear) → General tab → scroll to "Your apps"

2

Add Android App

Click "Add app" → Select Android icon

3

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").

4

Enter SHA-1 Fingerprint

Enter your SHA-1 fingerprint (required for Google Sign-In — see step 9 below)

5

Register & Download Config

Click Register app → Download google-services.json → Place at android/app/google-services.json in the Flutter project

6

Skip SDK Steps

Firebase shows "Add Firebase SDK" steps — skip these (Flutter already has it) → Click Continue to console

Register iOS App

1

Add iOS App

Click "Add app" → Select iOS icon

2

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.

3

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

4

Skip & Finish

Skip the remaining SDK steps → Click Continue to console

Repeat for all 3 apps
You need to register 6 apps total in Firebase (3 Android + 3 iOS) — the customer, vendor and delivery apps. The store app does not use Firebase. Each app gets its own 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)

File Paths
# 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:

Command Prompt
keytool -list -v -keystore %USERPROFILE%\.android\debug.keystore -alias androiddebugkey -storepass android -keypass android
Terminal
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
Terminal
# 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.

  1. Copy the SHA1 fingerprint from the output (format: XX:XX:XX:...:XX)
  2. Go to Firebase Console → Project Settings → Your apps → select the Android app
  3. Click "Add fingerprint" → Paste the SHA-1 → Save
  4. For Play Store release, add the release keystore SHA-1 too
  5. 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:

ConfigWhere in Admin PanelWhat to Enter
Push NotificationsSystem Settings → 3rd Party & Other Configs → Push Notifications SetupService Account JSON, API Key, Auth Domain, Project ID, Storage Bucket, Messaging Sender ID, App ID, Measurement ID (optional)
Firebase AuthSystem Settings → 3rd Party & Other Configs → Firebase AuthOTP on/off, and the Web API Key
Nothing Firebase-related goes in .env
There are no 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

WhatWhere to ConfigureSource in Firebase Console
Web API Key, Project ID, etc.Admin Panel → Push Notifications SetupProject Settings → General → Your apps → Web app config
Web API Key (for phone OTP)Admin Panel → Firebase AuthProject Settings → General → Your apps → Web app apiKey
Service Account JSONAdmin Panel → Push Notifications Setup → pasted into "Service Account Content"Project Settings → Service accounts → Generate new private key
Auth methodsFirebase Console directlyBuild → Authentication → Sign-in method
Android config (per app)android/app/google-services.jsonProject Settings → Your apps → Android app → Download
iOS config (per app)ios/Runner/GoogleService-Info.plistProject Settings → Your apps → iOS app → Download
SHA-1 fingerprintFirebase Console → Android app → Add fingerprintGenerated 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
2Factor019 SMS
BirdClickSend
D7 NetworksFast2SMS
Global SMSGupshup
HubtelInfobip
MSG91Nexmo (Vonage)
ParadoxPlivo
Signal WireSinch
SMS ToTelesign
TelnyxTwilio

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

1

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.

2

Get Your Account Credentials

After login, you land on the Twilio Console Dashboard. Your credentials are shown right on this page:

CredentialWhere to FindExample
Account SIDTwilio Console → Dashboard → "Account SID" (shown at top)ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Auth TokenSame page → Click "Show" next to Auth Token to reveal itxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keep Auth Token secret
Your Auth Token grants full API access to your Twilio account. Never share it, commit it to Git, or expose it in frontend code.

2. Enable WhatsApp Sandbox (for Testing)

1

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.

2

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.

3

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)

1

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.

2

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).

3

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

1

Open Twilio WhatsApp Config

Go to Admin Panel → System Settings → 3rd Party & Other Configs → Twilio WhatsApp Config.

2

Enter Credentials

Fill in the following fields:

FieldValueWhere to Get
Credentials SourceOwn credentials or SMS gatewayChoose "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 SIDACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTwilio Console → Dashboard (not needed if you picked "SMS gateway" above)
Twilio Auth TokenxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTwilio Console → Dashboard → Click "Show" (not needed if you picked "SMS gateway" above)
WhatsApp From Number+919876543210Your approved WhatsApp Business number (or sandbox number for testing)
Content SIDHXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTwilio Console → Content Template Builder. Meta requires an approved template for any message your business starts — without one Twilio refuses business-initiated messages.
Content VariablesJSON, e.g. {"1":"order_id"}Optional. Maps values into the numbered placeholders of your approved template.
3

Toggle Active & Save

Toggle the status to Active → Click Save. WhatsApp messaging is now enabled.

4

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.

The next two steps need the Store Management module
Store-level WhatsApp numbers and Bulk WhatsApp are part of the Store Management module. If you did not purchase it, the Store Management menu will not appear and you can skip to the feature table below.

5. Configure Store-Level WhatsApp Numbers

Each store branch can have its own WhatsApp number for receiving orders and customer messages.

  1. Go to Admin Panel → Store Management → Store Settings (or select a specific store)
  2. Find the WhatsApp Number field
  3. Enter the store's WhatsApp number with country code (e.g. +919876543210)
  4. Click Save

6. Test WhatsApp Messaging

  1. Go to Admin Panel → Store Management → Bulk WhatsApp
  2. Select a store with a configured WhatsApp number
  3. Enter a test message
  4. Click Preview to see the formatted WhatsApp message
  5. 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

FeatureDescriptionWhere in Admin
Bulk WhatsApp OrdersSend orders to multiple stores at once via WhatsApp with customizable messages (Store Management module)Store Management → Bulk WhatsApp
New Order NotificationMessage to the fulfilling store with order ID, items, total, payment method and address when an order is placedAutomatic, once "Notify stores" is switched on
Order Status UpdatesMessage to the store when an order moves to packed, out for delivery, delivered or cancelledAutomatic, once "Notify stores" is switched on
Store Notification TemplatesSingle-brace placeholders: {store_name}, {order_id}, {customer_name}, {customer_phone}, {total}, {payment_method}, {address}, {timestamp}Used by the automatic store notifications above
Customer WhatsApp TemplatesDouble-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 WhatsAppEach 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 soThe store's WhatsApp number (Store form); a vendor's shop contact number; Social Media Settings → Social Media Chat, else the company phone
Invoice SharingShare order invoices and receipts directly to customer's WhatsAppOrder Details page
Chat WidgetFloating WhatsApp chat button on storefront for instant supportSocial Media Settings → Social Media Chat

Twilio Pricing

Cost
Twilio charges per WhatsApp message sent, and business-initiated messages (order updates) cost more than customer-initiated replies. Rates and trial credit vary by country and change over time — check Twilio WhatsApp Pricing for the current figures before you switch store notifications on.

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

  1. Go to Admin Panel → System Settings → Payment Methods → Digital Payment Methods
  2. Fill in the gateway's credentials and choose the Mode: Test while you try it, Live for real payments
  3. 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.

FieldWhat to enter
Client Id / Client SecretThe Standard Checkout v2 client credentials PhonePe issues you. Both are required — without them PhonePe is not offered.
Client VersionThe client version issued with them (treated as 1 when left blank)
Merchant IdYour PhonePe merchant ID — the customer app's PhonePe SDK starts with it
Webhook Username / Webhook PasswordThe 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.
ModeTest uses PhonePe's sandbox; Live takes real payments

Give PhonePe this webhook URL:

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

  1. Go to Admin Panel → System Settings → Payment Methods → UPI Payments
  2. 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
  3. Switch on Show Pay with UPI at checkout and click Save
UPI moves Indian rupees only
Every amount is converted to rupees: as it is when your default currency is INR, otherwise through the INR exchange rate — so add the Indian rupee (INR) with its exchange rate under System Setup → Currency. A store that cannot express a price in rupees does not offer UPI. While UPI Payments is switched off or has no UPI ID, every checkout and till answers "UPI payment is not available right now".

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

TillPaid intoHow the sale is recorded
Admin POS (web)The platform's UPI IDPayment 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 itThe 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 POSThe platform's UPI IDThe 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 POSThe platform's UPI IDServer-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

1

Access Settings

Go to Admin Panel → Order Management → Shipping Calculator to view all available adapters and their status.

2

Enable & Prioritize

Toggle each adapter on/off and set priority numbers (lower = higher priority). The system processes adapters in priority order.

3

Test Connection

Use the Test button for each adapter to verify API credentials and connectivity before going live.

Available Shipping Adapters
Manual (custom flat rates) is always present and is the last-resort fallback. The other five are separately purchasable modules and only appear once the module is installed: Shiprocket (domestic courier aggregation), Shiprocket Local Quick (hyperlocal same-day), Shadowfax (two services: Courier, with AWBs and returns, and Hyperlocal, a rider straight to the customer — each quotes as its own adapter), Easyship (global multi-carrier) and ShipEngine (global multi-carrier with labels). All five are fully working — none is a preview.
AdapterModule requiredDefault priority
Shiprocket Local QuickShiprocket Local Quick5
Shadowfax (Courier)Shadowfax5
Shadowfax HyperlocalShadowfax — offered only when "Offer Shadowfax Hyperlocal at checkout" is on5
ShiprocketShiprocket10
EasyshipEasyship20
ShipEngineShipEngine30
ManualNone — always available100 (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.

CourierWebhook URLWhere to register it
Shiprockethttps://yourdomain.com/api/parcel-tracking/webhookShiprocket 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 Quickhttps://yourdomain.com/api/v1/local-delivery/webhookA 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 Courierhttps://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 Hyperlocalhttps://yourdomain.com/api/shadowfax/hyperlocal/webhook/production
(…/webhook/staging for staging)
Give it to Shadowfax with the Hyperlocal callback key set under Shadowfax Settings
Easyshiphttps://yourdomain.com/api/easyship/webhookPress Register Endpoint on Easyship Management → Webhooks — it registers the URL, switches the webhook on and saves its signing secret
ShipEnginehttps://yourdomain.com/api/shipengine/webhookShipEngine 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

ToolRequired VersionNotes
Flutter SDK3.47.0 or higherStable channel. One release builds all four apps
Dart SDKBundled with FlutterDart 3.13 comes with Flutter 3.47 — no separate install needed
Java JDKJDK 17All four apps compile against Java 17
Android StudioLatest stable releaseWith Flutter & Dart plugins installed
Android SDKPlatform 37 (Android 17)Install via Android Studio → SDK Manager → SDK Platforms. All four apps compile against it
Gradle, Android Gradle Plugin, KotlinNothing to installEach project names its own versions and the first build downloads them — they are listed in the table below
Xcode15.0+, 16 recommended (macOS only)Required for iOS builds
CocoaPodsLatest (macOS only)sudo gem install cocoapods. Not needed for the store app: its plugins come as Swift packages and it has no Podfile
One Flutter release and one JDK build all four apps
All four apps need Flutter 3.47 or newer and compile against Java 17. Install JDK 17 and point JAVA_HOME at it; building on JDK 11 fails in Gradle. An older Flutter release stops at flutter pub get.
AppFlutterJavaGradle / Android Gradle Plugin / KotlinAndroid SDK: compile / target / minimumiOS minimum
myntcartapp (Customer)3.47.0+JDK 179.3.1 / 9.1.1 / 2.3.2137 / 37 / 24 (Android 7.0)15.0
myntcart_vendor3.47.0+JDK 179.3.1 / 9.1.1 / 2.3.2137 / 37 / 26 (Android 8.0)15.0
myntcart_store3.47.0+JDK 179.3.1 / 9.1.1 / 2.3.2137 / 37 / 26 (Android 8.0)15.0
myntcart_delivery3.47.0+JDK 179.3.1 / 9.1.1 / 2.3.2137 / 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)

1

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).

PowerShell
# Extract to C:\flutter (or your preferred path)
# Then add to System PATH:
C:\flutter\bin
2

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.

System Environment Variables (Windows)
# Set JAVA_HOME (System Variable)
JAVA_HOME = C:\Program Files\Java\jdk-17

# Add to PATH (System Variable)
%JAVA_HOME%\bin
3

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.

4

Install Flutter & Dart Plugins

Open Android Studio → File → Settings → Plugins → Search "Flutter" → Install (it auto-installs the Dart plugin too). Restart Android Studio.

5

Configure System Environment Variables

Open System Properties → Environment Variables and add/update these:

VariableValue (example path)Type
JAVA_HOMEC:\Program Files\Java\jdk-17System Variable
ANDROID_HOMEC:\Users\YourName\AppData\Local\Android\SdkSystem Variable
PATH (append)C:\flutter\binSystem Variable
PATH (append)%JAVA_HOME%\binSystem Variable
PATH (append)%ANDROID_HOME%\platform-toolsSystem Variable
6

Verify Installation

Open a new terminal window (old ones don't see PATH changes) and run:

Terminal
# 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)

1

Download & Extract Flutter

Download Flutter SDK and extract to your home directory (e.g. ~/flutter). Add to PATH in your shell profile.

~/.zshrc (or ~/.bash_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"
2

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.

3

Install Xcode & CocoaPods

Xcode is required for building iOS apps. It's only available on macOS.

  1. Open the Mac App Store → Search "Xcode" → Click Get / Install (it's free, ~12 GB download)
  2. Wait for installation to complete (can take 20–40 minutes)
  3. Open Xcode once after installation → Accept the license agreement → Let it install additional components
  4. Set Xcode command line tools — open Terminal and run:
Terminal
# 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
  1. Verify Xcode installation:
Terminal
# Check Xcode version
xcodebuild -version
# Should show: Xcode 15.x or higher

# Check CocoaPods version
pod --version
# Should show: 1.x.x
Apple Silicon Macs (M1/M2/M3/M4)
If you're on an Apple Silicon Mac, you may need to run Terminal via Rosetta for some older CocoaPods commands, or install using Homebrew (brew install cocoapods) which works natively on ARM.
4

Install Android Studio + Plugins

Same as Windows — install Android Studio, then install Flutter & Dart plugins from Settings → Plugins.

5

Verify

Run source ~/.zshrc then flutter doctor — fix any issues it reports. Accept Android licenses: flutter doctor --android-licenses

Import Project into Android Studio

  1. Open Android Studio → File → Open
  2. Browse to the project folder (e.g. E:\AppDevelopment\CodeMynt\myntcartapp)
  3. Select the root folder that contains pubspec.yaml — click OK
  4. Android Studio detects it as a Flutter project and loads it
  5. Wait for "Running pub get..." to finish (bottom status bar)
  6. If prompted to configure Dart/Flutter SDK path → point to C:\flutter
  7. Connect a device or start an emulator → Click the green Run ▶ button
  1. Open Android Studio → File → Open
  2. Browse to the project folder (e.g. ~/Projects/myntcartapp)
  3. Select the root folder that contains pubspec.yaml — click Open
  4. Android Studio detects it as a Flutter project and loads it
  5. Wait for "Running pub get..." to finish
  6. For iOS: run cd ios && pod install && cd .. in the terminal (not for the store app, which has no Podfile)
  7. Select target device (Android emulator or iOS Simulator) → Click Run ▶
First time opening?
The first build takes 3–10 minutes as Gradle downloads all dependencies. Subsequent builds are much faster. If the build fails, 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.

Terminal
# 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.

env.json (customer app)
{
  "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.

Always pass your own backend URL
All four apps carry a fallback address that is not your site, so a plain 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.

AppConfig fileClassBackend URL field
myntcartapp (Customer)lib/utill/app_constants.dartAppConstantsbaseUrl
myntcart_vendorlib/utill/app_config.dartAppConfigbaseUrl (re-exported as AppConstants.baseUrl)
myntcart_storelib/core/constants/myntcart_constants.dartMyntcartConstantsbaseUrl
myntcart_deliverylib/utill/app_config.dartAppConfigbaseUrl (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:

lib/utill/app_constants.dart (customer app)
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 defaultValue with your own URL (no trailing slash), or
  • Leave the file alone and give the app its address at build time: BASE_URL in env.json for the customer, vendor and delivery apps, --dart-define=BASE_URL=https://yourdomain.com (or BASE_URL in its own env.json) for the store app, on every flutter run and flutter build.
ConstantWhat to ChangeNotes
appNameYour brand name displayed inside the app (splash screen, headers, about page)Present in all four apps
sloganShort tagline shown below the logo on the splash screenCustomer app only. The vendor, store and delivery apps have no tagline constant
appVersionCurrent version — update on each release to match pubspec.yamlShips as 1.0.1 (customer), 1.0.2 (vendor), 1.0.0 (store), 1.0 (delivery)
Backend URLYour MyntCart site address, no trailing slashField name and file differ per app — see the table above
Backend URL — common mistake
Do NOT use 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.

ImageFile PathUsage
App Logoassets/images/logo.pngMain logo used inside the app (splash, about, headers)
Placeholder (square)assets/images/placeholder_1x1.pngDefault placeholder for product images that haven't loaded yet
Placeholder (banner)assets/images/placeholder_3x1.pngPlaceholder for banners and wide images
Login / Signupassets/images/login.png, signup.pngIllustrations on the login and registration screens
OTPassets/images/otp_login.pngIllustration on the one-time code screen
Onboardingassets/images/onboarding_one.png, onboarding_two.png, onboarding_three.pngThe three first-run intro screens
Order Successassets/images/purchase_success.pngShown after an order is placed
Walletassets/images/wallet_bonus.pngWallet bonus screen
Maintenance / Updateassets/images/maintenance.png, update.pngShown 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.

One command makes every size
All four apps generate their launcher icons from two source images. Replace 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

1

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.

2

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.

3

Copy generated icons to the project

Extract the downloaded zip and copy the files to the correct folders:

Android Icons
# 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
iOS Icons
# 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
Adaptive Icons (Android 8+)
For modern Android adaptive icons (round icons with background layer), also replace 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).

android/app/src/main/AndroidManifest.xml
<application
    android:label="Your App Name"   <!-- Change this -->
    ...
>

iOS

Edit ios/Runner/Info.plist — find CFBundleDisplayName (or CFBundleName):

ios/Runner/Info.plist
<key>CFBundleDisplayName</key>
<string>Your App Name</string>

The names the apps ship with, so you know what you are replacing:

AppDefault home-screen name
myntcartapp (Customer)Myntcart
myntcart_vendorMyntCart 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_storeMyntcart Store
myntcart_deliveryMyntcart 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.

android/app/build.gradle (or build.gradle.kts for the store app)
namespace = "com.yourcompany.yourapp"
applicationId = "com.yourcompany.yourapp"   // must match namespace

The package names the apps ship with:

AppGradle fileAndroid package nameiOS bundle identifier
myntcartapp (Customer)android/app/build.gradlecom.myntcart.appcom.myntcart.app
myntcart_vendorandroid/app/build.gradlecom.myntcart_vendor.appcom.myntcart-vendor.app
myntcart_storeandroid/app/build.gradle.ktscom.myntcart_store.appcom.myntcartstore.app
myntcart_deliveryandroid/app/build.gradlecom.myntcart_delivery.appcom.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.

Quick tip
You can also use the 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.

The store app does not use Firebase
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

  1. You need a Google account (Gmail). If you don't have one, create at accounts.google.com/signup
  2. Go to console.firebase.google.com
  3. Sign in with your Google account

6.2 — Create a Firebase Project

1

Click "Create a project"

On the Firebase Console dashboard, click the Create a project button (or "Add project" if you already have projects).

2

Enter Project Name

Enter your project name (e.g. myntcart or yourstore-app). Firebase auto-generates a project ID below it. Click Continue.

3

Google Analytics (Optional)

Toggle Google Analytics on or off. If enabled, select or create a Google Analytics account. Click Create project.

4

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.

AppAndroid Package Name (default)iOS Bundle ID
myntcartapp (Customer)com.myntcart.appcom.myntcart.app
myntcart_vendorcom.myntcart_vendor.appcom.myntcart-vendor.app
myntcart_deliverycom.myntcart_delivery.appcom.myntcart-delivery.app

For each app, repeat these steps:

Register Android App

1

Click the Android icon

In your Firebase project dashboard, click "Add app" → Select the Android icon.

2

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).

3

Download google-services.json

Click Download google-services.json. Save this file — you'll place it in your Flutter project next.

4

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

1

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.

2

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):

ServiceWhere to EnableWhy MyntCart Needs It
AuthenticationBuild → Authentication → Sign-in methodPhone OTP login, Google sign-in, email/password login
Cloud Messaging (FCM)Project Settings → Cloud MessagingPush notifications to all mobile apps
Crashlytics (optional)Build → CrashlyticsAutomatic crash reporting and error tracking

Enable Authentication Methods

  1. Go to Build → Authentication → Sign-in method
  2. Enable Phone — required for OTP login in all apps
  3. Enable Google — for Google sign-in on customer app
  4. Enable Email/Password — for email-based login
  5. Click Save for each

Get the service account for push notifications

  1. Go to Project Settings (gear icon) → Service accounts tab
  2. Click Generate new private key and download the JSON file
  3. 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.

Terminal (get debug SHA-1)
# 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
  1. Copy the SHA1 fingerprint from the output
  2. Go to Firebase Console → Project Settings → Your Android app → Add fingerprint
  3. Paste the SHA-1 and save
  4. For release builds, use your release keystore SHA-1 instead

6.5 — Place Firebase Config Files in Flutter Project

A

Android — google-services.json

Place the downloaded file at exactly this path:

File Location
myntcartapp/android/app/google-services.json

Open the file and verify package_name matches your applicationId from build.gradle:

google-services.json (key fields)
{
  "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..." }]
  }]
}
B

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.

File Location
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.

This file is not in the download
No app ships with a GoogleService-Info.plist. For an iOS build you must download your own from the Firebase Console and add it to every app you build.
Mismatched package name = crash
If the 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.

Terminal
# 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:

android/local.properties
# 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:

ios/Flutter/Secrets.xcconfig
# 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:

pubspec.yaml
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

Terminal — customer, vendor and delivery apps (Flutter 3.47)
# 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
Terminal — store app (Flutter 3.47)
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:

android/key.properties
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.

Three things to know before you publish
Certificate pinning. All four apps pin the certificate authority of 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 ChangeFile Path
Backend URL, app name, version — customer; app name, version — deliverylib/utill/app_constants.dart
Backend URL — vendor & deliverylib/utill/app_config.dart
Backend URL, Firebase values, Maps key at build time — customer, vendor & deliveryenv.json in the app's root folder (you create it)
Backend URL, app name, version — storelib/core/constants/myntcart_constants.dart — backend URL at build time: --dart-define=BASE_URL=, or BASE_URL in env.json
Logo, placeholder, illustrationslib/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 nameandroid/app/build.gradle — store app: android/app/build.gradle.kts
Launcher iconassets/icon/ (store app: assets/images/appstore.png and assets/icon/adaptive_foreground.png), then dart run flutter_launcher_icons
Android Firebaseandroid/app/google-services.json — customer, vendor & delivery: also the FIREBASE_… values in env.json
Android release signingandroid/key.properties (you create it)
Android Google Maps keyandroid/local.properties — delivery app: also GOOGLE_MAPS_API_KEY in env.json
iOS app nameios/Runner/Info.plist — vendor app: APP_DISPLAY_NAME in ios/Flutter/Secrets.xcconfig
iOS bundle identifierXcode → Runner → General → Bundle Identifier
iOS launcher icon — store & deliveryios/Runner/Assets.xcassets/AppIcon.appiconset/
iOS Firebaseios/GoogleService-Info.plist (customer, vendor) or ios/Runner/GoogleService-Info.plist (delivery) — download your own
iOS Google Maps keyios/Flutter/Secrets.xcconfig
App version + build numberpubspec.yaml → version:

App-Specific Notes

AppPackageKey Features
myntcartappcom.myntcart.appShopping, cart, checkout, wallet, order tracking
myntcart_storecom.myntcart_store.appPOS, inventory, employees and employee roles. Branches themselves are created in the admin panel, not in the app
myntcart_vendorcom.myntcart_vendor.appProduct listing, order processing, earnings, withdrawal
myntcart_deliverycom.myntcart_delivery.appOrder 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.

ModuleDescriptionKey Features
ShiprocketDomestic courier aggregationShip Now (AWB + pickup), labels, manifests and invoices, NDR status updates by webhook, COD reconciliation, cancellations synced
Shiprocket Local QuickHyperlocal same-day delivery for local businessesInstant delivery, real-time tracking, local couriers, cancellations and refunds synced
ShadowfaxTwo services: Courier and HyperlocalCourier: 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
EasyshipGlobal multi-carrier shipping aggregatorRate comparison, the checkout-quoted courier booked, customs, insurance, label buying and printing, pickups, reconciliation
ShipEngineMulti-carrier shipping with label generationLabel printing, rate shopping, warehouses, reconciliation, tracking webhooks
Store ManagementMulti-branch store operations with POSBranch management, store managers, inventory, employees
Global Payment Gateways6 international payment providersAdyen, Airwallex, Alipay, Authorize.Net, Checkout.com, Mollie (wallets such as Apple Pay and Google Pay through their hosted payment pages)
Commercial TaxTax engine for stores outside India — VAT, sales tax, GST/HST, SSTTax 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-orphans lists Shiprocket orders whose order here was deleted; add --cancel to 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.

Server Requirements
The Addons page does not check your PHP limits, so an oversized zip simply fails to upload. Module packages are small, but give PHP room: 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.
1

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.

2

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.

3

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.

Nothing to run on the server
There is no migration to run for a module. The database your installer built already holds the tables of every module, so installing one adds its code only; and publishing it clears the application and configuration caches by itself. One exception: if your server runs with a cached route list — you ran php artisan route:cache yourself — run it once more after publishing, or the module's pages are not found.
4

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.

5

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.

Alternative: activate from MyntCart Modules
You can also activate from MyntCart Addons → MyntCart Modules, which lists every module in one place. Activating there runs the module's own activation against the licence server, so it is the same activation as the module's own page — only the screen you start from differs.

After installation, the module files are placed at:

Directory Structure
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

1

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.

2

Click "Activate" on the Module

Click the Activate button on the module you want to license. This opens that module's activation page.

3

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.

4

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.

The domain a licence binds to is your APP_URL
Activation registers the domain in your .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 Required badge. All other items (Dashboard, Branch Management, etc.) show License Required and 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.

ModuleSidebar SectionActivation Path
ShiprocketShiprocket ManagementShiprocket Management → Module Activation
Shiprocket Local QuickShiprocket Local QuickShiprocket Local Quick → Module Activation
ShadowfaxShadowfax ManagementShadowfax Management → Module Activation
EasyshipEasyship ManagementEasyship Management → Module Activation
ShipEngineShipEngine ManagementShipEngine Management → Module Activation
Store ManagementStore ManagementStore Management → Module Activation
Global Payment GatewaysGlobal Payment GatewaysGlobal Payment Gateways → Module Activation
Commercial TaxCommercial Tax ManagementCommercial Tax Management → Module Activation
License Verification
Each module licence is verified online via the CodeMynt licence server. Your server needs outbound internet access to 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.
Only the main admin sees Module Activation
The Module Activation item in each module's sidebar section is visible to the super-admin account only. A staff admin with a restricted role cannot see it or reach it, so licence activation has to be done from the main admin account.

How to Deactivate a Module License

1

Go to MyntCart Modules

Navigate to Admin Panel → MyntCart Addons → MyntCart Modules and open the licensed module with the Manage button.

2

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.

Deactivating here does not free the domain
Deactivation switches the module off on this install; the licence stays registered to this domain on the CodeMynt server. To move a licence to a different domain, sign in to the licence portal, open the licence and release the activation for the old domain — that is what frees the slot.
Deactivation Warning
Deactivating a module disables all its features. Orders already in progress via that module's shipping or payment provider are not affected, but new orders cannot use the deactivated module.

How to Delete / Remove a Module

Option A — From Addons Page (Recommended)

1

Deactivate License First

Go to MyntCart Modules → Manage → Deactivate License (see above).

2

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.

3

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)

1

Deactivate license first

Always deactivate the module license before removing files.

2

Delete the module folder via terminal

Remove the directory from your server:

Terminal
# 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.

Data Retention
Removing a module does not delete its database tables or stored data. If you reinstall the module later, previous data (orders, settings, transactions) will still be available.

Production Deployment Checklist

Before going live
Complete every item below before exposing your application to the public.
  • Set APP_ENV=production and APP_DEBUG=false
  • Set APP_URL to 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-install must 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.

Always backup before updating
Take a full backup of both your files and database before every update. Updates cannot be rolled back without a backup.
1

Backup Everything

Before touching anything, create a full backup:

Terminal
# 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/
2

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.

Not php artisan down
That command closes the whole application, the admin panel and its Software Update page included, so the update could not be started.
3

Upload 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:

  1. Verifies the licence you type with the licence server.
  2. 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.
  3. Unpacks the package over your installation.
  4. 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 is
  • Modules/ — not in the package; your installed add-on modules stay as they are
  • storage/ — 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
Do not update by copying the files over
A package holds no database migrations. Files replaced by hand bring the new code and leave the database on the old version's tables — 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:

FieldWhat to enter
Purchase sourceCodeCanyon or Direct — where you bought MyntCart
UsernameYour CodeCanyon username, or the email your direct licence is registered to
Purchase keyA 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 packageThe .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 more
  • post_max_size — 200M or more
"Invalid update file" usually means the package is not newer
The updater reads the version out of the package and compares it with the version you are running. A package of the same version or older is refused. Check the version shown on the dashboard against the one you downloaded before assuming the zip is damaged.

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.

4

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:

Terminal
php artisan route:cache
5

Disable Maintenance Mode

Bring the site back online: switch maintenance mode off again under System Settings → Business Setup → General Settings.

6

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
One license = one domain
Each licence key carries a domain limit, and every distinct address counts — a subdomain, a 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

ItemRegularExtended
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

ChannelDetailsResponse Time
Emailsupport@codemynt.inWithin 24–48 hours (business days)
License Portallicense.codemynt.in → Support TicketWithin 24 hours
DocumentationThis documentation siteSelf-service (instant)
Support Period
Your purchase includes 6 months of support, by e-mail or by a support ticket in the license portal, from the date of purchase. After 6 months, you can renew support for an additional period through the license portal.

Demo Access

Panel / AppURL / AccessCredentials
Admin Panelhttps://yourdomain.com/login/adminEmail: admin@admin.com / Password: password
Customer Websitehttps://yourdomain.comRegister a new account or use demo credentials
Vendor Panelhttps://yourdomain.com/vendor/auth/loginRegister as vendor or contact admin for credentials
Customer Appmyntcartapp (Flutter)Register via app or use website credentials
Vendor Appmyntcart_vendor (Flutter)Use vendor panel credentials
Store Appmyntcart_store (Flutter)Assigned by admin (store manager account)
Delivery Appmyntcart_delivery (Flutter)Assigned by admin (delivery man account)
The shipped password only gets you to the next step
The admin credentials above (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

Q

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.

Q

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.

Q

Are updates free?

Yes. All future updates for the version you purchased are free and lifetime. Download new versions from license.codemynt.in.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.

Q

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.