OpenCart Mobile App · 5 min read · Updated

OpenCart Mobile App Developer Guide, Part 1: Overview, Architecture, Repository Layout and Languages

How the OpenCart 4.1.0.4 mobile app works: why it uses a custom API extension, its architecture, the repository layout and the languages used.

OpenCart Mobile App

This guide is for developers who will maintain or extend this project. It covers how the system is built and why. It also covers how each user flow works from start to finish, and how to add features safely.

For installing the extension and running the app the first time, see the OpenCart Mobile App: a Native iOS and Android App for OpenCart 4.1.0.4. This guide assumes you have done that.

This guide is published as a 5-part series. This is part 1.

In this post


1. What this project is

A native iOS and Android shopping app for an OpenCart 4.1.0.4 store. It has two parts that ship separately:

PartFolderRuns onShips as
Mobile appmobile/Phones (iOS, Android), with web for testingApp Store / Play Store build, or Expo Go during development
Mobile App API extensionopencart-extension/mobile_api/The OpenCart server (PHP)mobile_api.ocmod.zip, installed via Extensions → Installer

A local Docker store (docker-compose.yml, store/) is included for development only.

Why a custom extension instead of OpenCart’s built-in API

OpenCart 4.1.0.4 ships an API (catalog/controller/api/*), but it was built for the admin panel, not for public clients:

  • Only the api/order and api/subscription routes are allowed.
  • Every call needs an HMAC-SHA1 signature with a secret that must stay on the server.
  • Calls are limited to whitelisted IP addresses. Phones have changing IPs.
  • It trusts prices posted by the caller, which is safe for an admin but not for a customer.
  • It has no catalog browsing, customer accounts, wishlist, or order history.

So the extension adds a separate set of public JSON endpoints under extension/mobile_api/api/*. Wherever possible these call OpenCart’s own models and controllers, so stock checks, option validation, taxes, totals, shipping, and payment behave exactly as they do on the website.


2. Architecture at a glance

OpenCart 4.1.0.4 server(PHP)Phone (React Native app)online paymentHTTPS JSONX-Api-Key, X-Session-TokenScreens and componentsReact Query hooksapi/endpoints.tsapi/client.tsSecureStore:session token, currencyWebViewindex.php front controllerstartup/mobile_apirestores session fromheaderextension/mobile_api/api/*controllersApiController base classguard, envelope, helpersOpenCart core models andcontrollerscart, checkout, customer,catalogMySQL / MariaDBcheckout.pay HTML pagePayment extensions

Key ideas:

  • The server owns all state. The cart, checkout progress, login, and wishlist live in the OpenCart session on the server. The app is a thin client that renders what the server returns.
  • The session travels in a header. Native apps don’t share the browser’s OCSESSID cookie, so the app sends X-Session-Token. The extension’s startup action reopens that session.
  • One response shape. Every endpoint returns {success, data, message} or {success:false, error, errors}.
  • Reuse over reimplementation. Adding to the cart calls core api/cart.addProduct. Totals call api/cart.getTotals. Offline payments run the payment extension’s own confirm(). Online gateways render their own forms in a WebView.

3. Repository layout

opencart-mobile-app/
├── README.md                       Setup, API reference, known limits
├── docs/
│   ├── DEVELOPER.md                This guide (the source; edit this file)
│   ├── developer-guide.html        Bootstrap web page built from it (build-html.cjs)
│   ├── developer-guide.wordpress.xml  WordPress import (5 posts) built from it (build-wordpress.cjs)
│   └── featured-images/            Featured images for the 5 posts (build.cjs, README.md)
├── docker-compose.yml              Local dev store: web (PHP 8.3 + Apache) and db (MariaDB 11.4)
├── docker/php/Dockerfile           PHP image with gd, mysqli, zip, curl
├── .env                            Local DB and admin passwords (dev only, never commit real secrets)
├── store/                          OpenCart 4.1.0.4 install used for local testing
│
├── opencart-extension/
│   ├── build.sh                    Packages mobile_api/ into mobile_api.ocmod.zip
│   └── mobile_api/                 Extension source (the folder name is the extension code)
│       ├── install.json            Name, version and description shown in the Installer
│       ├── system/library/
│       │   └── api_controller.php  Base class for every endpoint
│       ├── catalog/controller/
│       │   ├── startup/mobile_api.php   Session, currency and CORS handling for API routes
│       │   └── api/                     One file per resource (see §8.4)
│       └── admin/
│           ├── controller/module/mobile_api.php        Settings page, install and uninstall
│           ├── language/en-gb/module/mobile_api.php    Admin texts
│           └── view/template/module/mobile_api.twig    Settings form
│
└── mobile/                         Expo / React Native app
    ├── App.tsx                     Entry: providers, boot screen, theme, lazy navigator
    ├── app.json                    Expo config: name, bundle ids, iOS ATS, plugins
    ├── package.json                Dependencies and scripts
    ├── tsconfig.json               TypeScript strict mode
    └── src/
        ├── config.ts               Store URL, API key, language, page size
        ├── theme.ts                Colours, spacing, radius, font sizes, applyTheme()
        ├── api/
        │   ├── client.ts           fetch wrapper: headers, token storage, envelope, ApiError
        │   ├── endpoints.ts        Typed function per endpoint (the `api` object)
        │   └── types.ts            TypeScript types for every response
        ├── context/StoreContext.tsx   Init data, customer, login/logout, currency
        ├── hooks/                  useCart, useWishlist (shared React Query hooks)
        ├── navigation/             RootNavigator (stack + tabs) and param types
        ├── components/             Reusable UI (buttons, fields, product card, address form…)
        ├── screens/                One file per screen (23 screens)
        └── utils/errors.ts         Error message helpers

4. Languages

LanguageVersionWhereWhy
TypeScript (TSX)~6.0 (see mobile/package.json), strict: trueAll app code in mobile/Catches mistakes at compile time, such as a wrong field name in an API response or a wrong navigation parameter. The API types in src/api/types.ts and the navigation types in src/navigation/types.ts make the compiler check every screen against the server contract.
PHP8.3 in the dev container (OpenCart 4.1.0.4 needs 8.0+)opencart-extension/OpenCart is written in PHP. An extension has to be PHP to run inside it and call its models. The code uses typed properties, str_starts_with, arrow functions and hash_equals.
TwigOpenCart’s bundled versionAdmin settings formOpenCart’s admin view layer.
JavaScript / jQueryInside the Twig templateAdmin colour pickersThe admin panel already loads jQuery and Bootstrap 5, so small scripts use them.
SQLMariaDB 11.4 / MySQLOnly through OpenCart modelsThe extension writes almost no SQL. It calls core models. The one exception is a SHOW TABLES check for the optional bestseller table.
YAML / Dockerfile / shelln/adocker-compose.yml, docker/php/Dockerfile, build.shLocal dev environment and packaging.

Next: Part 2: Tools and Libraries, Why Expo, and the Development Environment →

The series

  1. Part 1: Overview, Architecture, Repository Layout and Languages (you are reading this part)
  2. Part 2: Tools and Libraries, Why Expo, and the Development Environment
  3. Part 3: The OpenCart Extension and the Mobile App
  4. Part 4: Design Patterns, Hooks and End-to-End Flows
  5. Part 5: Configuration, Security, Extending, Testing, Releasing and Troubleshooting

Rupak Nepali
Written byRupak Nepali

Author of four Opencart book.
The recent are Opencart 4 developer book and Opencart 4 user manual

Leave a Reply

Your email address will not be published. Required fields are marked *