grafite/commerce
Grafite Commerce is a Laravel package for building online stores, with products, orders, transactions, subscriptions, coupons, and shipping. It ships with migrations, models, and admin tools so you can add catalog and checkout features to your app quickly.
Read this first: grafite/commerce was last released 2017-03-03, is archived on GitHub, has 47 stars and zero dependents. It is a Quarx CMS module, not a standalone Laravel package, and it targets the Laravel 5.x / PHP 7.0-7.1 era. Treat it as a legacy maintenance target or a reference implementation — not something to install on a new project. If you are evaluating it for a greenfield build, skip to the last section of this document.
If you are picking up an existing install, the minimal path is:
asdf setup with PHP 7.1 and the Laravel version named in composer.json. The single biggest source of pain with 2017-era Grafite packages is Composer resolving against a modern PHP/Laravel and failing halfway through.quarx/core (admin panel, auth, module loader, permissions) is already present and booted. composer require grafite/commerce into a fresh Laravel skeleton will not give you a working storefront.config/app.php, then publish config, migrations, and views in one shot:
php artisan vendor:publish --provider="Grafite\Commerce\CommerceServiceProvider"
php artisan migrate
Confirm the publish tags in the provider source — Commerce, like most Quarx modules, publishes config, assets, and views under separate tags, and publishing the wrong one silently leaves you without views.module.json or an entry in config/quarx.php). The admin UI at /admin should show a Commerce section with Products, Orders, Customers, Coupons, Shipping, and Taxes.routes/ (admin + storefront route groups), src/Models/ (Product, Variant, Order, Cart, Transaction), config/ (model map + payment driver), database/migrations/, then resources/views/.Your first use case: create a product with at least one variant, add it to a cart, and walk it through checkout with a sandbox payment driver. That single loop touches every subsystem — catalog, pricing, cart persistence, order creation, transaction recording — and will surface configuration gaps faster than reading the source.
Quarx module registration is the integration seam. Everything — admin routes, menu entries, permissions, asset loading — flows through Quarx's module loader. If you need to add an admin screen for a custom entity (e.g., a "Gift Card" model), follow the pattern of an existing Commerce module rather than inventing a new one; consistency here is what keeps the admin nav and ACL working.
Products and variants. Price, SKU, and stock almost always live at the variant level, not the product level. Build your catalog import and any custom admin tooling around variants from day one. A common mistake is writing product-level price logic that then breaks the moment a product has two sizes.
Cart resolution. The cart is resolved through the package's helper/facade and is persisted (session or DB-backed depending on config). Wrap it in your own thin service rather than calling the helper from controllers and Blade directly — you will want to swap the backing store or add line-item metadata (engraving text, gift wrap) and the package gives you no clean hook for that.
Checkout as an explicit state machine in your app. Let Commerce own the cart and the order record, but keep the checkout orchestration (validate address → apply shipping → apply tax → create order → charge → record transaction → fire receipt) in your own controller or action class. The package's own checkout flow is terse and hard to instrument; owning the orchestration means you can add idempotency keys and logging without forking.
Model swapping via config. Quarx packages conventionally let you override models by class name in config (e.g. config/commerce.php maps products → your subclass). This is the cleanest extension point for adding relationships, scopes, or accessors without editing vendor code. Verify the exact key names in the package's config file before relying on it.
Events for post-order side effects. Whatever the package fires on order completion, subscribe to it for emails, webhooks, and fulfillment handoff rather than patching the checkout controller. Where no suitable event exists, add one in your own wrapper.
Payment drivers. Gateways are configured, not coded — you set credentials and a driver in config. In practice, every payment SDK from 2017 (Stripe, PayPal) has had breaking API changes since. Budget for writing a thin adapter that translates your current gateway SDK calls into whatever shape the package's transaction model expects.
Testing. Use RefreshDatabase and drive the cart through HTTP requests rather than calling models directly, since cart state is part of the flow. Build your own factories — 2017-era packages rarely ship usable ones — and stub the payment driver in the container so tests never hit a live API.
composer.lock for transitive CVEs and pin with composer audit in CI. This is the single highest-risk item in any assessment of this package.--ignore-platform-reqs is a band-aid that hides PHP version mismatches until runtime. The reliable fix is a containerized PHP 7.1 with a frozen lockfile.database/migrations/ and confirm. Getting this wrong produces rounding bugs that only appear at scale.bootstrap/cache/ and check that the provider is registered after the Quarx core provider in config/app.php. Cached routes from a prior boot will mask the real problem.resources/views/vendor/commerce/ and edit there. Never edit vendor/ — a composer install on a fresh machine will silently revert your changes.DB::listen() in a local service provider when tracing an order that "didn't go through" — the SQL timeline usually reveals whether the cart, the order, or the transaction row was the point of failure.products, variants, orders, order_items, transactions export cleanly to CSV. Then evaluate lunarphp/lunar, aimeos/aimeos-laravel, or a hand-rolled catalog + Laravel Cashier. A bespoke product/order model with Cashier for payments is often less total work than dragging a 2017 Quarx module into a supported Laravel version — and it is the recommendation here.How can I help you explore Laravel packages today?