blax-software/laravel-shop

A comprehensive headless e-commerce package for Laravel

Installs: 55

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/blax-software/laravel-shop

dev-master 2025-12-20 14:08 UTC

This package is auto-updated.

Last update: 2025-12-20 14:18:12 UTC


README

Tests Latest Version License PHP Version

A comprehensive headless e-commerce package for Laravel with stock management, Stripe integration, and product actions.

Features

  • 🛍️ Product Management - Simple, variable, grouped, and external products
  • 💰 Multi-Currency Support - Handle multiple currencies with ease
  • 📦 Advanced Stock Management - Stock reservations, low stock alerts, and backorders
  • 💳 Stripe Integration - Built-in Stripe product and price synchronization
  • 🎯 Product Actions - Execute custom actions on product events (purchases, refunds)
  • 🔗 Product Relations - Related products, upsells, and cross-sells
  • 🌍 Translation Ready - Built-in meta translation support
  • 📊 Stock Logging - Complete audit trail of stock changes
  • 🎨 Headless Architecture - Perfect for API-first applications
  • Caching Support - Built-in cache management for better performance
  • 🛒 Shopping Capabilities - Built-in trait for any purchaser model
  • 🎭 Facade Support - Clean, expressive API through Shop and Cart facades
  • 👤 Guest Cart Support - Session-based carts for unauthenticated users

Installation

composer require blax-software/laravel-shop

Publish the configuration:

php artisan vendor:publish --provider="Blax\Shop\ShopServiceProvider"

Run migrations:

php artisan migrate

Quick Start

Setup Your User Model

Add the HasShoppingCapabilities trait to any model that should be able to purchase products (typically your User model):

use Blax\Shop\Traits\HasShoppingCapabilities;

class User extends Authenticatable
{
    use HasShoppingCapabilities;
    
    // ...existing code...
}

Creating Your First Product

use Blax\Shop\Models\Product;

$product = Product::create([
    'slug' => 'amazing-t-shirt',
    'sku' => 'TSH-001',
    'type' => 'simple',
    'manage_stock' => true,
    'status' => 'published',
]);

$product->prices()->create([
    'currency' => 'USD',
    'unit_amount' => 1999, // $19.99
    'sale_unit_amount' => 1499, // $14.99
    'is_default' => true,
]);

$product->adjustStock(StockType::INCREASE, 100); // Add 100 items to stock
$product->adjustStock(StockType::DECREASE, 90); // Remove 100 items from stock
$product->adjustStock(
    StockType::CLAIMED, 
    10, 
    from: now(), 
    until: now()->addDay(), 
    note: 'Booked'
); // Claim/reserve 10 stocks


// Add translated name
$product->setLocalized('name', 'Amazing T-Shirt', 'en');
$product->setLocalized('description', 'A comfortable cotton t-shirt', 'en');

Working with Cart (Authenticated Users)

use Blax\Shop\Facades\Cart;
use Blax\Shop\Models\Product;

$product = Product::find($productId);
$user = auth()->user();

// Add to cart (via facade)
Cart::add($product, quantity: 2);

// Or via user trait
$cartItem = $user->addToCart($product, quantity: 1);

// Get cart totals
$total = Cart::total();
$itemCount = Cart::itemCount();

// Check if cart is empty
if (Cart::isEmpty()) {
    // Cart is empty
}

// Remove from cart
Cart::remove($product);

// Clear entire cart
Cart::clear();

// Checkout cart
$completedPurchases = Cart::checkout();

Working with Guest Carts

use Blax\Shop\Facades\Cart;

// Create or retrieve guest cart (uses session ID automatically)
$guestCart = Cart::guest();

// Or with specific session ID
$guestCart = Cart::guest('custom-session-id');

// Add items to guest cart
$guestCart->addToCart($product, quantity: 1);

// Get guest cart totals
$total = Cart::total($guestCart);
$itemCount = Cart::itemCount($guestCart);

// Check if guest cart is empty
if (Cart::isEmpty($guestCart)) {
    // Cart is empty
}

// Clear guest cart
Cart::clear($guestCart);

// Convert guest cart to user cart on login
$guestCart->convertToUserCart($user);

Purchasing Products Directly

use Blax\Shop\Models\Product;

$product = Product::find($productId);
$user = auth()->user();

// Simple purchase
$purchase = $user->purchase($product, quantity: 1);

// Purchase with options
$purchase = $user->purchase($product, quantity: 2, options: [
    'price_id' => $priceId,
    'charge_id' => $paymentIntent->id,
]);

// Check if user has purchased
if ($user->hasPurchased($product)) {
    // Grant access
}

Using Shop Facade

use Blax\Shop\Facades\Shop;

// Get all products
$products = Shop::products()->get();

// Get published products only
$products = Shop::published()->get();

// Get products in stock
$products = Shop::inStock()->get();

// Get featured products
$featured = Shop::featured()->get();

// Search products
$results = Shop::search('t-shirt')->get();

// Check stock availability
if (Shop::checkStock($product, quantity: 5)) {
    // Sufficient stock available
}

// Get available stock
$available = Shop::getAvailableStock($product);

// Check if product is on sale
if (Shop::isOnSale($product)) {
    // Show sale badge
}

// Get configuration
$currency = Shop::currency(); // USD
$config = Shop::config('cart.expire_after_days', 30);

Documentation

Models

The package includes the following models:

  • Product - Main product model with support for simple, variable, grouped, and external products
  • ProductPrice - Multi-currency pricing with sale prices and subscription support
  • ProductCategory - Hierarchical product categories
  • ProductStock - Advanced stock management with reservations and logging
  • ProductAttribute - Product attributes (size, color, material, etc.)
  • ProductPurchase - Purchase records and history
  • ProductAction - Custom actions triggered by product events
  • ProductActionRun - Execution logs for product actions
  • Cart - Shopping cart for authenticated users and guests
  • CartItem - Individual items in a cart
  • PaymentMethod - Saved payment methods
  • PaymentProviderIdentity - Links users to payment providers (Stripe, etc.)

Traits

Available traits for your models:

  • HasShoppingCapabilities - Complete shopping functionality (cart + purchases)
  • HasCart - Cart management functionality only
  • HasPaymentMethods - Payment method management
  • HasStripeAccount - Stripe integration for users
  • HasPrices - Price management (for Product model)
  • HasStocks - Stock management (for Product model)
  • HasCategories - Category relationships (for Product model)
  • HasProductRelations - Related products, upsells, cross-sells
  • HasChargingOptions - Payment processing capabilities

Facades

The package provides two facades for cleaner API access:

Shop Facade

use Blax\Shop\Facades\Shop;

Shop::products()              // Get product query builder
Shop::product($id)            // Find product by ID
Shop::categories()            // Get categories query builder
Shop::inStock()              // Get in-stock products
Shop::featured()             // Get featured products
Shop::published()            // Get published products
Shop::search($query)         // Search products
Shop::checkStock($product, $qty) // Check stock availability
Shop::getAvailableStock($product) // Get available stock quantity
Shop::isOnSale($product)     // Check if product is on sale
Shop::config($key, $default) // Get shop configuration
Shop::currency()             // Get default currency

Cart Facade

use Blax\Shop\Facades\Cart;

Cart::current()                    // Get current user's cart
Cart::guest($sessionId)            // Get/create guest cart
Cart::forUser($user)               // Get cart for specific user
Cart::find($cartId)                // Find cart by ID
Cart::add($product, $qty, $params) // Add item to cart
Cart::remove($product, $qty)       // Remove item from cart
Cart::update($cartItem, $qty)      // Update cart item quantity
Cart::clear($cart)                 // Clear cart items
Cart::checkout($cart)              // Checkout cart
Cart::total($cart)                 // Get cart total
Cart::itemCount($cart)             // Get item count
Cart::items($cart)                 // Get cart items
Cart::isEmpty($cart)               // Check if cart is empty
Cart::isExpired($cart)             // Check if cart is expired
Cart::isConverted($cart)           // Check if cart was converted
Cart::unpaidAmount($cart)          // Get unpaid amount
Cart::paidAmount($cart)            // Get paid amount

Configuration

The config/shop.php file contains all configuration options:

return [
    // Table names (customizable for multi-tenancy)
    'tables' => [
        'products' => 'products',
        'product_categories' => 'product_categories',
        'product_prices' => 'product_prices',
        'product_stocks' => 'product_stocks',
        'product_attributes' => 'product_attributes',
        'product_purchases' => 'product_purchases',
        'product_actions' => 'product_actions',
        'product_action_runs' => 'product_action_runs',
        'product_relations' => 'product_relations',
        'carts' => 'carts',
        'cart_items' => 'cart_items',
        'cart_discounts' => 'cart_discounts',
        'payment_methods' => 'payment_methods',
        'payment_provider_identities' => 'payment_provider_identities',
    ],
    
    // Model classes (allow overriding)
    'models' => [
        'product' => \Blax\Shop\Models\Product::class,
        'product_price' => \Blax\Shop\Models\ProductPrice::class,
        'product_category' => \Blax\Shop\Models\ProductCategory::class,
        'product_stock' => \Blax\Shop\Models\ProductStock::class,
        'product_attribute' => \Blax\Shop\Models\ProductAttribute::class,
        'product_purchase' => \Blax\Shop\Models\ProductPurchase::class,
        'cart' => \Blax\Shop\Models\Cart::class,
        'cart_item' => \Blax\Shop\Models\CartItem::class,
        'payment_provider_identity' => \Blax\Shop\Models\PaymentProviderIdentity::class,
        'payment_method' => \Blax\Shop\Models\PaymentMethod::class,
    ],
    
    // API Routes
    'routes' => [
        'enabled' => true,
        'prefix' => 'api/shop',
        'middleware' => ['api'],
        'name_prefix' => 'shop.',
    ],
    
    // Stock management
    'stock' => [
        'track_inventory' => true,
        'allow_backorders' => false,
        'low_stock_threshold' => 5,
        'log_changes' => true,
        'auto_release_expired' => true,
    ],
    
    // Product actions
    'actions' => [
        'path' => app_path('Jobs/ProductAction'),
        'namespace' => 'App\\Jobs\\ProductAction',
        'auto_discover' => true,
    ],
    
    // Stripe integration
    'stripe' => [
        'enabled' => env('SHOP_STRIPE_ENABLED', false),
        'sync_prices' => true,
    ],
    
    // Cache configuration
    'cache' => [
        'enabled' => env('SHOP_CACHE_ENABLED', true),
        'ttl' => 3600,
        'prefix' => 'shop:',
    ],
    
    // Cart configuration
    'cart' => [
        'expire_after_days' => 30,
        'auto_cleanup' => true,
        'merge_on_login' => true,
    ],
    
    // API response format
    'api' => [
        'include_meta' => true,
        'wrap_response' => true,
        'response_key' => 'data',
    ],
];

Commands

Add Example Products

Create example products for testing and demonstration purposes:

# Create 2 products of each type (default)
php artisan shop:add-example-products

# Create 5 products of each type
php artisan shop:add-example-products --count=5

# Clean existing example products first
php artisan shop:add-example-products --clean

This command creates:

  • ✅ All 4 product types (simple, variable, grouped, external)
  • ✅ Product categories
  • ✅ Product attributes (material, size, color, etc.)
  • ✅ Multiple pricing options (multi-currency, subscriptions)
  • ✅ Example product actions (email notifications, stats updates)
  • ✅ Variations for variable products
  • ✅ Child products for grouped products
  • ✅ Realistic data using Faker

Reinstall Shop Tables

# With confirmation
php artisan shop:reinstall

# Force without confirmation
php artisan shop:reinstall --force

⚠️ Warning: This will delete all shop data!

License

MIT License

Support

For issues and questions, please use the GitHub issue tracker.