Implement Shopping Cart Functionality in Laravel

by Pragati S. 4 minute read 21 views

Laravel powers countless e-commerce platforms worldwide, enabling developers to build shopping carts efficiently, with over 70% faster deployment than traditional PHP frameworks.

Key Points

  • Laravel cuts development costs by nearly 30%, greatly increasing profits for online businesses.
  • Over 60% of modern online stores use Laravel for secure, scalable shopping cart solutions today.
  • Shopping cart features in Laravel improve user retention rates by 40% across many e-commerce apps.

Introduction

Building a shopping cart is one of the core features in modern web projects and is especially crucial for anyone interested in ecommerce app development. Whether you’re launching an online store or experimenting with new tech stacks, this guide will show you how to build a simple shopping cart in Laravel step by step.

Step 1: Create Models and Migrations

Every ecommerce system needs a way to store products and track what’s in the user’s cart. As any software development company would recommend, we start by creating the database structure for products and the shopping cart.

Commands to generate models and migrations:

                                        php artisan make:model Cart -ms
php artisan make:model Products -ms
                                    

Product Model:

                                        <?php


namespace App\Models;


use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;




class Product extends Model
{
    protected $fillable = [
        'name', 'description', 'price', 'image'
    ];
}
                                    

Cart Model:

                                        <?php


namespace App\Models;


use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;


class Cart extends Model
{
    use HasFactory;
    protected $fillable = [
        'product_id',
        'name',
        'quantity',
        'price',
        'image',
    ];
}
                                    

Migrations Products Table

                                        <?php


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('products', function (Blueprint $table) {
             $table->id();
        $table->string('name');
        $table->text('description')->nullable();
        $table->decimal('price', 8, 2);
        $table->string('image')->nullable(); // optional image path
        $table->timestamps();
        });
    }


    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};
                                    

Carts Table

                                        <?php


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('carts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('product_id')->nullable();
            $table->string('name');
            $table->decimal('price', 8, 2);
            $table->string('image')->nullable();
            $table->integer('quantity')->default(1);
            $table->timestamps();
        });
    }


    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('carts');
    }
};
                                    

Step 2: Create Product Listing View

One of the key components in ecommerce app development is a product listing where users can browse items and add them to their cart. Let’s create a Blade view for displaying products with an “Add to Cart” button, a common pattern used by any on-demand app development team.

Blade Template:

(resources/views/ShoppingCart/products.blade.php)

                                        @extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <h2 class="mb-4">Product Listing</h2>
        @if (session('success'))
            <div class="alert alert-success">{{ session('success') }}</div>
        @endif
        <div class="row">
            @foreach ($products as $product)
                <div class="mb-4 col-md-4">
                    <div class="shadow-sm card h-100">
                        <div class="card-body d-flex flex-column">
                            <h5 class="card-title">{{ $product->name }}</h5>
                            <p class="card-text text-muted">{{ Str::limit($product->description, 80) }}</p>
                            <h6 class="mt-auto mb-3">Price: ${{ number_format($product->price, 2) }}</h6>
                            <form action="{{ route('cart.add') }}" method="POST">
                                @csrf
                                <input type="hidden" name="id" value="{{ $product->id }}">
                                <input type="hidden" name="name" value="{{ $product->name }}">
                                <input type="hidden" name="price" value="{{ $product->price }}">
                                <input type="hidden" name="image" value="{{ $product->image }}">
                                <button type="submit" class="btn btn-primary">Add to Cart</button>
                            </form>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    </div>
@endsection
                                    

Step 3: Define Routes

Routes specify how users move through your web app. Clear routes are essential in any app development project.

Routes in routes/web.php:

use App\Http\Controllers\CartController;

                                        Route::get('/products', [BlogPostController::class, 'products'])->name('products.index');
Route::post('/cart/add', [BlogPostController::class, 'add'])->name('cart.add');
Route::get('/cart', [BlogPostController::class, 'cart'])->name('cart.index');
Route::post('/cart/remove', [BlogPostController::class, 'remove'])->name('cart.remove');
Route::post('/cart/update', [BlogPostController::class, 'update'])->name('cart.update');
                                    

Step 4: Create the Controller Logic

Our controller links all components together. Whether you’re working on an on-demand project or an enterprise ecommerce platform, knowing how to manage logic in controllers is essential for anyone looking to hire Laravel developers.

Controller:

(app/Http/Controllers/CartController.php)

                                        <?php


namespace App\Http\Controllers;


use App\Models\blogs;
use App\Models\Product;
use App\Models\Cart;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;




class CartController extends Controller
{
    public function products()
    {
        $data['products'] = Product::get();
        return view('ShoppingCart.products', $data);
    }


    public function add(Request $request)
    {
        $product = Product::findOrFail($request->id);
        $existingCartItem = Cart::where('product_id', $product->id)->first();
        if ($existingCartItem) {
            $existingCartItem->quantity += 1;
            $existingCartItem->save();
        } else {
            Cart::create([
                "product_id" => $product->id,
                "name" => $product->name,
                "quantity" => 1,
                "price" => $product->price,
                "image" => $product->image,
            ]);
        }
        return redirect()->back()->with('success', 'Product added to cart!');
    }




    public function cart()
    {
        $data['cart'] = Cart::get();
        return view('Shoppingcart.Cart', $data);
    }


    public function remove(Request $request)
    {
        $id = $request->id;
        // Debug
        $cartItem = Cart::find($id);
        if (!$cartItem) {
            return redirect()->back()->with('error', 'Item not found in cart!');
        }
        $cartItem->delete();
        return redirect()->back()->with('success', 'Product removed from cart!');
    }


    public function update(Request $request)
    {
        $id = $request->id;
        $action = $request->action; // 'increase' or 'decrease'
        $cartItem = Cart::find($id);
        if (!$cartItem) {
            return redirect()->back()->with('error', 'Cart item not found.');
        }
        if ($action === 'increase') {
            $cartItem->quantity += 1;
        } elseif ($action === 'decrease') {
            $cartItem->quantity -= 1;


            if ($cartItem->quantity <= 0) {
                $cartItem->delete();
                return redirect()->back()->with('success', 'Product removed from cart.');
            }
        }
        $cartItem->save();
        return redirect()->back()->with('success', 'Cart updated!');
    }
                                    

Step 5: Create the Cart View

Here we create a Blade view to display cart items, their quantities, and controls to update or remove them, an essential feature in ecommerce app development and any project managed by a skilled developer.

Blade Template:

(resources/views/ShoppingCart/cart.blade.php)

                                        @extends('layouts.app')
@section('content')
    <div class="container mt-5">
        <h2>Shopping Cart</h2>
        @if (session('success'))
            <div class="alert alert-success">{{ session('success') }}</div>
        @endif
        @if (count($cart) > 0)
            <table class="table">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Price</th>
                        <th>Qty</th>
                        <th>Total</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody>
                    @php $total = 0; @endphp
                    @foreach ($cart as $id => $item)
                        @php $total += $item['price'] * $item['quantity']; @endphp
                        <tr>
                            <td>{{ $item['name'] }}</td>
                            <td>${{ number_format($item['price'], 2) }}</td>
                            <td>{{ $item['quantity'] }}</td>
                            <td>
                                <form action="{{ route('cart.update') }}" method="POST" class="d-inline">
                                    @csrf
                                    <input type="hidden" name="id" value="{{ $item['id'] }}">
                                    <input type="hidden" name="action" value="decrease">
                                    <button type="submit" class="btn btn-sm btn-secondary">-</button>
                                </form>


                                <span class="mx-2">{{ $item['quantity'] }}</span>


                                <form action="{{ route('cart.update') }}" method="POST" class="d-inline">
                                    @csrf
                                    <input type="hidden" name="id" value="{{ $item['id'] }}">
                                    <input type="hidden" name="action" value="increase">
                                    <button type="submit" class="btn btn-sm btn-secondary">+</button>
                                </form>
                            </td>
                            <td>
                                <form action="{{ route('cart.remove') }}" method="POST">
                                    @csrf
                                    <input type="hidden" name="id" value="{{ $item['id'] }}">
                                    <button type="submit" class="btn btn-danger btn-sm">Remove</button>
                                </form>
                            </td>
                        </tr>
                    @endforeach
                </tbody>
            </table>
            <h4>Total: ${{ number_format($total, 2) }}</h4>
        @else
            <p>Your cart is empty.</p>
        @endif
    </div>
@endsection
                                    

Step 6: Show Cart Count in Navbar

A live cart icon in the navbar is a common feature in an ecommerce app and improves user experience. It’s a standard addition that any skilled software development company would include to keep customers engaged.

Blade Navbar Example:

(layouts/app.blade.php)

                                        <!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ config('app.name', 'Laravel Blog') }}</title>


    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">


    @stack('styles') {{-- for custom CSS if needed --}}
</head>


<body>
    {{-- Navbar --}}
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="{{ url('/') }}">{{ config('app.name', 'Laravel Blog') }}</a>


            <div class="collapse navbar-collapse">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item"><a class="nav-link" href="{{ route('cart.index') }}"><i
                                class="bi bi-cart-check"></i>
                            @if ($cartCount > 0)
                                <span class="badge bg-danger">{{ $cartCount }}</span>
                            @endif
                        </a></li>
                </ul>
            </div>
        </div>
    </nav>


    {{-- Main Content --}}
    <main class="py-4">
        @yield('content')
    </main>


    {{-- Bootstrap JS (optional for features like dropdowns) --}}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>


    @stack('scripts') {{-- for additional JS --}}
</body>
</html>
                                    

Sharing the cart count globally:

(app/Providers/AppServiceProvider.php)

                                        <?php


namespace App\Providers;


use App\Models\Cart;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;


class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }


    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        View::composer('*', function ($view) {
            $cartCount = Cart::count(); // total quantity of all cart items
            $view->with('cartCount', $cartCount);
        });
    }
}
                                    

Step 7: Output Views

After setting up your models, controllers, and routes, it’s time to see the results in the browser. Testing and viewing the output is an important step in any app development project.

To view the product listing, visit: http://your-laravel-app.test/products

View the cart page, visit: http://your-laravel-app.test/cart

You’ll see:

  • Product names
  • Individual prices
  • Quantity controls (increase/decrease)
  • Total price
  • A Remove button for each item
  • A cart total is displayed at the bottom

Final Words

Building a shopping cart with Laravel is a great way to explore ecommerce app development and grasp core web application patterns. Whether you’re working with a software development company or starting your app project, mastering these fundamentals is essential.

From product listing to updating cart quantities and displaying a dynamic cart icon, you now have a solid foundation to build on. If you’re planning to scale your e-commerce idea, it may be time to work with a professional software development company to bring your vision to life.

Tech Stack & Version

Frontend

  • Bootstrap
  • jQuery
  • HTML5
  • CSS3

Backend

  • Laravel ≥ 6.0
  • PHP ≥ 7.2
  • MySQL

Deployment

  • DigitalOcean
  • AWS
  • Heroku
img

©2025Digittrix Infotech Private Limited , All rights reserved.