Skip to main content
v0.1.0 MIT · PHP 8.2+ · CodeIgniter 4.7 · HTMX 2
WinCart.ioSingle-TLD CodeIgniter 4 Cart
Architecture

Single-TLD CodeIgniter 4 Cart Architecture | WinCart

Independent merchants and PHP engineers looking for a clean, self-hosted single-store shopping cart have faced an uncomfortable tradeoff for years: inherit decades of global-registry debt from legacy OpenCart forks, bolt WooCommerce onto a WordPress blog database, or provision heavy enterprise multi-channel stacks designed around Symfony and Laravel worker fleets. WinCart takes a deliberately narrower architectural path on CodeIgniter 4.7 and PHP 8.2+.

WinCart Single-TLD CodeIgniter 4.7 four-tier modular architecture diagram
WinCart maps storefront views, PSR-4 domain modules, official CodeIgniter 4 packages, and MariaDB InnoDB tables across strict single-store boundaries.

Why Single-TLD Scope Changes Every Layer of the Cart

Multi-store commerce engines pay a hidden tax on every HTTP request. The moment a schema assumes multiple tenants or storefronts inside one database, every catalog lookup, slug uniqueness check, coupon rule, tax bracket, and cache key has to carry a composite store_id or channel_id predicate. Query plans widen, index memory balloons, and plugin authors inevitably forget a tenant filter in custom reports.

By committing the MIT open-source edition of WinCart strictly to a single top-level domain—one installation equals one store—every table and service boundary stays razor-sharp:

  • Catalog slugs and variant SKUs use direct single-column unique indexes (products.slug and product_variants.sku) without composite multi-store join tables.
  • Storefront configuration lives in codeigniter4/settings with cached MariaDB reads and deterministic fallbacks in app/Config/.
  • The checkout state machine, webhook payloads, and immutable order snapshots form a clean 1:1 domain model that can serve either server-rendered HTML or a future standalone frontend without schema translation layers.

Assembling a First-Party CodeIgniter 4.7 Foundation

One of CodeIgniter 4.7's quiet strengths is its official package ecosystem. Rather than pulling dozens of third-party Composer packages with conflicting release cycles, WinCart builds its runtime almost entirely from audited first-party components:

Authentication and Role Matrices via Shield

Customer registration, guest checkout upgrades, password resets, personal API tokens, and admin role-based permissions run on codeigniter4/shield. Wrapping Shield user entities inside Modules\Customers keeps authentication battle-tested while isolating shipping addresses and order history in dedicated commerce tables.

Zero-Redis Background Queues

Small and mid-sized merchants deploying onto a standard Nginx or Apache + PHP-FPM + MariaDB virtual server should not be forced to maintain Redis or RabbitMQ just to send order receipts. WinCart wires codeigniter4/queue to its native database driver out of the box, letting a lightweight cron or supervisor worker drain transactional emails and webhook jobs directly from InnoDB.

HTMX 2 + View Cells Without a Production Node Build

Shoppers expect instant slide-out cart drawers, live variant price updates, and inline coupon feedback without full-page flashes. WinCart combines server-rendered CodeIgniter View Cells with HTMX 2 partial swaps and pre-compiled modern CSS tokens. Merchants can deploy a release archive via Git or SFTP without installing Node.js, Webpack, or Vite on their production PHP host.

PSR-4 Module Isolation and Zero Core Hacks

Instead of crowding controllers and models into a flat app/ folder, WinCart registers seven bounded PSR-4 namespaces in app/Config/Autoload.php: Modules\Catalog, Modules\Cart, Modules\Checkout, Modules\Orders, Modules\Customers, Modules\Admin, and Modules\Storefront. Storefront templates live separately under themes/default/ so designers can override product cards and checkout views cleanly.

// app/Config/Autoload.php
public $psr4 = [
    APP_NAMESPACE        => APPPATH,
    'Modules\\Catalog'    => ROOTPATH . 'modules/Catalog',
    'Modules\\Cart'       => ROOTPATH . 'modules/Cart',
    'Modules\\Checkout'   => ROOTPATH . 'modules/Checkout',
    'Modules\\Orders'     => ROOTPATH . 'modules/Orders',
    'Modules\\Customers'  => ROOTPATH . 'modules/Customers',
    'Modules\\Admin'      => ROOTPATH . 'modules/Admin',
    'Modules\\Storefront' => ROOTPATH . 'modules/Storefront',
];

Classic PHP shopping carts became notorious for fragile XML monkey-patching systems like vQmod and OCMOD because core checkout flows lacked explicit extension seams. WinCart replaces file patching with two typed mechanisms: driver interfaces (PaymentGatewayInterface and shipping calculators) and CodeIgniter's native Events bus firing cart.calculated, order.paid, and order.shipped at deterministic transaction boundaries. Explore the Spark CLI Quickstart or inspect the 27-table InnoDB schema to start building on WinCart.