saeedvir / shopping-cart
A comprehensive shopping cart package for Laravel 11/12 with tax calculation, discounts, coupons, and flexible storage options
Fund package maintenance!
saeedvir
Installs: 4
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/saeedvir/shopping-cart
Requires
- php: ^8.2
- illuminate/cache: ^11.0|^12.0
- illuminate/database: ^11.0|^12.0
- illuminate/session: ^11.0|^12.0
- illuminate/support: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0
- phpunit/phpunit: ^11.0|^12.0
README
A comprehensive shopping cart package for Laravel 11/12 with tax calculation, discounts, coupons, and flexible storage options.
Features
- Item Management: Easily add, update, and remove items from the cart with an intuitive API
- Attributes and Options: Define custom attributes and options for cart items to handle variations like size and color
- Tax Calculation: Built-in support for tax calculations, enabling automatic tax application based on predefined rules
- Discounts and Coupons: Integrate discount codes and coupon functionalities to offer promotions and special offers
- Session and Database Storage: Flexible storage options allow carts to be stored in sessions or the database
- Multiple Cart Instances: Support for multiple cart instances (shopping cart, wishlist, etc.)
- High Performance: Optimized with calculation caching, bulk operations, and efficient database queries
- Memory Efficient: 99% less memory usage with smart data storage
- Customizable: Extend and customize the core functionalities to meet specific business requirements
- Easy Integration: Designed to integrate seamlessly with existing Laravel projects
Requirements
- PHP 8.2 or higher
- Laravel 11.0 or 12.0
Installation
Install the package via Composer:
composer require saeedvir/shopping-cart
Publish the configuration file:
php artisan vendor:publish --tag=shopping-cart-config
If using database storage, publish and run the migrations:
php artisan vendor:publish --tag=shopping-cart-migrations php artisan migrate
Note: The package includes performance optimizations with database indexes. Make sure to run migrations to benefit from optimal query performance.
Configuration
The configuration file is located at config/shopping-cart.php. You can configure:
- Storage driver (session or database)
- Tax settings
- Currency formatting
- Cart expiration
- And more...
return [ 'storage' => 'session', // or 'database' 'tax' => [ 'enabled' => true, 'default_rate' => 0.15, // 15% 'included_in_price' => false, ], 'currency' => [ 'code' => 'USD', 'symbol' => '$', ], ];
Basic Usage
Adding Items to Cart
use Saeedvir\ShoppingCart\Facades\Cart; // Add a product model $product = Product::find(1); Cart::add($product, 2); // Add 2 items // Add with custom attributes Cart::add($product, 1, [ 'size' => 'Large', 'color' => 'Red', ]); // Add manually Cart::add([ 'buyable_type' => Product::class, 'buyable_id' => 1, 'name' => 'Product Name', 'price' => 99.99, ], 1);
Using the Buyable Trait
Add the Buyable trait to your product model:
use Saeedvir\ShoppingCart\Traits\Buyable; class Product extends Model { use Buyable; } // Now you can use convenient methods $product->addToCart(2); $product->inCart(); // Returns true/false $product->removeFromCart();
Retrieving Cart Items
// Get all items $items = Cart::items(); // Get item count $count = Cart::count(); // Check if cart is empty if (Cart::isEmpty()) { // Cart is empty } // Get a specific item $item = Cart::get($itemId);
Updating Items
Cart::update($itemId, [ 'quantity' => 3, 'price' => 89.99, 'attributes' => ['color' => 'Blue'], ]);
Removing Items
// Remove a specific item Cart::remove($itemId); // Clear entire cart Cart::clear(); // Destroy cart (remove from storage) Cart::destroy();
Advanced Features
Multiple Cart Instances
Support different cart types (cart, wishlist, saved items):
// Use wishlist instance Cart::instance('wishlist')->add($product); // Switch back to default cart Cart::instance('default')->items();
Tax Calculation
Taxes are automatically calculated based on configuration:
// Get cart totals $subtotal = Cart::subtotal(); // Before tax $tax = Cart::tax(); // Tax amount $total = Cart::total(); // Final total // Per-item tax foreach (Cart::items() as $item) { echo $item->getTax(); echo $item->getTotal(); }
Discounts and Conditions
Apply discounts, fees, and other conditions:
// Apply percentage discount Cart::condition('sale', 'discount', 10, 'percentage'); // Apply fixed discount Cart::condition('coupon', 'discount', 5.00, 'fixed'); // Apply fee Cart::condition('handling', 'fee', 2.50, 'fixed'); // Remove condition Cart::removeCondition('sale');
Coupon Codes
// Apply coupon with validation Cart::applyCoupon('SAVE20', function ($code, $cart) { // Validate coupon $coupon = Coupon::where('code', $code)->first(); if (!$coupon || $coupon->isExpired()) { return false; } // Apply discount $cart->condition('coupon', 'discount', $coupon->value, 'percentage'); return true; });
Metadata
Store additional cart information:
// Set metadata Cart::setMetadata('note', 'Gift wrapping requested'); Cart::setMetadata('shipping_method', 'express'); // Get metadata $note = Cart::getMetadata('note'); $allMetadata = Cart::getMetadata();
Currency Formatting
Get formatted prices with currency symbols:
// Cart-level formatted amounts echo Cart::formattedSubtotal(); // "$249.99" echo Cart::formattedTax(); // "$37.50" echo Cart::formattedDiscount(); // "$25.00" echo Cart::formattedTotal(); // "$262.49" // Item-level formatted amounts $item = Cart::items()->first(); echo $item->formattedPrice(); // "$99.99" echo $item->formattedSubtotal(); // "$199.98" echo $item->formattedTax(); // "$30.00" echo $item->formattedTotal(); // "$229.98" // Using helper functions echo cart_currency(99.99); // "$99.99" echo cart_currency_symbol(); // "$" echo cart_currency_code(); // "USD"
Loading Product Details (Performance Optimized)
To avoid N+1 queries when displaying products:
// Load all product data at once (no N+1 queries!) $cart = Cart::instance('default'); $cart->loadBuyables(); // Now safely access product details foreach ($cart->items() as $item) { echo $item->buyable->name; echo $item->buyable->description; // No additional queries! }
Cart Summary
// Get complete cart data $summary = Cart::toArray(); /* Returns: [ 'identifier' => 'session_abc123', 'instance' => 'default', 'items' => [...], 'count' => 5, 'subtotal' => 249.99, 'tax' => 37.50, 'discount' => 25.00, 'total' => 262.49, 'conditions' => [...], 'metadata' => [...], ] */
Storage Options
Session Storage (Default)
Cart data is stored in the user's session:
'storage' => 'session',
Database Storage
Cart data is persisted to the database:
'storage' => 'database',
Database storage provides:
- Persistent carts across sessions
- Cart recovery for logged-in users
- Automatic cart expiration
- Better scalability
Performance
The package is highly optimized for production use:
- 99% less memory usage: Smart storage without full object serialization
- 95-99% fewer database queries: Bulk operations and intelligent caching
- 4x faster calculations: Built-in calculation caching
- Database indexes: Optimized queries for large datasets
- Supports 10,000+ concurrent users
- Handles 1000+ item carts efficiently
See PERFORMANCE-SUMMARY.md for detailed benchmarks and PERFORMANCE-QUICK-TIPS.md for best practices.
Events
The package fires events for cart operations (when enabled in config):
CartItemAdded(planned)CartItemUpdated(planned)CartItemRemoved(planned)CartCleared(planned)CartDestroyed(planned)
API Reference
Cart Methods
| Method | Description |
|---|---|
instance(string $instance) |
Set the cart instance |
add($buyable, int $quantity, array $attributes) |
Add item to cart |
update(string $itemId, array $data) |
Update cart item |
remove(string $itemId) |
Remove item from cart |
get(string $itemId) |
Get specific item |
items() |
Get all items |
count() |
Get total item count |
isEmpty() |
Check if cart is empty |
clear() |
Clear cart contents |
destroy() |
Destroy cart |
condition(...) |
Apply condition |
applyCoupon(string $code, callable $validator) |
Apply coupon |
removeCondition(string $name) |
Remove condition |
subtotal() |
Get subtotal |
tax() |
Get tax total |
discount() |
Get discount total |
total() |
Get final total |
setMetadata(string $key, $value) |
Set metadata |
getMetadata(string $key) |
Get metadata |
CartItem Methods
| Method | Description |
|---|---|
getSubtotal() |
Get item subtotal |
getTax() |
Get item tax |
getTotal() |
Get item total |
toArray() |
Convert to array |
Testing
composer test
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
The MIT License (MIT). Please see License File for more information.
Credits
Support
For support, please open an issue on GitHub.