Build a Shopping Portal with Laravel
Build a Professional Laravel E-Commerce Shopping Cart
Master Laravel by building a full-featured e-commerce platform from scratch. This comprehensive tutorial teaches shopping cart implementation, payment integration, order management, and inventory tracking. Perfect for developers ready to build production-ready e-commerce applications with Laravel.
What You'll Build
- Complete e-commerce platform with product catalog
- Shopping cart with session management
- Checkout process with payment integration (Stripe/PayPal)
- Order tracking and management system
- Admin dashboard for inventory and sales
- Customer accounts and order history
Laravel E-Commerce Skills You'll Master
- Shopping Cart Logic: Session-based cart with add/remove/update functionality
- Eloquent Relationships: Complex database relationships for products, orders, and customers
- Payment Integration: Stripe or PayPal API integration
- Order Management: Complete order workflow from cart to fulfillment
- Authentication: Customer accounts with Laravel Breeze
- Email Notifications: Order confirmations and shipping updates
- Admin Panel: Inventory management and sales analytics
Prerequisites
- Intermediate PHP knowledge
- Basic Laravel experience (or complete our blog/portfolio tutorials first)
- Understanding of e-commerce concepts (cart, checkout, orders)
- MySQL or PostgreSQL database
- Stripe or PayPal developer account (free)
Time Commitment: 10-12 hours total. This is a comprehensive project. Each step includes AI prompts to help you build faster.
Why Laravel for E-Commerce Development?
Laravel's robust ecosystem makes it ideal for e-commerce applications. Built-in features like queue management, event broadcasting, and task scheduling handle complex e-commerce workflows elegantly. Laravel Cashier simplifies subscription billing, while Laravel Nova provides a ready-made admin panel. Major online stores use Laravel for its scalability and maintainability.
This tutorial teaches production-ready e-commerce patterns including secure payment handling, inventory management, and order fulfillment workflows. You'll build something portfolio-worthy that demonstrates advanced Laravel skills employers value. Learn more about Laravel's enterprise features.
Build a Shopping Portal with Laravel
Build a full-featured e-commerce platform with Laravel. PHP framework, the Eloquent ORM, and a SQL database. Laravel gives you everything you need for an online store, including authentication, authorization, payment handling, and email notifications, all written in clear, expressive code thatβs enjoyable to work with. This guide walks you through building a scalable shopping experience with built-in security, smooth payment integration, and the reliability trusted by thousands of real-world e-commerce sites.
Laravel E-Commerce Setup: Installation and Project Configuration
Initialize Laravel project
Initialize a new Laravel e-commerce project using composer create-project laravel/laravel shop Set up the proper folder structure and organize routes (web.php for frontend routes, api.php for API endpoints) Configure the .env file with app name, environment settings, and debug mode Initialize git repository and create .gitignore for Laravel projects Set up proper directory permissions for storage and bootstrap/cache directories Plan your application structure with separate controllers for Shop, Cart, Checkout, Admin, and API.
Configure PHPStorm/VS Code
Set up IDE workspace for Laravel e-commerce development For VS Code, install extensions: Laravel Extension Pack, PHP Intelephense, Laravel Blade Snippets, Laravel Extra Intellisense, Alpine.js IntelliSense Create .vscode/settings.json with PHP formatting rules, blade formatter settings, and file associations Configure PHP CS Fixer or Laravel Pint for code style (PSR-12 standard) Add editor config for consistent formatting (4-space indent for PHP) Set up Xdebug configuration for debugging For PHPStorm, enable Laravel plugin and configure code style for PSR-12.
Laravel Cashier, Laravel Sanctum
Install essential Laravel packages for e-commerce functionality Use composer to install laravel/cashier-stripe for Stripe payment integration, laravel/sanctum for API authentication Install gloudemans/shoppingcart or create custom cart package Add intervention/image for product image manipulation, spatie/laravel-sluggable for automatic product slug generation, spatie/laravel-permission for role/permission management Install laravel/breeze or jetstream for authentication scaffolding Add barryvdh/laravel-debugbar for development Run npm install and add Alpine.js via CDN or npm for interactive components Configure each package: publish config files, run migrations, register service providers as needed.
Database and Environment Configuration for Laravel
Configure MySQL connection
Configure MySQL database connection in .env file. Set DB_CONNECTION=mysql, DB_HOST=127.0.0.1, DB_PORT=3306, DB_DATABASE=shop, DB_USERNAME and DB_PASSWORD Create the database using MySQL Workbench, phpMyAdmin, or command line: CREATE DATABASE shop CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci Test connection using php artisan migrate:status Configure database timezone and charset in config/database.php Set up separate testing database configuration (shop_testing) for running tests Consider connection pooling settings for production Plan database schema for products, categories, orders, order_items, users, cart, reviews, and inventory tables.
products, orders, cart tables
Create comprehensive database migrations for e-commerce tables using php artisan make:migration Design products table with: id, name, slug, description, price, compare_price, cost, sku, barcode, quantity, category_id, brand, images (JSON), is_visible, is_featured, timestamps, soft_deletes Create categories table with: id, name, slug, parent_id, description, is_visible Build orders table with: id, user_id, order_number, status (pending/processing/shipped/completed/cancelled), subtotal, tax, shipping, total, shipping_address (JSON), billing_address (JSON), payment_method, payment_status, timestamps Create order_items table: id, order_id, product_id, quantity, unit_price, total Add cart table: id, user_id, product_id, quantity, timestamps Create product_images table for multiple images Add foreign key constraints, indexes on slug, sku, status, created_at Run migrations with php artisan migrate.
Set up Blade with Alpine.js
Set up Blade template structure in resources/views Create layouts/shop.blade.php as main layout with header (logo, search bar, navigation, cart icon with count badge), main content area, and footer Install and configure Tailwind CSS using npm install -D tailwindcss postcss autoprefixer, then npx tailwindcss init Configure tailwind.config.js to scan blade files and include e-commerce UI plugin Add Alpine.js via CDN or npm for reactive components Create reusable Blade components: components/product-card.blade.php (image, title, price, add-to-cart button), components/cart-icon.blade.php, components/breadcrumb.blade.php, components/product-filter.blade.php Build views: shop/index.blade.php (product listing), shop/show.blade.php (product detail), cart/index.blade.php, checkout/index.blade.php Ensure responsive design with mobile-first approach Add CSS transitions and hover effects. Compile assets with npm run dev.
Building E-Commerce Features: Core Functionality and Admin Panel
Create Product, Order, Cart models
Create comprehensive Eloquent models using php artisan make:model Build Product model with fillable fields (name, slug, description, price, compare_price, cost, sku, quantity, category_id, brand, images, is_visible, is_featured), relationships to Category (belongsTo), OrderItems (hasMany), Reviews (hasMany), automatic slug generation using spatie/sluggable, price accessor/mutator for formatting, inStock scope, featured scope, search scope for filtering Create Category model with parent/children relationships (belongsTo self, hasMany self), products relationship Build Order model with belongsTo User, hasMany OrderItems relationships, order number generation, status transitions, total calculations Create OrderItem model with belongsTo Order and Product Build Cart model or use shoppingcart package Add model observers for inventory management, order number generation Implement casts for JSON fields (images, addresses).
Build product CRUD
Build complete product management system Create ShopController for customer-facing product views with index() to list all visible products with pagination, filtering by category/price/brand using query scopes, sorting options Implement show() to display single product with images, description, reviews, related products, add-to-cart form Create Admin/ProductController using php artisan make:controller Admin/ProductController --resource for admin CRUD operations: index() with search and filtering, create() and store() for adding products with image upload to storage, edit() and update() for editing, destroy() for soft deleting Create form requests for validation: StoreProductRequest, UpdateProductRequest Build admin views: admin/products/index.blade.php with DataTables, create.blade.php and edit.blade.php with rich text editor for description, image upload with preview Implement image handling with intervention/image for resizing/optimization Add product search using Scout or basic LIKE queries Protect admin routes with auth and admin middleware.
Implement cart functionality
Implement shopping cart functionality using gloudemans/shoppingcart package or custom solution Create CartController with methods: add() to add product to cart with quantity and variant options, update() to change quantity, remove() to remove item, clear() to empty cart, getCart() API endpoint returning cart contents For authenticated users, persist cart to database For guests, use session storage Build cart UI in cart/index.blade.php showing: cart items table with product thumbnail, name, price, quantity input with + / - buttons (use Alpine.js for instant updates), remove button, subtotal per item, cart totals section with subtotal, estimated tax, shipping, and total Implement cart badge in header showing item count using Alpine.js or Livewire for reactivity Add "Continue Shopping" and "Proceed to Checkout" buttons. Show empty cart state with message and shop link Validate stock availability when adding to cart Apply coupon code functionality if desired Create CartService class for cart business logic. Sync guest cart to user cart on login.
Build checkout and order processing
Build comprehensive checkout and order processing system Create CheckoutController with methods: index() to show checkout page, processOrder() to handle order submission Build multi-step checkout form in checkout/index.blade.php with sections: 1) Customer information (email, phone), 2) Shipping address (name, address, city, state, zip - with validation), 3) Shipping method (radio buttons for standard/express with prices), 4) Payment information (Stripe Elements or PayPal button), 5) Order review (display all items, addresses, totals) Implement form validation using FormRequest classes: CheckoutRequest Create OrderService class to handle order creation logic: validate cart not empty, validate stock availability, calculate totals (subtotal, tax, shipping, discounts), create Order record, create OrderItems records, reduce product quantities, clear cart, send confirmation email Implement order status tracking Build order confirmation page showing order number, items, shipping info, estimated delivery Add guest checkout option or require registration Store shipping/billing addresses in JSON or separate addresses table. Calculate tax based on location if needed Implement order notifications via email using Laravel notifications.
Integrate Stripe/PayPal
Integrate payment gateway for order processing For Stripe: install Laravel Cashier Stripe (composer require laravel/cashier), configure STRIPE_KEY and STRIPE_SECRET in .env Create PaymentController with methods: createPaymentIntent() to generate client secret for checkout amount, handleWebhook() to process Stripe webhooks for payment confirmation Implement Stripe Elements in checkout blade view: include Stripe.js, create card element, handle form submission with stripe.confirmCardPayment(), show loading states and error messages For PayPal: install PayPal SDK, create PayPal payment buttons, handle payment approval and capture Store payment information in orders table: payment_method, payment_status (pending/completed/failed/refunded), transaction_id, payment_details (JSON) Handle payment success: update order payment_status, send confirmation email, redirect to success page Handle payment failure: show error message, allow retry, don't create order until payment confirmed. Implement refund functionality in admin panel. Set up Stripe webhooks for payment events (payment_intent.succeeded, payment_intent.payment_failed). Test with Stripe test cards. Ensure PCI compliance by never storing card details directly.
Build admin panel
Build comprehensive admin dashboard for e-commerce management Create admin middleware to check user role Set up admin routes prefix in routes/web.php under /admin Create Admin/DashboardController with index() showing key metrics: total sales, order count, revenue charts, recent orders, low stock alerts, popular products Use Chart.js or ApexCharts for visualizations Build order management: Admin/OrderController with index() listing all orders with filtering by status/date, show() displaying full order details, updateStatus() to change order status (processing, shipped, completed, cancelled), printInvoice() to generate PDF invoice using laravel-dompdf Create admin views: admin/dashboard.blade.php with analytics widgets, admin/orders/index.blade.php with searchable/sortable table, admin/orders/show.blade.php with order details and status change form Add product inventory management: show stock levels, bulk update, low stock notifications Implement sales reports: daily/monthly/yearly revenue, top selling products, customer analytics Create admin navigation sidebar with menu items: Dashboard, Products, Categories, Orders, Customers, Reports, Settings Style admin panel with AdminLTE or custom Tailwind UI Implement breadcrumbs for navigation Add activity logs to track admin actions.
Implement customer and admin roles
Implement user roles and permissions system for e-commerce
Install spatie/laravel-permission package: composer require spatie/laravel-permission, publish and run migrations
Define roles: customer, admin, super-admin
Create seeder for roles: php artisan make:seeder RoleSeeder. Assign roles to users: use HasRoles trait in User model
Create middleware for role checking: php artisan make:middleware CheckRole
Protect routes: use middleware('role:admin') on admin routes. Build customer account area with routes: account/dashboard, account/orders (list past orders), account/orders/{id} (view order details), account/profile (edit profile, change password), account/addresses (manage shipping/billing addresses). Create AccountController for customer-facing account management. Implement order history view showing order number, date, status, total, "View Details" and "Reorder" buttons. Allow customers to track order status. Build profile edit form with validation. Add address book management for saving multiple shipping addresses. Protect customer routes with auth middleware. Style account pages with sidebar navigation. For admin: protect all admin routes with role:admin middleware, add super-admin for managing other admins. Add authorization policies for Products, Orders to check user can perform actions. Test role-based access control thoroughly.Product Image Management & Variants
Implement comprehensive product image management for e-commerce store.
Ensure intervention/image is installed: composer require intervention/image.
Configure image storage in config/filesystems.php: create product_images disk pointing to storage/app/public/products, set default quality and format options.
Create migrations for product images: php artisan make:migration create_product_images_table with fields (product_id, image_path, thumbnail_path, medium_path, is_primary, display_order, alt_text, variant_id nullable for variant-specific images), add indexes on product_id and variant_id.
Build ProductImage model: belongsTo Product relationship, belongsTo ProductVariant (if implementing variants), scopes for ordering (orderBy display_order), accessor for public URLs using Storage::url().
Create ImageService class for centralized image operations: upload(UploadedFile $file, $productId) - validates, generates unique filename with Str::uuid(), stores original, resize(string $path) - creates multiple sizes: thumbnail (200x200), medium (600x600), large (1200x1200), uses intervention/image maintain aspect ratio, optimize(string $path) - compresses with quality=85, converts to WebP with fallback, delete($imageId) - removes all size variants from storage.
Update Product model: hasMany ProductImages relationship, define primary_image accessor to get first image or is_primary=true image, implement gallery_images method to get all images ordered by display_order.
Build admin product image management: create image upload form in admin/products/edit.blade.php, implement multi-file upload using Livewire FileUpload or Dropzone.js, show image preview grid with thumbnails after upload, add drag-and-drop reordering using SortableJS with AJAX to update display_order, allow setting primary image with radio button or star icon, include alt text input field for each image, add delete button with confirmation dialog.
Create ImageController for admin operations: store() method for uploading multiple images, destroy() method for deleting images, updateOrder() method for AJAX reordering requests, validate uploaded files (required|image|mimes:jpeg,png,jpg,webp|max:5120).
For product listing pages: display primary product image on product cards, implement hover effect showing secondary image if available, use <img loading="lazy"> for performance, show placeholder for products without images, add "Sale" or "New" badges overlaid on images.
Build product detail image gallery: create product.show Blade view with main large image display and thumbnail strip (grid of small images below or sidebar), implement JavaScript click-to-change main image, add image zoom on hover using CSS or library (Drift.js, ElevateZoom), include full-screen lightbox using PhotoSwipe or GLightbox, support keyboard navigation (arrow keys, ESC), show image counter (e.g., "Image 3 of 5").
Implement responsive image serving: use <picture> element in Blade templates with WebP source and JPEG fallback: <picture><source srcset="{{ Storage::url($image->webp_path) }}" type="image/webp"><img src="{{ Storage::url($image->image_path) }}" alt="{{ $image->alt_text }}"></picture>, implement srcset for responsive sizing, serve appropriate sizes based on viewport.
For product variants (color/size options): link specific images to product variants in product_images table, switch gallery images when customer selects different variant, preload variant images for instant display, maintain zoom/lightbox functionality across variant changes.
Add image optimization queue: implement job for processing images (php artisan make:job ProcessProductImage), dispatch job on image upload for background processing, process: resize, optimize, generate WebP, prevents blocking user during upload.
Implement image metadata and SEO: require alt text in admin forms, use product name + variant in alt text by default, implement schema.org Product markup including image URLs, add multiple images to structured data for rich search results, optimize image filenames (use product slug).
Handle missing images gracefully: create default placeholder image in public/images/placeholder.jpg, show placeholder on products without images, add "upload images" reminder in admin dashboard for products without images.
Create image cleanup artisan command: php artisan make:command CleanOrphanedImages, find images in storage not linked to any product, optionally delete or report orphaned images, schedule to run weekly via Laravel Scheduler.
For production performance: integrate with cloud storage (S3, DigitalOcean Spaces) using Laravel Storage, configure CDN (CloudFlare, AWS CloudFront) for global delivery, implement on-the-fly image transformations with Cloudinary or Imgix, lazy load non-primary images, use progressive JPEG format.
Add image validation in FormRequests: StoreProductImageRequest with rules for type, size, dimensions, batch validation for multiple uploads, custom error messages for better UX.Testing Your Laravel E-Commerce Application
Configure PHPUnit
Set up comprehensive testing infrastructure for Laravel e-commerce. PHPUnit is included by default Configure phpunit.xml with testing database connection (use separate shop_testing database or sqlite in-memory) Set up environment variables in .env.testing: APP_ENV=testing, DB_CONNECTION=sqlite, DB_DATABASE=:memory:, CACHE_DRIVER=array, SESSION_DRIVER=array, QUEUE_CONNECTION=sync Create database factories using php artisan make:factory for Product, Category, Order, OrderItem, User models to generate realistic fake data Create seeders for test data if needed Set up test traits: use RefreshDatabase to reset database between tests, use WithFaker for fake data Create base test classes in tests/Feature and tests/Unit directories Install additional packages: pestphp/pest for modern testing syntax if preferred Create test helpers: createUser(), createAdmin(), createProduct(), addToCart() helper methods Add test scripts to composer.json Configure code coverage reporting Create tests for: model relationships, business logic, cart operations, checkout process, payment processing (mock Stripe), admin operations, authentication and authorization.
Test product listing
Write your first feature test for product listing in tests/Feature/ProductTest.php
Create test using php artisan make:test ProductTest
Test that shop index page returns 200 status code, displays visible products (use factory to create products with is_visible=true), does not show hidden products (is_visible=false), shows product names and prices correctly, pagination works with more than 12 products, breadcrumbs display correctly
Use Laravel testing assertions: assertStatus(200), assertSee($product->name), assertDontSee($hiddenProduct->name), assertViewHas('products'). Test product detail page: create product with factory, visit route('shop.show', $product), assert page returns 200, assert product details display (name, price, description), assert add-to-cart form exists. Test product filtering: create products in different categories, test filtering by category returns only products in that category. Use RefreshDatabase trait to reset database. Run tests with php artisan test or vendor/bin/phpunit. Ensure all assertions pass before proceeding.Test cart and checkout
Write comprehensive feature tests for cart and checkout functionality in tests/Feature/CartTest.php and tests/Feature/CheckoutTest.php
Test cart operations: add product to cart with valid quantity succeeds and shows success message, cart displays added products correctly, update quantity changes cart item quantity and recalculates total, remove item removes product from cart, cart badge shows correct item count, empty cart shows empty state message
Test cart validations: cannot add out-of-stock products, cannot add quantity exceeding available stock, cannot add invalid product ID
Test checkout process: authenticated user can access checkout page, checkout displays cart items and totals correctly, valid checkout form submission creates order, creates order items, reduces product stock quantity, clears cart after successful order
Test checkout validations: required fields must be filled (name, email, address), email format validation, invalid data shows error messages. Mock Stripe payment: use Mockery or Laravel's Http fake to mock Stripe API calls, test successful payment creates order with completed payment status, test failed payment does not create order. Test order confirmation page displays correct order details. Use database assertions: assertDatabaseHas('orders'), assertDatabaseCount('order_items', 2). Test as different user types: guest, authenticated customer, admin. Verify email notifications are sent using Mail::fake().Deploying Your Laravel E-Commerce to Production
Deploy to Laravel Forge
Deploy Laravel e-commerce application to production For Laravel Forge: create Forge account, connect your server provider (DigitalOcean, AWS, Linode), provision new server with PHP 8.2+, MySQL 8, Nginx, Redis Create new site in Forge, connect GitHub/GitLab repository, configure environment variables in Forge dashboard (.env): APP_ENV=production, APP_DEBUG=false, APP_KEY, DB_* credentials, STRIPE_KEY, STRIPE_SECRET, MAIL_* settings Set up deployment script in Forge: git pull, composer install --no-dev --optimize-autoloader, npm ci && npm run build, php artisan migrate --force, php artisan config:cache, php artisan route:cache, php artisan view:cache, php artisan queue:restart Enable Quick Deploy for automatic deployments on git push Configure SSL certificate using Let's Encrypt (automatic in Forge). Set up queue worker for processing jobs. Configure scheduled tasks (Laravel Scheduler) in Forge. For manual deployment: set up server with LEMP stack, install composer, clone repository, copy .env.production to .env, run composer install, generate APP_KEY, run migrations, set permissions on storage and bootstrap/cache. Pre-deployment checklist: run tests (php artisan test), optimize assets (npm run build), test in staging environment, backup database, test Stripe in production mode. Post-deployment: monitor error logs (php artisan telescope in dev, Sentry/Bugsnag in production), set up uptime monitoring, test complete purchase flow, verify emails send correctly. Configure CDN for static assets if high traffic expected.
