### Clone and Setup Demo Store
Source: https://docs.laravelshopper.dev/v2/demo-store
Clone the demo store repository and run the setup command to install dependencies, build assets, and seed the database for local development.
```bash
git clone https://github.com/shopperlabs/demo.laravelshopper.dev.git shopper-demo && cd shopper-demo
composer install
npm install && npm run build
composer setup
```
--------------------------------
### Install React Starter Kit on Existing Project
Source: https://docs.laravelshopper.dev/v2/react-starter-kit
When installing on an existing project, it's recommended to create a new branch first to review all changes. This command installs the kit and its dependencies.
```bash
git checkout -b storefront
php artisan shopper:kit:install shopperlabs/react-starter-kit
```
--------------------------------
### Shopper Kit State File Example
Source: https://docs.laravelshopper.dev/v2/starter-kits
This JSON file records the installed kit, its version, and the SHA-256 hash of copied files. Commit this file to git to track local modifications and upstream changes.
```json
{
"kit": "shopper/livewire-starter-kit",
"version": "1.0.0",
"installed_at": "2026-04-06T14:32:00+00:00",
"files": {
"app/Livewire/Pages/Home.php": "sha256:abc123...",
"resources/views/pages/home.blade.php": "sha256:def456..."
}
}
```
--------------------------------
### Install Livewire Starter Kit
Source: https://docs.laravelshopper.dev/v2/livewire-starter-kit
Use the `shopper:kit:install` Artisan command to install the Livewire Starter Kit into your Shopper project. This command downloads the kit and copies storefront files into your project.
```bash
php artisan shopper:kit:install shopperlabs/livewire-starter-kit
```
--------------------------------
### Install Livewire Starter Kit on Existing Project
Source: https://docs.laravelshopper.dev/v2/livewire-starter-kit
When installing on an existing project, it is recommended to create a new branch first. This allows for easier review of all changes before merging.
```bash
git checkout -b storefront
php artisan shopper:kit:install shopperlabs/livewire-starter-kit
```
--------------------------------
### Install Vue Starter Kit
Source: https://docs.laravelshopper.dev/v2/vue-starter-kit
Use the `shopper:kit:install` Artisan command to install the Vue Starter Kit into your Laravel project. This command is part of the Shopper package and does not require additional installations.
```bash
php artisan shopper:kit:install shopperlabs/vue-starter-kit
```
--------------------------------
### Install Vue Starter Kit on Existing Project
Source: https://docs.laravelshopper.dev/v2/vue-starter-kit
When installing the Vue Starter Kit on an existing project, it is recommended to create a new Git branch first. This allows for easier review of all changes before merging them into your main codebase.
```bash
git checkout -b storefront
php artisan shopper:kit:install shopperlabs/vue-starter-kit
```
--------------------------------
### Install React Starter Kit
Source: https://docs.laravelshopper.dev/v2/react-starter-kit
Run this command to install the React Starter Kit into your Shopper project. Ensure you have PHP 8.4+, Laravel 12.0+, Shopper 2.9+, and Node.js 20+.
```bash
php artisan shopper:kit:install shopperlabs/react-starter-kit
```
--------------------------------
### Full Example: Loyalty Points Addon Implementation
Source: https://docs.laravelshopper.dev/v2/addons
This example demonstrates a complete Loyalty Addon. It defines routes, livewire components, views, sidebar entries, permissions, and settings. Register the addon in your service provider.
```php
use Shopper\Addon\BaseAddon;
use Shopper\ShopperPanel;
final class LoyaltyAddon extends BaseAddon
{
public function getId(): string
{
return 'loyalty';
}
public function register(ShopperPanel $panel): void
{
$panel->addonRoutes(function () {
Route::middleware(['shopper'])->prefix('loyalty')->name('shopper.loyalty.')->group(function () {
Route::get('/', \App\Livewire\Loyalty\Index::class)->name('index');
Route::get('/tiers', \App\Livewire\Loyalty\Tiers::class)->name('tiers');
});
});
$panel->addonLivewireComponents([
'loyalty-index' => \App\Livewire\Loyalty\Index::class,
'loyalty-tiers' => \App\Livewire\Loyalty\Tiers::class,
'loyalty-customer-points' => \App\Livewire\Loyalty\CustomerPoints::class,
]);
$panel->addonViews('loyalty', __DIR__.'/../resources/views');
$panel->addonSidebar(\App\Sidebar\LoyaltySidebar::class);
$panel->addonPermissions([
'browse_loyalty',
'edit_loyalty',
]);
$panel->addonSettingItems([
\App\Livewire\Settings\LoyaltySettings::class => true,
]);
}
public function boot(ShopperPanel $panel): void
{
\Shopper\View\CustomerRenderHook::class;
$panel->renderHook(
\Shopper\View\CustomerRenderHook::SHOW_TABS_END,
fn (): string => '',
);
}
}
```
```php
use Shopper\Facades\Shopper;
Shopper::addon(new LoyaltyAddon);
```
--------------------------------
### Complete Blog Sidebar Extension Example
Source: https://docs.laravelshopper.dev/v2/sidebar/shopper-extension
A comprehensive example demonstrating how to build a blog sidebar extension, including groups, items, badges for drafts, and quick create buttons for posts.
```php
group(__('Content'), function (Group $group): void {
$group->weight(5);
$group->setAuthorized();
$group->item(__('Blog'), function (Item $item): void {
$item->weight(1);
$item->setAuthorized(fn() => $this->user?->can('manage_blog'));
$item->route('shopper.blog.posts.index');
$item->setIcon('untitledui-edit-04');
// Badge for draft posts
$item->badge(function (Badge $badge): void {
$drafts = Post::draft()->count();
if ($drafts > 0) {
$badge->setValue($drafts);
$badge->setClass('text-xs bg-warning-100 text-warning-700');
}
});
// Quick create button
$item->append(function (Append $append): void {
$append->route('shopper.blog.posts.create');
$append->setIcon('untitledui-plus');
$append->setName(__('New Post'));
});
// Sub-items
$item->item(__('All Posts'), function (Item $subItem): void {
$subItem->weight(1);
$subItem->setAuthorized();
$subItem->useSpa();
$subItem->route('shopper.blog.posts.index');
});
$item->item(__('Categories'), function (Item $subItem): void {
$subItem->weight(2);
$subItem->setAuthorized();
$subItem->useSpa();
$subItem->route('shopper.blog.categories.index');
});
$item->item(__('Tags'), function (Item $subItem): void {
$subItem->weight(3);
$subItem->setAuthorized();
$subItem->useSpa();
$subItem->route('shopper.blog.tags.index');
});
});
$group->item(__('Pages'), function (Item $item): void {
$item->weight(2);
$item->setAuthorized(fn() => $this->user?->can('manage_pages'));
$item->useSpa();
$item->route('shopper.pages.index');
$item->setIcon('untitledui-file-06');
});
});
return $menu;
}
}
```
--------------------------------
### Shopper Kit Manifest Example
Source: https://docs.laravelshopper.dev/v2/starter-kits
This is an example of a `shopper-kit.yaml` manifest file. It defines metadata, version constraints, paths to export, dependencies, and post-installation commands for a starter kit.
```yaml
name: "My Storefront"
description: "A modern storefront for Shopper."
version: "1.0.0"
author: "acme"
url: "https://github.com/acme/my-storefront"
shopper: "^2.7"
php: "^8.4"
laravel: "^12.0"
export_paths:
- resources/views
- resources/css
- routes/web.php
- app/Livewire
dependencies:
- livewire/livewire: "^3.7"
dev_dependencies: []
post_install:
- php artisan migrate
- npm install && npm run build
```
--------------------------------
### Install Stripe Package
Source: https://docs.laravelshopper.dev/v2/addons/stripe
Install the Stripe driver for Shopper using Composer. The service provider is auto-discovered.
```bash
composer require shopper/stripe
```
--------------------------------
### Run Shopper Installer
Source: https://docs.laravelshopper.dev/v2/installation
Execute the Shopper installer command to publish configuration files, create asset symlinks, and optionally run migrations and seeders.
```bash
php artisan shopper:install
```
--------------------------------
### Install Shopper Types with yarn
Source: https://docs.laravelshopper.dev/v2/reference/typescript-types
Install the Shopper types package using yarn.
```bash
yarn add @shopperlabs/shopper-types
```
--------------------------------
### Install Shopper Types with npm
Source: https://docs.laravelshopper.dev/v2/reference/typescript-types
Install the Shopper types package using npm.
```bash
npm install @shopperlabs/shopper-types
```
--------------------------------
### Install Shopper Types with pnpm
Source: https://docs.laravelshopper.dev/v2/reference/typescript-types
Install the Shopper types package using pnpm.
```bash
pnpm add @shopperlabs/shopper-types
```
--------------------------------
### Install AI-Assisted Upgrade Package
Source: https://docs.laravelshopper.dev/v2/upgrade/v2-6-to-v2-7
Install the AI-assisted upgrade package for v2.7 using Composer. This package provides guided migration prompts for breaking changes.
```bash
composer require shopper/upgrade:^2.7 --dev
php artisan boost:install
```
--------------------------------
### Managing Discount Zone
Source: https://docs.laravelshopper.dev/v2/discounts
Examples for retrieving and restricting discounts to specific zones. Use the zone relationship to get the associated zone or update the discount's zone_id.
```php
// Get discount zone (market)
$discount->zone; // Zone model or null
// Restrict discount to a zone
$discount->update(['zone_id' => $zoneId]);
```
--------------------------------
### Install Tailwind CSS and Plugins
Source: https://docs.laravelshopper.dev/v2/extending/control-panel
Install Tailwind CSS v4 with the Vite plugin and the required plugins using npm.
```bash
npm install -D tailwindcss @tailwindcss/vite @tailwindcss/forms @tailwindcss/typography
```
--------------------------------
### Install Shopper Package
Source: https://docs.laravelshopper.dev/v2/installation
Install the Shopper framework package using Composer. Ensure you have Laravel 11.28+ or 12.x installed.
```bash
composer require shopper/framework
```
--------------------------------
### Order Creation Example
Source: https://docs.laravelshopper.dev/v2/events
This snippet shows how an order is created, which automatically dispatches the OrderCreated event.
```php
use Shopper\Core\Models\Order;
$order = Order::query()->create([...]);
```
--------------------------------
### Simple Heading Example
Source: https://docs.laravelshopper.dev/v2/extending/components/heading
A basic example of the Heading component displaying only a title without any actions. This is suitable for pages where only a clear title is needed.
```blade
Dashboard
```
--------------------------------
### Create an About Page Controller
Source: https://docs.laravelshopper.dev/v2/react-starter-kit
Example of a controller to render an 'about' Inertia page.
```php
use App\Models\Page;
use Inertia\Inertia;
use Inertia\Response;
class AboutController extends Controller
{
public function __invoke(): Response
{
return Inertia::render('about');
}
}
```
--------------------------------
### Creating a Product Tag with Associated Products
Source: https://docs.laravelshopper.dev/v2/product-tags
Provides an example of creating a new product tag and then associating it with multiple products.
```php
use Shopper\Core\Models\ProductTag;
$tag = ProductTag::query()->create([
'name' => 'Summer 2026',
'slug' => 'summer-2026',
]);
$tag->products()->attach([$product1->id, $product2->id]);
```
--------------------------------
### Querying Orders by Payment Method
Source: https://docs.laravelshopper.dev/v2/payment-methods
Provides an example of how to query for all orders that used a specific payment method.
```php
Order::query()
->where('payment_method_id', $paymentMethod->id)
->get();
```
--------------------------------
### Initialize Shopper Starter Kit in Custom Path
Source: https://docs.laravelshopper.dev/v2/starter-kits
Specify a custom directory for the new starter kit using the `--path` option.
```bash
php artisan shopper:kit:init --path=../my-starter-kit
```
--------------------------------
### Retrieve All Active Discounts
Source: https://docs.laravelshopper.dev/v2/discounts
Fetches all discounts that are currently active, considering start and end dates. Use this to get a list of all valid promotions.
```php
use Shopper\Core\Models\Discount;
// Get all active discounts
$discounts = Discount::query()
->where('is_active', true)
->where('start_at', '<=', now())
->where(function ($q) {
$q->whereNull('end_at')
->orWhere('end_at', '>', now());
})
->get();
```
--------------------------------
### Customer Usage Examples
Source: https://docs.laravelshopper.dev/v2/reference/types/customer
Provides utility functions for working with Customer objects, such as getting the full name, default shipping address, and marketing opt-in status.
```typescript
import type { Customer } from '@shopperlabs/shopper-types'
// Get full name
function getCustomerName(customer: Customer): string {
if (customer.first_name) {
return `${customer.first_name} ${customer.last_name}`
}
return customer.last_name
}
// Get default shipping address
function getDefaultShippingAddress(customer: Customer) {
return customer.addresses?.find((addr) => addr.shipping_default)
}
// Check if customer has opted in to marketing
function canSendMarketing(customer: Customer): boolean {
return customer.opt_in && customer.email_verified_at !== null
}
```
--------------------------------
### Initialize New Shopper Starter Kit
Source: https://docs.laravelshopper.dev/v2/starter-kits
Use this command to create a new starter kit with the correct directory structure. It will prompt for kit name, package name, description, and author.
```bash
php artisan shopper:kit:init
```
--------------------------------
### Deleting Obsolete System Permissions
Source: https://docs.laravelshopper.dev/v2/upgrade/v2-5-to-v2-6
Provides a code example to manually remove outdated system permissions ('manage_mail', 'impersonate', 'setting_analytics') from the database in v2.6. This is optional for existing installations.
```php
use Shopper\Models\Permission;
Permission::query()->whereIn('name', ['manage_mail', 'impersonate', 'setting_analytics'])->delete();
```
--------------------------------
### Livewire Starter Kit Project Structure
Source: https://docs.laravelshopper.dev/v2/livewire-starter-kit
This outlines the standard directory structure for the Livewire starter kit, showing the placement of application logic, views, and routes.
```text
app/
├── Actions/
│ ├── Cart/
│ │ └── AddToCart.php
│ ├── Checkout/
│ │ ├── BuildShippingPackages.php
│ │ ├── FetchDeliveryRates.php
│ │ ├── FetchPaymentMethods.php
│ │ └── ResolveZoneForCountry.php
│ ├── Fortify/
│ │ ├── CreateNewUser.php
│ │ └── ResetUserPassword.php
│ ├── Product/
│ │ ├── AddProductReviewAction.php
│ │ ├── BuildVariantOptions.php
│ │ └── ResolveVariantAvailability.php
│ ├── CreateOrder.php
│ ├── GetCountriesByZone.php
│ └── ZoneSessionManager.php
├── Concerns/
│ ├── PasswordValidationRules.php
│ └── ProfileValidationRules.php
├── DTO/
│ ├── AddressData.php
│ ├── CountryByZoneData.php
│ ├── PriceData.php
│ └── ProductReviewsData.php
├── Http/Controllers/
│ └── StripeWebhookController.php
├── Livewire/
│ ├── Account/
│ │ ├── AddressForm.php
│ │ └── Addresses.php
│ ├── Actions/
│ │ └── Logout.php
│ ├── Home/
│ │ ├── FeaturedCollections.php
│ │ ├── FeaturedProducts.php
│ │ └── ShopByCategory.php
│ ├── Pages/
│ │ ├── Cart.php
│ │ ├── CategoryIndex.php
│ │ ├── CategoryShow.php
│ │ ├── Checkout.php
│ │ ├── CollectionShow.php
│ │ ├── Home.php
│ │ ├── ProductIndex.php
│ │ ├── ProductShow.php
│ │ ├── SearchProducts.php
│ │ └── StripePayment.php
│ ├── CartCount.php
│ ├── StoreFooter.php
│ ├── StoreHeader.php
│ └── ZoneSelector.php
├── Models/
│ ├── Category.php
│ ├── Channel.php
│ ├── Product.php
│ ├── ProductVariant.php
│ └── User.php
├── Providers/
│ ├── AppServiceProvider.php
│ ├── FortifyServiceProvider.php
│ └── VoltServiceProvider.php
├── Traits/
│ └── HasProductPricing.php
├── CheckoutSession.php
└── helpers.php
resources/views/
├── components/ # Blade components (product cards, price display, badges)
├── layouts/ # Store, account, and auth layouts
├── livewire/ # Livewire component views (header, footer, cart count)
├── pages/
│ ├── auth/ # Login, register, password reset, 2FA
│ ├── home/ # Homepage sections (collections, products, categories)
│ ├── settings/ # Profile, appearance, security
│ ├── shop/ # Product listing, detail, cart, checkout
│ └── account/ # Order history, order detail
└── partials/ # Shared head, settings heading
routes/
├── web.php # Storefront, checkout, account routes
└── settings.php # Profile and security routes
tests/
├── Feature/Auth/ # Authentication tests
└── Feature/Settings/ # Profile and security tests
```
--------------------------------
### React Starter Kit Project Structure
Source: https://docs.laravelshopper.dev/v2/react-starter-kit
This is the complete file structure for the React Starter Kit, showing the organization of application, resources, routes, and tests directories.
```tree
app/
├── Actions/
│ ├── Cart/
│ │ └── AddToCart.php
│ ├── Checkout/
│ │ ├── BuildShippingPackages.php
│ │ ├── FetchDeliveryRates.php
│ │ ├── FetchPaymentMethods.php
│ │ └── ResolveZoneForCountry.php
│ ├── Fortify/
│ │ ├── CreateNewUser.php
│ │ └── ResetUserPassword.php
│ ├── Product/
│ │ ├── AddProductReviewAction.php
│ │ ├── BuildVariantOptions.php
│ │ └── ResolveVariantAvailability.php
│ ├── CreateOrder.php
│ ├── GetCountriesByZone.php
│ └── ZoneSessionManager.php
├── Concerns/
│ ├── InteractsWithStorefrontMedia.php
│ ├── PasswordValidationRules.php
│ └── ProfileValidationRules.php
├── DTO/
│ ├── AddressData.php
│ ├── CountryByZoneData.php
│ ├── PriceData.php
│ └── ProductReviewsData.php
├── Http/
│ ├── Controllers/
│ │ ├── Account/ # Address and order management
│ │ ├── Settings/ # Profile and security
│ │ ├── Shop/ # Home, products, cart, checkout, zone
│ │ └── StripeWebhookController.php
│ ├── Middleware/
│ │ ├── HandleAppearance.php
│ │ └── HandleInertiaRequests.php
│ └── Requests/Settings/ # Profile and password form requests
├── Models/
│ ├── Category.php
│ ├── Channel.php
│ ├── Collection.php
│ ├── Product.php
│ ├── ProductVariant.php
│ └── User.php
├── Providers/
│ ├── AppServiceProvider.php
│ ├── FortifyServiceProvider.php
│ └── TypeScriptTransformerServiceProvider.php
├── Traits/
│ └── HasProductPricing.php
├── CheckoutSession.php
└── helpers.php
resources/js/
├── components/
│ ├── account/ # Order status badge
│ ├── shop/ # Product cards, price display, zone selector, Stripe form
│ └── ui/ # shadcn/ui primitives (button, dialog, select, ...)
├── hooks/ # useCart, useShop, useStripeElements, useAppearance
├── layouts/ # Storefront, account, settings, and auth layouts
├── lib/ # format, stripe, and utility helpers
├── pages/
│ ├── account/ # Orders, order detail, addresses
│ ├── auth/ # Login, register, password reset, 2FA
│ ├── settings/ # Profile, appearance, security
│ └── shop/ # Home, catalog, product, cart, checkout
├── types/ # Shared and generated TypeScript types
└── app.tsx # Inertia application entry point
routes/
├── web.php # Storefront, checkout, account routes
└── settings.php # Profile and security routes
tests/
├── Feature/Auth/ # Authentication tests
└── Feature/Settings/ # Profile and security tests
```
--------------------------------
### Vue Starter Kit Project Structure
Source: https://docs.laravelshopper.dev/v2/vue-starter-kit
Illustrates the directory layout for the Vue Starter Kit, showing the organization of backend PHP files and frontend JavaScript/Vue components.
```tree
app/
├── Actions/
│ ├── Cart/
│ │ └── AddToCart.php
│ ├── Checkout/
│ │ ├── BuildShippingPackages.php
│ │ ├── FetchDeliveryRates.php
│ │ ├── FetchPaymentMethods.php
│ │ └── ResolveZoneForCountry.php
│ ├── Fortify/
│ │ ├── CreateNewUser.php
│ │ └── ResetUserPassword.php
│ ├── Product/
│ │ ├── AddProductReviewAction.php
│ │ ├── BuildVariantOptions.php
│ │ └── ResolveVariantAvailability.php
│ ├── CreateOrder.php
│ ├── GetCountriesByZone.php
│ └── ZoneSessionManager.php
├── Concerns/
│ ├── InteractsWithStorefrontMedia.php
│ ├── PasswordValidationRules.php
│ └── ProfileValidationRules.php
├── DTO/
│ ├── AddressData.php
│ ├── CountryByZoneData.php
│ ├── PriceData.php
│ └── ProductReviewsData.php
├── Http/
│ ├── Controllers/
│ │ ├── Account/ # Address and order management
│ │ ├── Settings/ # Profile and security
│ │ ├── Shop/ # Home, products, cart, checkout, zone
│ │ └── StripeWebhookController.php
│ ├── Middleware/
│ │ ├── HandleAppearance.php
│ │ └── HandleInertiaRequests.php
│ └── Requests/Settings/ # Profile and password form requests
├── Models/
│ ├── Category.php
│ ├── Channel.php
│ ├── Collection.php
│ ├── Product.php
│ ├── ProductVariant.php
│ └── User.php
├── Providers/
│ ├── AppServiceProvider.php
│ ├── FortifyServiceProvider.php
│ └── TypeScriptTransformerServiceProvider.php
├── Traits/
│ └── HasProductPricing.php
├── CheckoutSession.php
└── helpers.php
resources/js/
├── components/
│ ├── account/ # Order status badge
│ ├── shop/ # Product cards, price display, zone selector, Stripe form
│ └── ui/ # shadcn-vue primitives (button, dialog, select, ...)
├── composables/ # useCart, useShop, useStripeElements, useAppearance
├── layouts/ # Storefront, account, settings, and auth layouts
├── lib/ # format, stripe, and utility helpers
├── pages/
│ ├── account/ # Orders, order detail, addresses
│ ├── auth/ # Login, register, password reset, 2FA
│ ├── settings/ # Profile, appearance, security
│ └── shop/ # Home, catalog, product, cart, checkout
├── types/ # Shared and generated TypeScript types
└── app.ts # Inertia application entry point
routes/
├── web.php # Storefront, checkout, account routes
└── settings.php # Profile and security routes
tests/
├── Feature/Auth/ # Authentication tests
└── Feature/Settings/ # Profile and security tests
```
--------------------------------
### Get Total Stock Across Variants
Source: https://docs.laravelshopper.dev/v2/products
Access the 'variants_stock' computed attribute to get the total stock of all variants.
```php
$product->variants_stock;
```
--------------------------------
### Create Fixed Amount and Percentage Discounts
Source: https://docs.laravelshopper.dev/v2/discounts
Demonstrates how to create new discount records, specifying values in cents for fixed amounts and as percentages for percentage-based discounts.
```php
Discount::query()->create([
'code' => 'SAVE10',
'type' => DiscountType::FixedAmount,
'value' => 1000, // 1000 cents = $10.00
]);
Discount::query()->create([
'code' => 'SAVE15',
'type' => DiscountType::Percentage,
'value' => 15, // 15%
]);
```
--------------------------------
### Managing Discount Items (Products and Customers)
Source: https://docs.laravelshopper.dev/v2/discounts
Examples for managing discount items, including adding products or eligible customers to a discount. Ensure the correct DiscountCondition and discountable types are used.
```php
use Shopper\Core\Enum\DiscountCondition;
// Get all discount items (products or customers)
$discount->items; // Collection of DiscountDetail models
// Add a product to discount
$discount->items()->create([
'condition' => DiscountCondition::ApplyTo,
'discountable_type' => Product::class,
'discountable_id' => $productId,
]);
// Add eligible customer
$discount->items()->create([
'condition' => DiscountCondition::Eligibility,
'discountable_type' => User::class,
'discountable_id' => $userId,
]);
```
--------------------------------
### Start Queue Worker
Source: https://docs.laravelshopper.dev/v2/collections
Ensure that background jobs for synchronization are processed by starting a queue worker. This command should be run in your server environment.
```bash
php artisan queue:work
```
--------------------------------
### Creating a Standard Product
Source: https://docs.laravelshopper.dev/v2/products
Create a new standard product with basic details, prices, and categories. Ensure you have brand and currency IDs available.
```php
use Shopper\Models\Product;
use Shopper\Core\Enum\ProductType;
$product = Product::query()->create([
'name' => 'Classic T-Shirt',
'sku' => 'TSHIRT-001',
'type' => ProductType::Standard,
'description' => 'A comfortable cotton t-shirt available in multiple colors.',
'is_visible' => true,
'published_at' => now(),
'brand_id' => $brandId,
]);
$product->prices()->create([
'amount' => 2999,
'currency_id' => $currencyId,
]);
$product->categories()->attach([$categoryId]);
```
--------------------------------
### Install Sidebar Package via Composer
Source: https://docs.laravelshopper.dev/v2/sidebar/standalone
Install the sidebar package using Composer. This is the first step to integrate the package into your Laravel application.
```bash
composer require shopper/sidebar
```
--------------------------------
### Before: Using Repositories in v2.1
Source: https://docs.laravelshopper.dev/v2/upgrade/v2-1-to-v2-2
Illustrates the previous approach of using the Repository pattern in Shopper v2.1 for data retrieval and creation.
```php
use Shopper\Core\Repositories\ProductRepository;
use Shopper\Core\Repositories\UserRepository;
// Using repositories
$products = (new ProductRepository)->all();
$user = (new UserRepository)->create([...]);
// Dependency injection
public function __construct(
private ProductRepository $productRepository
) {}
```
--------------------------------
### Getting Payment Method Logo URL
Source: https://docs.laravelshopper.dev/v2/payment-methods
Illustrates how to get the logo URL for a payment method, falling back to the driver's logo if necessary.
```php
$paymentMethod->logoUrl(); // Media library URL or null
use Shopper\Payment\Services\PaymentProcessingService;
$service = resolve(PaymentProcessingService::class);
$service->getLogoUrl($paymentMethod); // Media URL → driver logo → null
```
--------------------------------
### Create a Supplier and Link Products
Source: https://docs.laravelshopper.dev/v2/suppliers
Create a new supplier record and then associate products with this supplier by updating the product's supplier ID.
```php
use App\Models\Supplier;
// Create your supplier
$supplier = Supplier::query()->create([
'name' => 'Shenzhen TechParts',
'email' => 'orders@techparts.com',
'is_enabled' => true,
]);
// Link products to supplier
$product->update(['supplier_id' => $supplier->id]);
```
--------------------------------
### Get Formatted Attribute Type and Available Types
Source: https://docs.laravelshopper.dev/v2/attributes
Retrieve the formatted, translated label for an attribute's type and get a list of all available attribute types with their labels.
```php
$attribute->type_formatted;
Attribute::typesFields();
```
--------------------------------
### Create Prices in Cents
Source: https://docs.laravelshopper.dev/v2/pricing
Demonstrates how to create price entries for different currencies, storing amounts in cents. Ensure you have the currency IDs available.
```php
use Shopper\Core\Models\Price;
Price::query()->create(['amount' => 2999, 'currency_id' => $usdCurrency->id]);
Price::query()->create(['amount' => 15000, 'currency_id' => $xafCurrency->id]);
```
--------------------------------
### DiscountApplyTo Enum Examples
Source: https://docs.laravelshopper.dev/v2/discounts
Shows the scopes for discount application: Order for the entire purchase and Products for specific items. Discounts applied to products only affect linked items.
```php
use Shopper\Core\Enum\DiscountApplyTo;
DiscountApplyTo::Order // order - Applies to entire order
DiscountApplyTo::Products // products - Applies to specific products
```
--------------------------------
### Product Usage Examples
Source: https://docs.laravelshopper.dev/v2/reference/types/product
Provides utility functions for working with Product objects, including checking if a product is a variant, fetching a product by its slug, determining stock availability, and retrieving the product's primary image.
```typescript
import type { Product } from '@shopperlabs/shopper-types'
import { ProductType } from '@shopperlabs/shopper-types'
function isVariantProduct(product: Product): boolean {
return product.type === ProductType.VARIANT
}
async function fetchProduct(slug: string): Promise {
const response = await fetch(`/api/products/${slug}`)
return response.json()
}
function isInStock(product: Product): boolean {
if (product.type === ProductType.VARIANT) {
return (product.variants_stock ?? 0) > 0
}
return product.stock > 0
}
function getProductImage(product: Product): string | null {
return product.images?.[0]?.url ?? null
}
```
--------------------------------
### Create Basic Customer
Source: https://docs.laravelshopper.dev/v2/customers
Create a new customer user with essential details like name, email, and password. Assign the customer role after creation.
```php
use App\Models\User;
use Shopper\Core\Enum\GenderType;
use Illuminate\Support\Facades\Hash;
$customer = User::query()->create([
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'john@example.com',
'password' => Hash::make('password'),
'gender' => GenderType::Male,
'email_verified_at' => now(),
]);
// Assign customer role
$customer->assignRole(config('shopper.admin.roles.user'));
```
--------------------------------
### Configure Discount Admin UI Components
Source: https://docs.laravelshopper.dev/v2/discounts
Define the pages and components for discount management in the configuration file.
```php
use Shopper\Livewire;
return [
'pages' => [
'discount-index' => Livewire\Pages\Discount\Index::class,
],
'components' => [
'slide-overs.discount-form' => Livewire\SlideOvers\DiscountForm::class,
],
];
```
--------------------------------
### Create an order and associate with a payment method
Source: https://docs.laravelshopper.dev/v2/payment-methods
Demonstrates how to create a new order record and link it to a specific payment method using its ID. Also shows how to access the associated payment method details from the order.
```php
use Shopper
Core
Models
Order;
$order = Order::query()->create([
'number' => $orderNumber,
'customer_id' => $customerId,
'payment_method_id' => $paymentMethod->id,
// ... other order fields
]);
$order->paymentMethod->title;
$order->paymentMethod->instructions;
```
--------------------------------
### Accessing Payment Drivers via Facade
Source: https://docs.laravelshopper.dev/v2/payments
Use the Payment facade to get instances of specific payment drivers or to access driver management methods. You can retrieve a driver by its code, get the default driver, or check driver availability and configuration.
```php
use Shopper\Payment\Facades\Payment;
$stripe = Payment::driver('stripe');
$manual = Payment::driver('manual');
$manual = Payment::driver();
Payment::availableDrivers();
Payment::configuredDrivers();
Payment::isConfigured('stripe');
```
--------------------------------
### Alpine.js Store Setup
Source: https://docs.laravelshopper.dev/v2/sidebar/standalone
Set up the Alpine.js store for sidebar state management by importing and initializing the sidebar store. Ensure you publish the JavaScript files first.
```javascript
import Alpine from 'alpinejs'
import sidebarStore from './vendor/sidebar/stores/sidebar'
Alpine.store('sidebar', sidebarStore())
Alpine.start()
document.addEventListener('alpine:init', () => {
Alpine.store('sidebar').init()
})
```
--------------------------------
### Getting Only Approved Ratings
Source: https://docs.laravelshopper.dev/v2/reviews
Retrieve only the ratings that have been approved.
```php
// Assuming $product is an instance of Product model
$product->getApprovedRatings($product->id);
```
--------------------------------
### Resolve and Handle Actions in PHP
Source: https://docs.laravelshopper.dev/v2/livewire-starter-kit
Demonstrates how to resolve and handle specific actions from the container. Ensure the necessary action classes are imported.
```php
use App\Actions\Cart\AddToCart;
use App\Actions\Checkout\FetchDeliveryRates;
use App\Actions\CreateOrder;
resolve(AddToCart::class)->handle($product, $selectedVariant);
resolve(FetchDeliveryRates::class)->handle($addressData, $packages);
resolve(CreateOrder::class)->handle();
```
--------------------------------
### Counting All Ratings
Source: https://docs.laravelshopper.dev/v2/reviews
Get the total number of ratings for a product.
```php
// Assuming $product is an instance of Product model
$product->countRating(); // Returns integer
```
--------------------------------
### Get Searchable Attributes
Source: https://docs.laravelshopper.dev/v2/attributes
Fetch attributes that are designated as searchable.
```php
use Shopper\
Core\nModels\nAttribute;
Attribute::query()->isSearchable()->get();
```
--------------------------------
### Getting Average Rating
Source: https://docs.laravelshopper.dev/v2/reviews
Calculate the average rating value for a product.
```php
// Assuming $product is an instance of Product model
$product->averageRating(); // Collection with average
```
--------------------------------
### Getting Sum of Ratings
Source: https://docs.laravelshopper.dev/v2/reviews
Calculate the sum of all rating values for a product.
```php
// Assuming $product is an instance of Product model
$product->sumRating(); // Collection with sum
```
--------------------------------
### Create Customer with Address
Source: https://docs.laravelshopper.dev/v2/customers
Create a customer and immediately add a shipping address. Ensure the country ID and address type are correctly specified.
```php
use Shopper\Core\Models\Address;
use Shopper\Core\Enum\AddressType;
$customer = User::query()->create([
'first_name' => 'Jane',
'last_name' => 'Doe',
'email' => 'jane@example.com',
'gender' => GenderType::Female,
'phone_number' => '+1234567890',
'opt_in' => true,
]);
$customer->assignRole(config('shopper.admin.roles.user'));
// Add shipping address
$customer->addresses()->create([
'first_name' => 'Jane',
'last_name' => 'Doe',
'street_address' => '123 Main Street',
'city' => 'New York',
'postal_code' => '10001',
'country_id' => $countryId,
'type' => AddressType::Shipping,
'shipping_default' => true,
]);
```
--------------------------------
### Getting Pending (Not Approved) Ratings
Source: https://docs.laravelshopper.dev/v2/reviews
Retrieve ratings that are pending approval.
```php
// Assuming $product is an instance of Product model
$product->getNotApprovedRatings($product->id);
```
--------------------------------
### Getting All Ratings for a Product
Source: https://docs.laravelshopper.dev/v2/reviews
Retrieve all review models associated with a product.
```php
// Assuming $product is an instance of Product model
$product->ratings; // Collection of Review models
```
--------------------------------
### Example Controller for Admin Posts
Source: https://docs.laravelshopper.dev/v2/extending/controllers
A standard Laravel controller demonstrating methods for listing, creating, and storing posts within the Shopper admin panel.
```php
namespace App\Http\Controllers\Shopper;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
class PostController extends Controller
{
public function index(): View
{
$posts = Post::query()->latest()->paginate(20);
return view('shopper.posts.index', compact('posts'));
}
public function create(): View
{
return view('shopper.posts.create');
}
public function store(Request $request)
{
// Handle form submission
return redirect()->route('shopper.posts.index');
}
}
```
--------------------------------
### Get Order Refund
Source: https://docs.laravelshopper.dev/v2/orders
Retrieve the refund record associated with an order.
```php
$order->refund;
```
--------------------------------
### Get Order Items
Source: https://docs.laravelshopper.dev/v2/orders
Access the collection of items included in an order.
```php
$order->items;
```
--------------------------------
### Retrieve Products from Automatic Collection with Rules
Source: https://docs.laravelshopper.dev/v2/collections
Fetches products from a collection, specifically demonstrating how `getProducts()` works for automatic collections by evaluating their defined rules. This example includes fetching the collection with its rules pre-loaded.
```php
$collection = Collection::query()
->where('slug', 'sale-items')
->with('rules')
->first();
$products = $collection->getProducts();
```
--------------------------------
### Get Filterable Attributes
Source: https://docs.laravelshopper.dev/v2/attributes
Retrieve attributes that are specifically marked as filterable.
```php
use Shopper\
Core\nModels\nAttribute;
Attribute::query()->isFilterable()->get();
```
--------------------------------
### Storefront Product Listing by Channel
Source: https://docs.laravelshopper.dev/v2/channels
Retrieve and display products for the default channel in a storefront. Includes eager loading of brand and categories.
```php
namespace App\Http\Controllers;
use Shopper\Core\Models\Channel;
use Shopper\Models\Product;
class ProductController extends Controller
{
public function index()
{
// Get products for default channel
$channel = Channel::query()->default()->first();
$products = Product::query()
->forChannel($channel->id)
->publish()
->with(['brand', 'categories'])
->paginate(12);
return view('products.index', compact('products'));
}
}
```
--------------------------------
### Publish Customer Component Configuration
Source: https://docs.laravelshopper.dev/v2/customers
Use the Artisan command to publish the customer component configuration file.
```bash
php artisan shopper:component:publish customer
```
--------------------------------
### Get Enabled Attributes
Source: https://docs.laravelshopper.dev/v2/attributes
Filter attributes to retrieve only those that are enabled for use.
```php
use Shopper\
Core\nModels\nAttribute;
Attribute::query()->enabled()->get();
```
--------------------------------
### Initiate a Payment
Source: https://docs.laravelshopper.dev/v2/payments
Start a payment flow by creating a payment session with the provider and recording an 'initiate' transaction. Handles different result types like client secrets for Stripe, redirect URLs for other providers, or immediate completion.
```php
use Shopper\Payment\Services\PaymentProcessingService;
$service = resolve(PaymentProcessingService::class);
$result = $service->initiate($order);
if (! $result->success) {
session()->flash('error', $result->message ?? 'Payment initiation failed.');
return redirect()->route('order-confirmed', $order->number);
}
if ($result->clientSecret) {
session()->put('stripe_payment', [
'client_secret' => $result->clientSecret,
'publishable_key' => $result->data['publishable_key'],
]);
return redirect()->route('stripe-payment', $order->number);
}
if ($result->redirectUrl) {
return redirect($result->redirectUrl);
}
return redirect()->route('order-confirmed', $order->number);
```
--------------------------------
### Basic Label Example
Source: https://docs.laravelshopper.dev/v2/extending/components/label
Shows a simple label with the text 'Username'.
```blade
```
--------------------------------
### Create a Basic Order
Source: https://docs.laravelshopper.dev/v2/orders
Create a new order with essential details like number, customer ID, currency, and status.
```php
use Shopper\Core\Models\Order;
use Shopper\Core\Enum\OrderStatus;
$order = Order::query()->create([
'number' => generate_number(),
'customer_id' => auth()->id(),
'currency_code' => current_currency(),
'channel_id' => $channelId,
'status' => OrderStatus::New,
]);
```
--------------------------------
### Getting Recent Ratings
Source: https://docs.laravelshopper.dev/v2/reviews
Retrieve a specified number of the most recent ratings for a product.
```php
// Assuming $product is an instance of Product model
$product->getRecentRatings($product->id, 5);
```
--------------------------------
### Initialize CarrierRateService and Define Addresses/Packages
Source: https://docs.laravelshopper.dev/v2/carriers
This snippet shows how to instantiate the CarrierRateService and prepare the necessary Address and Package data transfer objects for shipping rate calculations. Ensure all required address fields are populated.
```php
use Shopper\Shipping\Services\CarrierRateService;
use Shopper\Shipping\DataTransferObjects\Address;
use Shopper\Shipping\DataTransferObjects\Package;
$service = app(CarrierRateService::class);
$from = new Address(
firstName: 'Store',
lastName: 'Warehouse',
street: '123 Warehouse St',
city: 'Los Angeles',
postalCode: '90001',
state: 'CA',
country: 'US',
);
$to = new Address(
firstName: 'John',
lastName: 'Doe',
street: '456 Customer Ave',
city: 'New York',
postalCode: '10001',
state: 'NY',
country: 'US',
);
$packages = [
new Package(
length: 30,
width: 20,
height: 15,
weight: 2.5,
unit: 'metric',
),
];
```
--------------------------------
### Getting Ratings with Sorting
Source: https://docs.laravelshopper.dev/v2/reviews
Retrieve all ratings for a product and sort them in descending order.
```php
// Assuming $product is an instance of Product model
$product->getAllRatings($product->id, 'desc');
```
--------------------------------
### Manage Channel Products
Source: https://docs.laravelshopper.dev/v2/channels
Demonstrates how to retrieve, add, remove, and sync products associated with a channel using Eloquent relationships.
```php
// Get all products for a channel
$channel->products; // Collection of Product models
// Add products to channel
$channel->products()->attach([$productId1, $productId2]);
// Remove products from channel
$channel->products()->detach($productId);
// Sync products
$channel->products()->sync($productIds);
```
--------------------------------
### Get Order Addresses
Source: https://docs.laravelshopper.dev/v2/orders
Retrieve the shipping and billing addresses associated with an order.
```php
$order->shippingAddress;
$order->billingAddress;
$order->shippingAddress->full_name;
```
--------------------------------
### Get Location's Country
Source: https://docs.laravelshopper.dev/v2/locations
Access the country associated with a location model.
```php
$location->country; // Country model
```
--------------------------------
### Rendering a Product Page in PHP
Source: https://docs.laravelshopper.dev/v2/react-starter-kit
Shows how a controller renders a product page using Inertia. It loads product data including variants and media.
```php
use App\Models\Product;
use Inertia\Inertia;
use Inertia\Response;
public function show(Product $product): Response
{
return Inertia::render('shop/product', [
'product' => $product->load('variants', 'medias'),
]);
}
```
--------------------------------
### Creating a Free Shipping Option
Source: https://docs.laravelshopper.dev/v2/carriers
Set up a carrier for free shipping, including a specific option with a price of 0 and metadata for order conditions.
```php
$freeShipping = Carrier::query()->create([
'name' => 'Free Shipping',
'slug' => 'free-shipping',
'description' => 'Free standard shipping',
'is_enabled' => true,
]);
$freeShipping->options()->create([
'name' => 'Free Standard Delivery',
'price' => 0,
'zone_id' => $domesticZoneId,
'is_enabled' => true,
'metadata' => [
'min_order_amount' => 5000,
'estimated_days' => '5-7',
],
]);
```
--------------------------------
### Run Composer Update
Source: https://docs.laravelshopper.dev/v2/upgrade/v2-1-to-v2-2
Execute this command after updating your composer.json to install the new dependencies.
```bash
composer update -W
```
--------------------------------
### Full Sidebar Configuration Example
Source: https://docs.laravelshopper.dev/v2/sidebar/configuration
This snippet shows the complete configuration array for the Laravel Sidebar. It covers caching methods and duration, sidebar dimensions for expanded and collapsed states, the responsive breakpoint, and whether the sidebar is collapsible.
```php
[
'method' => env('SIDEBAR_CACHE', null),
'duration' => 1440,
],
/*
|--------------------------------------------------------------------------
| Sidebar Dimensions
|--------------------------------------------------------------------------
|
| Configure the sidebar width for expanded and collapsed states.
| These values will be injected as CSS variables.
|
*/
'width' => '17.5rem',
'collapsed_width' => '4.5rem',
/*
|--------------------------------------------------------------------------
| Responsive Breakpoint
|--------------------------------------------------------------------------
|
| The breakpoint (in pixels) below which the sidebar switches to mobile
| mode (hidden by default, shown via toggle).
|
*/
'breakpoint' => 1024,
/*
|--------------------------------------------------------------------------
| Collapsible
|--------------------------------------------------------------------------
|
| Whether the sidebar can be collapsed on desktop.
|
*/
'collapsible' => true,
];
```
--------------------------------
### Get Order Shipping Information
Source: https://docs.laravelshopper.dev/v2/orders
Access the shipping option and associated shipments for an order.
```php
$order->shippingOption;
$order->shippings;
```
--------------------------------
### Run Tests After Upgrade
Source: https://docs.laravelshopper.dev/v2/upgrade/v2-8-to-v2-9
Execute your test suite to verify that the upgrade process has been completed successfully and no regressions have been introduced.
```bash
php artisan test
```
--------------------------------
### Accessing Currency Information
Source: https://docs.laravelshopper.dev/v2/pricing
Get the Currency model or its code associated with a price record.
```php
$price->currency;
$price->currency_code;
```
--------------------------------
### Get Parent/Child Orders
Source: https://docs.laravelshopper.dev/v2/orders
Access the parent order or child orders for split order scenarios.
```php
$order->parent;
$order->children;
```