Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shop Laravel Package

rmscms/shop

rmscms/shop is a Laravel package for adding e-commerce to RMS CMS: product catalogs, categories, carts, orders, and checkout. It provides straightforward store management and a lightweight storefront foundation for launching online shops without heavy dependencies.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Confirm the prerequisite first. rmscms/shop is an add-on for RMS CMS, not a standalone storefront. Verify rmscms/* core is installed, migrated, and booting before you add this package — otherwise you will spend an afternoon debugging tables and admin routes that were never going to exist.
  2. composer require rmscms/shop, then confirm discovery: php artisan about (or php artisan package:discover) should list the provider. With 2 stars and a recent-but-thin release history, assume the README is not the source of truth.
  3. Publish everything you might touch, scoped by tag so you can see what exists: php artisan vendor:publish --provider="Rmscms\Shop\ShopServiceProvider" — try --tag=config, --tag=migrations, --tag=views individually. Run php artisan vendor:publish --list if a tag is rejected.
  4. Read config/shop.php end to end. For a package this size, the config file is the documentation: it tells you which models are swappable, whether routes are registered, and what the cart/session keys are. Then skim the provider's register()/boot() — you need to know whether migrations, routes, and views load conditionally.
  5. php artisan migrate, then seed one category and two products (via tinker is fine) so you have real data before writing any UI.
  6. First end-to-end use case: a single feature test that hits a category listing route, adds a product to the cart, and posts a checkout that creates one order row — asserting the order total and the line-item price. That one test exercises models, routes, cart persistence, and order writing. If it passes, the wiring is correct and everything after is usage detail.

Implementation Patterns

  • Treat the catalog as a read-heavy, cache-friendly layer. Category trees and product listings are the highest-traffic queries in any shop. Cache the tree (Cache::remember keyed on the category table's updated_at), and eager-load relationships explicitly — a naive $category->products in a Blade @foreach is the classic N+1 that turns a 20-product page into 60 queries.
  • Wrap the cart behind your own service. The package gives you cart storage; it will not give you your business rules (minimum order value, per-customer pricing, promotional codes). Define App\Shop\CartService with add/update/remove/totals, implement it over the package's cart, and bind it in a provider. When pricing logic changes — and it will — you edit one file.
  • Never trust posted prices. Recalculate every line total and the order total server-side inside the checkout transaction. The cart should store a product reference and a quantity; the price is resolved at calculation time.
  • Checkout belongs in a transaction with a stock guard. Wrap order creation + line items + stock decrement in DB::transaction(). Decrement stock with a conditional update (where('stock', '>=', $qty)->decrement(...)) and abort if zero rows were affected, or you will oversell the last unit under concurrent requests.
  • Snapshot prices onto order lines. Store unit_price, product_name, and sku on the order line at purchase time. Joining back to products for historical invoices means a price edit rewrites your accounting history.
  • Model order state as an enum with explicit transitions (pending → paid → shipped → cancelled), and dispatch your own domain events from the transition methods. Put emails, stock returns, and admin notifications in listeners — not scattered through the checkout controller.
  • Override views, don't edit vendor files. Publish views into resources/views/vendor/shop/, or wrap the package's views in your own layout. If the package registers a shop:: view namespace, reference shop::product.card from your app so future package updates land cleanly.
  • Integrate with RMS CMS rather than around it. Use its user/media models for customer identity and product imagery; extend the admin screens through the CMS's extension points instead of building a parallel admin. Two sources of truth for "who is a customer" is the fastest route to a corrupted orders table.
  • Queue the slow, external parts — order confirmation mail, invoice PDFs, webhooks to a fulfilment provider. Set an explicit $timeout and $tries lower than your worker timeout, or you get opaque MaxAttemptsExceeded failures.
  • Testing: use RefreshDatabase plus your own factories for products/orders, and in unit tests $this->swap(CartService::class, new FakeCart()). Assume there is no Shop::fake() — this package is small enough that container swaps are the supported path.

Gotchas and Tips

  • vendor:publish --force silently clobbers your edited views and config. Diff before forcing, and commit the published files so drift shows up in code review rather than production.
  • Migration ordering against RMS CMS tables is the top install failure. Published package migrations carry a package timestamp; if shop_orders references a CMS users table that migrates later, the foreign key fails. Check php artisan migrate:status, and rename the migration timestamp if you need to reorder.
  • The package may auto-register public routes. Before you ship, run php artisan route:list and confirm the prefix, middleware, and auth guard on cart/checkout routes. A default-open checkout is a launch-day surprise.
  • Cart loss on login is the most common "bug report" in any shop package: the guest session cart does not automatically merge into the authenticated user's cart. Handle the Login event with an explicit merge (sum quantities, cap at stock) and clear the session key.
  • Config cache is the number one "works locally" bug. After any .env change in staging/production: php artisan config:clear && php artisan config:cache. Package config is read at boot only. Use php artisan config:show shop to confirm your values actually landed.
  • Money is almost certainly your problem, not the package's. Pick integer minor units (cents) at the database level, format only at the view boundary, and never float a total. Tax, shipping, and multi-currency are very likely not implemented — plan to own them in your CartService.
  • php artisan view:clear after publishing. Blade caches compiled views; stale cached templates after a publish is a five-minute confusion that looks like "my override isn't working."
  • Octane/queue workers and singleton state. If the package binds a cart or settings object as a singleton, it can leak between requests under Octane. Prefer scoped bindings in your own code, or reset the package's state in an Octane listener.
  • Pin the version and commit composer.lock. A 2-star package with a fast release cadence can change default behaviour inside a patch bump. Read the diff of config/ and database/migrations/ between releases before upgrading.
  • Debugging order that actually works: php artisan about (discovered?) → php artisan config:show shop (env landed?) → php artisan tinker calling the product/order model directly (package broken vs. my integration broken). The tinker step isolates the two faster than any log.
  • Extend, don't fork. If models or drivers are resolvable from config, subclass and swap the binding in your own provider. Editing vendor/rmscms/shop survives exactly one composer update.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource