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

S Cart Laravel Package

gp247/s-cart

GP247 S-Cart is an open-source ecommerce package for Laravel with a ready-to-use shopping cart, product and order management, admin dashboard, modules, themes, and SEO-friendly features for building online stores quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

gp247/s-cart (the successor to S-Cart) is not a cart trait you composer require into an existing app — it is the application. It ships models, routes, controllers, an admin panel, a storefront template engine, and a plugin/hook system on top of Laravel. Plan for greenfield (or a heavily isolated sub-app), not for bolting a cart onto an existing Laravel codebase.

Minimal path to a running shop:

composer create-project gp247/s-cart my-shop
cd my-shop
cp .env.example .env
php artisan key:generate
# edit DB_*, APP_URL, MAIL_* in .env
php artisan migrate --seed
php artisan storage:link
php artisan serve

Some releases add an explicit installer command (php artisan gp247:install or s-cart:install) that walks you through DB + admin credentials. The seed output prints the admin URL (/admin) and default credentials — change both before anything else touches the network.

Where to look first, in this order:

  1. config/gp247.php (and any config/scart.php still present) — template selection, admin prefix, auth guards, extension toggles, image sizes.
  2. vendor/gp247/s-cart/src/ — Models/, Controllers/, Routes/, Library/. This is the source of truth for field names; the docs lag the code.
  3. app/GP247/Templates/ and app/GP247/Plugins/ — your extension surfaces. If app/GP247 doesn't exist yet, a template/plugin generator command in the admin creates the skeleton.
  4. The admin panel itself: Catalog → Attributes/Options, then Shipping/Payment settings, then Orders.

First use case: create a product with one attribute set and one option, assign it to a category, configure a flat-rate shipping method and a test payment method, then place an order end-to-end as a guest. That single pass teaches you the model graph (ShopProduct → ShopProductAttribute/ShopProductOption → ShopOrder → ShopOrderDetail) faster than reading the docs, and it surfaces the two things that break first: image storage permissions and a missing store/currency setting.

Implementation Patterns

Never edit vendor/ or core views. Every customization goes through one of three channels: a template, a plugin, or a hook. Core files are overwritten on composer update, and the package's release cadence is fast.

Template pattern (storefront changes). Copy the default template out of the package into app/GP247/Templates/<YourTemplate>/ with the expected structure (Provider.php, config.php, Route.php, views/, Lang/), register it in config, then override only the Blade views you need. Everything else falls through to the parent template. This is the correct place for layout, CSS/JS bundles, and checkout markup changes.

Plugin pattern (features). Same skeleton, different directory:

app/GP247/Plugins/MyPlugin/
├── config.php      # name, version, enable flag, admin menu entries
├── Provider.php    # service provider: routes, views, hooks, migrations
├── Route.php       # web/admin routes
├── views/
└── Lang/

Plugins are activated from the admin extension screen; the enable state is persisted, so a plugin can ship disabled and be toggled per environment. Use plugins for payment/shipping gateways, ERP sync, loyalty points, custom report screens — anything with its own routes and settings.

Hooks/filters (cross-cutting changes). The extension system is action + filter based, invoked through helper functions (sc_... in older 3.x/4.x lines, gp247_... in the current line — check vendor/gp247/*/src/Library/ for the actual names in your version). Register in your plugin provider:

// pseudo-signature — confirm helper names in your version
gp247_process_hook_action('order.success', function ($order) {
    // push to ERP, increment loyalty, fire webhook
});

gp247_process_hook_filter('product.price.display', function ($price, $product) {
    return $product->is_promotion ? $price * 0.9 : $price;
});

This is the cleanest way to add post-purchase side effects without wrapping core controllers. Status-change and checkout-step hooks are the two you'll use most.

Cart flow. The cart is a session-backed library exposed as a facade (gloudemans/darryldecode-style API). Typical day-to-day:

Cart::add([
    'id'      => $product->id,
    'name'    => $product->name,
    'qty'     => $request->qty,
    'price'   => $product->price,
    'options' => ['color' => $request->color, 'size' => $request->size],
]);

$rows  = Cart::content();
$total = Cart::total();

Line items are keyed by product id + options hash, so two rows of the same product with different options coexist correctly. Validate stock and price at checkout, not at add-time — the session cart can outlive a price change.

Order creation is the seam. Core creates ShopOrder + ShopOrderDetail inside the checkout controller; you generally should not reimplement it. Instead hook the status transition (pending → processing → completed) and do stock decrement, email, invoice PDF, and external sync there. Custom endpoints that create orders directly tend to miss stock reservation and coupon accounting.

Custom routes over overridden controllers. Define your own routes in a plugin, resolve core models, and reuse the cart library. A 30-line controller in a plugin beats a 400-line copy of a core controller you now have to diff on every release.

Multi-language / multi-store / multi-vendor. All three are switches in config, and each adds a scoping dimension to queries. When writing custom queries against core models, apply the same scoping the core does (store id, vendor id, language) or you'll leak data across tenants. Translation strings live in each package's Lang/ directory — add your own in the plugin rather than editing core lang files.

Gotchas and Tips

  • It's an app, not a package. Merging into an existing Laravel project means reconciling two auth systems (customers vs. admin users), two route files, two view namespaces, and a session-based cart. If you must, mount it behind a separate domain/guard and proxy; don't try to share the users table.
  • API/SPA is an uphill walk. Checkout depends on session state and CSRF. Building a headless frontend means writing session/cookie adapters and re-validating cart state server-side. Budget for it — it's not a documented first-class path.
  • Version-lock the whole gp247/* set (gp247/core, front, shop, plus the template) together. Mixing a new core with an old template is the most common source of blank pages and missing hooks.
  • Blank page = missing view. The template resolver fails quietly when a view path or template config key is off. APP_DEBUG=true plus php artisan view:clear resolves 80% of these.
  • Clear caches after touching templates/plugins/config: php artisan config:clear && php artisan view:clear && php artisan cache:clear. Plugin enable state is often cached separately from Laravel's config cache.
  • Hooks fail silently. A misspelled hook name just never fires — no exception. Log inside your callback once during development to confirm registration, then remove the log.
  • Uploads need both the storage symlink and correct permissions on storage/app/public; image resizing goes through Intervention Image, so verify GD (or Imagick) is compiled in. "Image uploads but shows broken" is nearly always the symlink.
  • Seeded data is load-bearing. Many flows (currencies, order statuses, email templates, payment methods) read from settings tables, not config. RefreshDatabase in tests leaves you with a shop that can't check out — run the seeders or import a fixture.
  • Change the admin path and credentials in config immediately; the default /admin + seeded login is public knowledge.
  • Price/rounding: confirm the decimal precision setting matches your currency before importing a catalog; changing it later requires a data migration.
  • Mail defaults to log/sync. Order confirmation emails silently "work" in dev and never leave the box. Set a real transport in staging and test the full order lifecycle there, not just local.
  • Upgrade ritual: read the changelog for hook/key renames, back up the DB, upgrade the pinned set together, then re-run migrations and clear caches. Keep a diff of your app/GP247 tree in git so upgrades only ever touch composer.lock.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings