# Opencart

> This skill should be used when the user asks to "create an OpenCart extension", "build an OpenCart module", "OpenCart OCMOD", "OpenCart VQMOD", "OpenCart event system", "OpenCart MVC", "OpenCart payment extension", "publish to OpenCart marketplace", or needs guidance on OpenCart extension development.

- Skill: `biggora/opencart` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add biggora/opencart`
- Raw SKILL.md: https://api.skillmd.com/api/skills/biggora/opencart/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: biggora (https://skillmd.com/u/biggora)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/biggora/opencart

---


# 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](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

1. Create an XML file (typically `install.xml` inside the extension package) that declares modification operations.
2. Each operation specifies a target file, a search pattern (literal string or regex), and an action (add before, add after, replace).
3. When modifications are refreshed, OpenCart applies all operations sequentially, writing the modified files to `system/storage/modification/`.
4. 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](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](references/event-system.md).

## Development Setup

### Local Installation

1. Install PHP 8.1+ with required extensions (gd, curl, openssl, mbstring, zip, zlib).
2. Install MySQL 8.0+ or MariaDB 10.4+.
3. Install Apache with mod_rewrite or Nginx with appropriate rewrite rules.
4. Download the target OpenCart version from the official repository.
5. Run the installer at `/install/` or configure `config.php` and `admin/config.php` manually.
6. 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.zip` package 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.ini` and OpenCart's `config.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 at `system/storage/logs/`.
- Inspect the modification cache at `system/storage/modification/` to verify OCMOD changes applied correctly.
- Enable PHP `display_errors` in 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](../ecommerce-common/SKILL.md).

## 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](references/mvc-architecture.md) -- Controller/Model/View/Language structure, routing, admin vs catalog separation, library system, OC4 namespace changes, extension directory layout
- [OCMOD and VQMOD](references/ocmod-and-vqmod.md) -- OCMOD XML format, operations, search/add/replace, install.xml, VQMOD legacy, modification system, best practices
- [Event System](references/event-system.md) -- Event triggers, handlers, registering events, priority system, OC4 event changes, catalog and admin triggers
- [Marketplace Publishing](references/marketplace-publishing.md) -- OpenCart marketplace submission, extension packaging, documentation requirements, version compatibility, pricing

