Installation
Require the package, then publish and run its migrations. The service provider is auto-discovered — no manual registration:
composer require roundly-consulting/shops-for-laravel
php artisan vendor:publish --tag="shops-migrations"
php artisan migrateMigrations are publish-only — the package never loads them itself, so publishing is a required step, not an optional one. The fourteen files publish in dependency order (shops → products → variants → carts → orders), so a single migrate applies them cleanly. Republishing overwrites the same files instead of duplicating them.
Provider packages’ migrations
Shops builds on sibling Roundly packages that Composer installs automatically. Six of them ship their own tables — publish each one before migrating:
php artisan vendor:publish --tag="media-migrations"
php artisan vendor:publish --tag="reviews-migrations"
php artisan vendor:publish --tag="attributes-migrations"
php artisan vendor:publish --tag="coupons-migrations"
php artisan vendor:publish --tag="credits-migrations"
php artisan vendor:publish --tag="addresses-migrations"
php artisan migrateSluggable’s only migration (sluggable-migrations, the slug_history table) is needed just when you turn on shops.slugs.history.
Decide before migrating
- shops.key_type — bigint, uuid or ulid for the polymorphic orders.customer, carts.owner and stock_adjustments.reference columns. Match the key type of your user model; it is fixed once the migrations run.
- sluggable.locales.supported — the shops, products and categories migrations create one unique slug index per supported locale. It defaults to app.locale plus app.fallback_locale.
# .env — fixed once the migrations have run
SHOPS_KEY_TYPE=ulid # bigint (default) | uuid | ulid// config/sluggable.php — one unique slug index is created per supported locale
'locales' => [
'supported' => ['en', 'sk'], // null = app.locale + app.fallback_locale
],Configuration file
The config file is optional — every key has a default and the common ones are env-backed. Publish it only to override:
php artisan vendor:publish --tag="shops-config"The package exposes two publish tags: shops-migrations and shops-config.
What comes with it
These Roundly packages are hard dependencies and power specific parts of the shop:
| Package | What it powers |
|---|---|
money-for-laravel | Every amount: Money and Currency, exact per-line tax, discount spreading, casts and decimal(38,0) money columns. |
enums-for-laravel | Helpers on Status, PriceType and StockReason — labels(), options(), validationRule() and more. |
media-library-for-laravel | Product featured and gallery images, per-variant images, category banners. |
reviews-for-laravel | Product reviews, rating aggregates, verified-purchase gating. |
attributes-for-laravel | Typed, filterable product spec-sheet attributes. |
coupons-for-laravel | All coupon and discount logic — percentage, fixed, free shipping, caps, usage limits. |
credits-for-laravel | Pay with store credit, and refunds as store credit. |
addresses-for-laravel | Customer address book → order billing and shipping snapshot. |
sluggable-for-laravel | Per-locale shop, product and category slugs, uniqueness and route binding. |
package-toolkit-for-laravel | Provider builder, the morphKey column macro, model resolvers and the about section. |
What the provider registers
- Merges config/shops.php, registers ShopsManager (the Shops facade root) as a singleton and CurrentShop as a scoped binding — reset per request and per queued job. The global Shops alias comes from the package’s composer.json.
- Binds six drivers from config — NumberGenerator, TaxResolver, PaymentGateway, ShippingMethod, DiscountResolver and VerifiedPurchaseResolver.
- Registers the morphKey Blueprint macro the orders, carts and stock-adjustment migrations use.
- Registers every shops.attributes.definitions entry in the attributes registry.
- Listens for OrderRefunded with GrantStoreCreditOnRefund.
- Adds a Shops section to php artisan about.
php artisan about --only=shopsThe about section reports the shop and coupon models, currency, price type, tax resolver and tax-class count, payment gateway, store credit, shipping method, discount resolver, order numbers, low-stock threshold, attribute count, catalog media, verified purchases, fallback locale and slug history. Configured classes show by base name only; tax-class names, attribute names, the store-credit bucket and the media disk are never printed.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.