OpenCart Extension Development
Overview
OpenCart is an open-source PHP e-commerce platform built on a strict MVC (Model-View-Controller) architecture with a clear separation between the admin (back-office) and catalog (storefront) sides. Extensions modify or extend platform behavior without altering core files, using one of three mechanisms: the OCMOD XML modification system, the event/hook system (OpenCart 3.x+), or standalone MVC extensions that add entirely new controllers, models, and views.
OpenCart 4.x introduced namespaced PHP classes, Twig as the default template engine (replacing the older PHP-based .tpl files), and a modernized extension installer. Despite these changes, the fundamental architecture remains the same: every request routes through a controller, which loads models for data access and renders a view for output.
Develop extensions by creating files within the extension/ directory structure (OC4) or the upload/ overlay structure (OC3), following the platform's naming and routing conventions exactly. Deviating from these conventions causes silent failures because OpenCart's autoloader and routing engine depend on directory paths matching controller class names.
Extension Types
OpenCart organizes extensions into categories, each with a specific purpose and integration point:
- Modules -- General-purpose extensions that add blocks, widgets, or functionality to storefront pages. Examples: featured products carousel, newsletter signup, custom banners. Modules appear in Layout positions (content_top, content_bottom, column_left, column_right).
- Payment -- Payment gateway integrations. Each payment extension provides a checkout payment option, processes transactions, handles callbacks/webhooks, and manages order status updates. Payment extensions implement a standardized interface with
index(),confirm(), and callback methods. - Shipping -- Shipping method providers. Calculate shipping rates based on destination, weight, dimensions, and cart contents. Each shipping extension returns one or more quotes that appear during checkout.
- Order Totals -- Extensions that add line items to the order total calculation: subtotal, tax, shipping cost, discounts, handling fees, gift wrapping. Order totals execute in a configurable sort order.
- Feeds -- Data export extensions that generate product feeds for Google Shopping, Facebook Catalog, comparison shopping engines, or marketplace integrations. Feeds typically output XML or CSV.
- Themes -- Visual themes that override default template files. In OC4, themes provide Twig templates and assets. A theme can selectively override specific templates while falling back to the default theme for everything else.
- Reports -- Admin-side reporting extensions for sales analytics, customer behavior, product performance, and custom business metrics.
- Captcha -- Anti-spam integrations (reCAPTCHA, hCaptcha) used on registration, contact, and review forms.
The MVC Pattern in OpenCart
OpenCart enforces a strict MVC separation where every URL maps to a specific controller file. The routing pattern is index.php?route=path/to/controller/method, which translates to the file path controller/path/to/controller.php and calls the specified method (or index() if no method is given).
Controllers
Controllers handle request processing, load models, prepare data, and render views. Each controller class extends \Opencart\System\Engine\Controller (OC4) or Controller (OC3). The controller accesses core services through the registry: $this->load->model('catalog/product'), $this->model_catalog_product->getProduct($product_id).
Models
Models encapsulate database queries and business logic. Load models explicitly via $this->load->model('extension/payment/mygateway'). OpenCart uses PDO-based database access through $this->db->query() with manual query construction -- there is no ORM. Always escape user input with $this->db->escape().
Views
Views are Twig templates (OC4) or .tpl PHP template files (OC3). Controllers pass data to views via $data array. The view file path matches the route: a controller at controller/extension/module/mymodule.php renders view/template/extension/module/mymodule.twig. OC4 supports template inheritance and Twig's extends, block, and include directives.
Language Files
Language files provide translatable strings. Load language files in the controller with $this->load->language('extension/module/mymodule'). Access strings in the controller via $this->language->get('heading_title') and in Twig templates via {{ heading_title }}. Provide language files for each supported locale under language/en-gb/, language/de-de/, etc.
For complete MVC architecture details, namespace conventions, and OC4 migration patterns, see references/mvc-architecture.md.
OCMOD System
OCMOD (OpenCart Modification) is the XML-based system for modifying core and third-party files without directly editing them. An OCMOD file defines search-and-replace operations that the system applies at runtime, generating modified files in a cache directory. This approach allows multiple extensions to modify the same core file without conflict (assuming the search patterns do not overlap destructively).
How OCMOD Works
- Create an XML file (typically
install.xmlinside the extension package) that declares modification operations. - Each operation specifies a target file, a search pattern (literal string or regex), and an action (add before, add after, replace).
- When modifications are refreshed, OpenCart applies all operations sequentially, writing the modified files to
system/storage/modification/. - The application loads modified files from the modification cache instead of the originals.
When to Use OCMOD
Use OCMOD when the extension must alter existing controller logic, add template output to existing pages, inject model calls into core workflows, or modify admin forms. Prefer OCMOD over directly editing core files because OCMOD changes survive core upgrades and can be enabled/disabled without manual file restoration.
Key Limitations
OCMOD search patterns must match the exact source text. Core updates that change whitespace, variable names, or code structure will break OCMOD operations. Write narrow, specific search patterns and test against the target OpenCart version.
For OCMOD XML format, operation types, regex usage, and VQMOD legacy migration, see references/ocmod-and-vqmod.md.
Event System (OpenCart 3.x+)
The event system provides a hook-based mechanism for extending OpenCart without file modifications. Extensions register event handlers that fire before or after specific controller, model, or view operations. Events are the preferred extension mechanism in OC3.x and OC4 because they do not rely on fragile text-matching like OCMOD.
Event Triggers
OpenCart fires events at standard lifecycle points:
catalog/controller/checkout/confirm/before-- Fire before the checkout confirm controller executes.catalog/model/catalog/product/getProduct/after-- Fire after the product model returns data, allowing modification of the result.admin/view/sale/order_info/before-- Fire before the order info view renders, allowing injection of additional template data.
Registering Events
Register events in the extension's install() method using $this->model_setting_event->addEvent(). Provide the event trigger, the handler route, and a priority (sort order). Unregister events in uninstall() to clean up.
Benefits Over OCMOD
Events are version-resilient because they hook into method calls rather than matching source text. They compose cleanly -- multiple extensions can listen to the same event without conflicting. They are also easier to debug because the event handler code lives in the extension's own controller rather than in a modification cache.
For the complete event trigger catalog, handler implementation, priority system, and OC4 changes, see references/event-system.md.
Development Setup
Local Installation
- Install PHP 8.1+ with required extensions (gd, curl, openssl, mbstring, zip, zlib).
- Install MySQL 8.0+ or MariaDB 10.4+.
- Install Apache with mod_rewrite or Nginx with appropriate rewrite rules.
- Download the target OpenCart version from the official repository.
- Run the installer at
/install/or configureconfig.phpandadmin/config.phpmanually. - Remove the
/install/directory after setup.
Extension Development Workflow
- Develop the extension files in their proper directory structure under the OpenCart installation.
- Use the Extension Installer (admin panel) to test
.ocmod.zippackage installation. - Clear the modification cache (admin > Extensions > Modifications > Refresh) after OCMOD changes.
- Clear the Twig template cache (admin > Dashboard > gear icon > clear caches) after view changes.
- Enable error logging in
php.iniand OpenCart'sconfig.php(define('DIR_LOGS', ...)) for debugging.
Extension Packaging
Package extensions as .ocmod.zip files containing the extension files and an optional install.xml for OCMOD modifications. The ZIP structure must mirror the OpenCart installation directory layout exactly. The Extension Installer extracts files to their corresponding locations.
Debugging Techniques
- Use
$this->log->write('debug message')to write to the OpenCart log file atsystem/storage/logs/. - Inspect the modification cache at
system/storage/modification/to verify OCMOD changes applied correctly. - Enable PHP
display_errorsin the development environment but disable it in production. - Use browser developer tools to inspect AJAX requests, especially during checkout where payment and shipping extensions communicate asynchronously.
- Test extensions on a clean OpenCart installation with no other third-party extensions to isolate issues.
Building a Payment Extension
Payment extensions follow a specific contract. The admin controller provides a settings page for entering API credentials and configuring behavior. The catalog controller provides three key methods:
index()-- Render the payment method form on the checkout page. Return HTML that collects any required customer input (card fields, redirect button, hosted payment form embed).confirm()-- Process the payment when the customer confirms the order. Call the payment gateway API, handle the response, and update the order status.callback()-- Handle asynchronous notifications (webhooks, redirects) from the payment gateway. Verify the notification authenticity, update the order status, and return an appropriate HTTP response.
Register the payment method by storing settings with the prefix payment_mygateway_ (OC3) or following the OC4 extension settings convention. The checkout controller queries enabled payment extensions and displays them based on the customer's eligibility (geo zone, order total range, currency).
For cross-platform payment integration patterns including tokenization, 3D Secure, and PCI compliance, see the ecommerce-common skill.
Anti-Patterns
Avoid these common mistakes in OpenCart extension development:
- Editing core files directly. Always use OCMOD, events, or the extension directory structure. Core edits are overwritten by updates and conflict with other extensions.
- Hardcoding language strings. Always use language files. Hardcoded strings break multi-language stores and make the extension unpublishable on the marketplace.
- Skipping
$this->db->escape(). Every user-supplied value in SQL queries must be escaped. OpenCart does not use parameterized queries by default, so SQL injection is the developer's responsibility. - Ignoring the modification cache. After installing or updating OCMOD files, always refresh modifications. Stale cache causes confusing behavior where changes appear not to work.
- Writing OCMOD patterns that are too broad. Overly generic search patterns match unintended locations, breaking core functionality. Use enough surrounding context in the search string to match a unique location.
- Storing credentials in the database unencrypted. Use OpenCart's settings API with appropriate access controls. For sensitive keys, encrypt before storage.
- Bypassing the OpenCart registry. Do not instantiate models or libraries directly. Always use
$this->load->model()and$this->load->library()to ensure proper initialization and dependency injection.
Reference Files
- MVC Architecture -- Controller/Model/View/Language structure, routing, admin vs catalog separation, library system, OC4 namespace changes, extension directory layout
- OCMOD and VQMOD -- OCMOD XML format, operations, search/add/replace, install.xml, VQMOD legacy, modification system, best practices
- Event System -- Event triggers, handlers, registering events, priority system, OC4 event changes, catalog and admin triggers
- Marketplace Publishing -- OpenCart marketplace submission, extension packaging, documentation requirements, version compatibility, pricing