Laravel 12 Simple E-Commerce Application Setup: A Beginner's Guide

Author

Kritim Yantra

May 04, 2025

Laravel 12 Simple E-Commerce Application Setup: A Beginner's Guide

Welcome to this comprehensive guide on setting up a simple e-commerce application using Laravel 12! Whether you're a beginner looking to dive into Laravel development or an experienced developer wanting to brush up on e-commerce fundamentals, this tutorial will walk you through every step of the process.

Laravel is one of the most popular PHP frameworks, known for its elegant syntax and powerful features. By the end of this guide, you'll have a functional e-commerce application with product listings, a shopping cart, and basic checkout functionality.

Prerequisites

Before we begin, make sure you have the following installed on your system:

  1. PHP 8.2 or higher
  2. Composer (PHP dependency manager)
  3. Node.js and npm (for frontend assets)
  4. A database server (MySQL, PostgreSQL, or SQLite)
  5. A code editor (VS Code, PHPStorm, etc.)
  6. Basic understanding of PHP and MVC concepts

Step 1: Install Laravel 12

First, let's create a new Laravel project. Open your terminal and run:

composer create-project laravel/laravel laravel-ecommerce
cd laravel-ecommerce

This will create a new Laravel project in a directory called laravel-ecommerce and navigate into it.

Step 2: Configure Environment Variables

Laravel uses a .env file for environment configuration. Let's set up our database connection:

  1. Rename .env.example to .env
  2. Generate an application key:
    php artisan key:generate
    
  3. Configure your database settings in .env:
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel_ecommerce
    DB_USERNAME=root
    DB_PASSWORD=
    

Adjust these values according to your local database setup.

Step 3: Set Up Authentication

Laravel makes authentication easy with its built-in scaffolding. Let's install it:

composer require laravel/ui
php artisan ui bootstrap --auth
npm install && npm run dev

This will:

  1. Install the Laravel UI package
  2. Set up Bootstrap with authentication views
  3. Install and compile frontend assets

Step 4: Create Database Migrations

Let's create the necessary database tables for our e-commerce application.

Products Table

php artisan make:migration create_products_table

Open the created migration file in database/migrations and modify it:

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->text('description');
    $table->decimal('price', 8, 2);
    $table->string('image')->nullable();
    $table->timestamps();
});

Categories Table (Optional but recommended)

php artisan make:migration create_categories_table

Modify the migration:

Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('slug')->unique();
    $table->timestamps();
});

Add a category_id foreign key to products:

php artisan make:migration add_category_id_to_products_table
Schema::table('products', function (Blueprint $table) {
    $table->foreignId('category_id')->nullable()->constrained()->onDelete('set null');
});

Orders and Order Items Tables

php artisan make:migration create_orders_table
Schema::create('orders', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->decimal('total', 10, 2);
    $table->string('status')->default('pending');
    $table->timestamps();
});

php artisan make:migration create_order_items_table
Schema::create('order_items', function (Blueprint $table) {
    $table->id();
    $table->foreignId('order_id')->constrained();
    $table->foreignId('product_id')->constrained();
    $table->integer('quantity');
    $table->decimal('price', 8, 2);
    $table->timestamps();
});

Run the migrations:

php artisan migrate

Step 5: Create Models and Relationships

Now let's create the Eloquent models for our tables.

Product Model

php artisan make:model Product

Edit app/Models/Product.php:

<?php

namespace App\Models;

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

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'description',
        'price',
        'image',
        'category_id'
    ];

    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

Category Model

php artisan make:model Category

Edit app/Models/Category.php:

<?php

namespace App\Models;

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

class Category extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'slug'];

    public function products()
    {
        return $this->hasMany(Product::class);
    }
}

Order and OrderItem Models

php artisan make:model Order
php artisan make:model OrderItem

Edit app/Models/Order.php:

<?php

namespace App\Models;

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

class Order extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'total',
        'status'
    ];

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }
}

Edit app/Models/OrderItem.php:

<?php

namespace App\Models;

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

class OrderItem extends Model
{
    use HasFactory;

    protected $fillable = [
        'order_id',
        'product_id',
        'quantity',
        'price'
    ];

    public function order()
    {
        return $this->belongsTo(Order::class);
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }
}

Step 6: Create Factories and Seed the Database

Let's create factories to generate test data.

Product Factory

php artisan make:factory ProductFactory

Edit database/factories/ProductFactory.php:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class ProductFactory extends Factory
{
    public function definition(): array
    {
        return [
            'name' => $this->faker->words(3, true),
            'description' => $this->faker->paragraph,
            'price' => $this->faker->randomFloat(2, 10, 1000),
            'image' => $this->faker->imageUrl(400, 300, 'products', true),
            'category_id' => \App\Models\Category::factory(),
        ];
    }
}

Category Factory

php artisan make:factory CategoryFactory

Edit database/factories/CategoryFactory.php:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class CategoryFactory extends Factory
{
    public function definition(): array
    {
        return [
            'name' => $this->faker->word,
            'slug' => $this->faker->slug,
        ];
    }
}

Create a database seeder:

php artisan make:seeder DatabaseSeeder

Edit database/seeders/DatabaseSeeder.php:

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        \App\Models\User::factory()->create([
            'name' => 'Admin User',
            'email' => 'admin@example.com',
            'password' => bcrypt('password'),
        ]);

        \App\Models\Category::factory(5)->create();
        \App\Models\Product::factory(20)->create();
    }
}

Run the seeder:

php artisan db:seed

Step 7: Create Controllers

Let's create controllers for our e-commerce functionality.

Product Controller

php artisan make:controller ProductController --resource

Edit app/Http/Controllers/ProductController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index()
    {
        $products = Product::with('category')->latest()->paginate(12);
        return view('products.index', compact('products'));
    }

    public function show(Product $product)
    {
        return view('products.show', compact('product'));
    }
}

Cart Controller

php artisan make:controller CartController

Edit app/Http/Controllers/CartController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class CartController extends Controller
{
    public function index()
    {
        $cartItems = session()->get('cart', []);
        $total = 0;
        
        foreach ($cartItems as $item) {
            $total += $item['price'] * $item['quantity'];
        }

        return view('cart.index', compact('cartItems', 'total'));
    }

    public function add(Product $product, Request $request)
    {
        $cart = session()->get('cart', []);

        if (isset($cart[$product->id])) {
            $cart[$product->id]['quantity']++;
        } else {
            $cart[$product->id] = [
                'product_id' => $product->id,
                'name' => $product->name,
                'price' => $product->price,
                'quantity' => 1,
                'image' => $product->image
            ];
        }

        session()->put('cart', $cart);
        return redirect()->back()->with('success', 'Product added to cart!');
    }

    public function remove($productId)
    {
        $cart = session()->get('cart', []);

        if (isset($cart[$productId])) {
            unset($cart[$productId]);
            session()->put('cart', $cart);
        }

        return redirect()->back()->with('success', 'Product removed from cart!');
    }

    public function update(Request $request, $productId)
    {
        $cart = session()->get('cart', []);

        if (isset($cart[$productId])) {
            $cart[$productId]['quantity'] = $request->quantity;
            session()->put('cart', $cart);
        }

        return redirect()->back()->with('success', 'Cart updated!');
    }
}

Checkout Controller

php artisan make:controller CheckoutController

Edit app/Http/Controllers/CheckoutController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Order;
use App\Models\OrderItem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class CheckoutController extends Controller
{
    public function index()
    {
        $cartItems = session()->get('cart', []);
        
        if (empty($cartItems)) {
            return redirect()->route('products.index')->with('error', 'Your cart is empty!');
        }

        $total = 0;
        foreach ($cartItems as $item) {
            $total += $item['price'] * $item['quantity'];
        }

        return view('checkout.index', compact('cartItems', 'total'));
    }

    public function store(Request $request)
    {
        $cartItems = session()->get('cart', []);
        
        if (empty($cartItems)) {
            return redirect()->route('products.index')->with('error', 'Your cart is empty!');
        }

        $total = 0;
        foreach ($cartItems as $item) {
            $total += $item['price'] * $item['quantity'];
        }

        $order = Order::create([
            'user_id' => Auth::id(),
            'total' => $total,
            'status' => 'pending'
        ]);

        foreach ($cartItems as $item) {
            OrderItem::create([
                'order_id' => $order->id,
                'product_id' => $item['product_id'],
                'quantity' => $item['quantity'],
                'price' => $item['price']
            ]);
        }

        session()->forget('cart');

        return redirect()->route('orders.show', $order)->with('success', 'Order placed successfully!');
    }
}

Order Controller

php artisan make:controller OrderController

Edit app/Http/Controllers/OrderController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class OrderController extends Controller
{
    public function index()
    {
        $orders = Auth::user()->orders()->latest()->paginate(10);
        return view('orders.index', compact('orders'));
    }

    public function show(Order $order)
    {
        if ($order->user_id !== Auth::id()) {
            abort(403);
        }

        return view('orders.show', compact('order'));
    }
}

Step 8: Create Views

Now let's create the views for our application.

Layout

Create resources/views/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">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel E-Commerce</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    @vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="{{ route('home') }}">Laravel Shop</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav me-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="{{ route('products.index') }}">Products</a>
                    </li>
                </ul>
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link position-relative" href="{{ route('cart.index') }}">
                            Cart
                            @if(count(session()->get('cart', [])))
                                <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
                                    {{ array_sum(array_column(session()->get('cart', []), 'quantity')) }}
                                </span>
                            @endif
                        </a>
                    </li>
                    @auth
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('orders.index') }}">My Orders</a>
                        </li>
                        <li class="nav-item">
                            <form method="POST" action="{{ route('logout') }}">
                                @csrf
                                <button type="submit" class="nav-link btn btn-link">Logout</button>
                            </form>
                        </li>
                    @else
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('login') }}">Login</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="{{ route('register') }}">Register</a>
                        </li>
                    @endauth
                </ul>
            </div>
        </div>
    </nav>

    <div class="container my-4">
        @if(session('success'))
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
        @endif
        @if(session('error'))
            <div class="alert alert-danger">
                {{ session('error') }}
            </div>
        @endif
        
        @yield('content')
    </div>

    <footer class="bg-dark text-white py-4 mt-5">
        <div class="container text-center">
            <p>&copy; {{ date('Y') }} Laravel E-Commerce. All rights reserved.</p>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Products Index View

Create resources/views/products/index.blade.php:

@extends('layouts.app')

@section('content')
<div class="row mb-4">
    <div class="col-12">
        <h1>Our Products</h1>
    </div>
</div>

<div class="row">
    @foreach($products as $product)
    <div class="col-md-4 mb-4">
        <div class="card h-100">
            <img src="{{ $product->image ?? 'https://via.placeholder.com/400x300' }}" class="card-img-top" alt="{{ $product->name }}">
            <div class="card-body">
                <h5 class="card-title">{{ $product->name }}</h5>
                <p class="card-text">{{ Str::limit($product->description, 100) }}</p>
                <p class="h5">${{ number_format($product->price, 2) }}</p>
            </div>
            <div class="card-footer bg-white">
                <a href="{{ route('products.show', $product) }}" class="btn btn-primary">View Details</a>
                <form action="{{ route('cart.add', $product) }}" method="POST" class="d-inline">
                    @csrf
                    <button type="submit" class="btn btn-success">Add to Cart</button>
                </form>
            </div>
        </div>
    </div>
    @endforeach
</div>

<div class="row">
    <div class="col-12">
        {{ $products->links() }}
    </div>
</div>
@endsection

Product Show View

Create resources/views/products/show.blade.php:

@extends('layouts.app')

@section('content')
<div class="row">
    <div class="col-md-6">
        <img src="{{ $product->image ?? 'https://via.placeholder.com/400x300' }}" class="img-fluid" alt="{{ $product->name }}">
    </div>
    <div class="col-md-6">
        <h1>{{ $product->name }}</h1>
        <p class="h3 text-primary">${{ number_format($product->price, 2) }}</p>
        <p>{{ $product->description }}</p>
        
        @if($product->category)
        <p>Category: {{ $product->category->name }}</p>
        @endif

        <form action="{{ route('cart.add', $product) }}" method="POST" class="mt-4">
            @csrf
            <button type="submit" class="btn btn-primary btn-lg">Add to Cart</button>
        </form>
    </div>
</div>
@endsection

Cart Index View

Create resources/views/cart/index.blade.php:

@extends('layouts.app')

@section('content')
<div class="row mb-4">
    <div class="col-12">
        <h1>Shopping Cart</h1>
    </div>
</div>

@if(count($cartItems) > 0)
<div class="row">
    <div class="col-12">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Product</th>
                    <th>Price</th>
                    <th>Quantity</th>
                    <th>Total</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                @foreach($cartItems as $item)
                <tr>
                    <td>
                        <img src="{{ $item['image'] ?? 'https://via.placeholder.com/50' }}" width="50" class="me-2">
                        {{ $item['name'] }}
                    </td>
                    <td>${{ number_format($item['price'], 2) }}</td>
                    <td>
                        <form action="{{ route('cart.update', $item['product_id']) }}" method="POST" class="d-inline">
                            @csrf
                            <input type="number" name="quantity" value="{{ $item['quantity'] }}" min="1" class="form-control d-inline" style="width: 70px;">
                        </form>
                    </td>
                    <td>${{ number_format($item['price'] * $item['quantity'], 2) }}</td>
                    <td>
                        <form action="{{ route('cart.remove', $item['product_id']) }}" method="POST" class="d-inline">
                            @csrf
                            <button type="submit" class="btn btn-danger btn-sm">Remove</button>
                        </form>
                    </td>
                </tr>
                @endforeach
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="3" class="text-end"><strong>Total:</strong></td>
                    <td colspan="2">${{ number_format($total, 2) }}</td>
                </tr>
            </tfoot>
        </table>
    </div>
</div>

<div class="row">
    <div class="col-12 text-end">
        <a href="{{ route('products.index') }}" class="btn btn-secondary">Continue Shopping</a>
        <a href="{{ route('checkout.index') }}" class="btn btn-primary">Proceed to Checkout</a>
    </div>
</div>
@else
<div class="row">
    <div class="col-12">
        <div class="alert alert-info">
            Your cart is empty. <a href="{{ route('products.index') }}">Browse our products</a>.
        </div>
    </div>
</div>
@endif
@endsection

Checkout Views

Create resources/views/checkout/index.blade.php:

@extends('layouts.app')

@section('content')
<div class="row mb-4">
    <div class="col-12">
        <h1>Checkout</h1>
    </div>
</div>

<div class="row">
    <div class="col-md-8">
        <div class="card mb-4">
            <div class="card-header">
                <h4>Order Summary</h4>
            </div>
            <div class="card-body">
                <table class="table">
                    <thead>
                        <tr>
                            <th>Product</th>
                            <th>Price</th>
                            <th>Quantity</th>
                            <th>Total</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach($cartItems as $item)
                        <tr>
                            <td>{{ $item['name'] }}</td>
                            <td>${{ number_format($item['price'], 2) }}</td>
                            <td>{{ $item['quantity'] }}</td>
                            <td>${{ number_format($item['price'] * $item['quantity'], 2) }}</td>
                        </tr>
                        @endforeach
                    </tbody>
                    <tfoot>
                        <tr>
                            <td colspan="3" class="text-end"><strong>Total:</strong></td>
                            <td>${{ number_format($total, 2) }}</td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="card">
            <div class="card-header">
                <h4>Payment Information</h4>
            </div>
            <div class="card-body">
                <form action="{{ route('checkout.store') }}" method="POST">
                    @csrf
                    <div class="mb-3">
                        <label for="name" class="form-label">Name on Card</label>
                        <input type="text" class="form-control" id="name" required>
                    </div>
                    <div class="mb-3">
                        <label for="card" class="form-label">Card Number</label>
                        <input type="text" class="form-control" id="card" required>
                    </div>
                    <div class="row mb-3">
                        <div class="col-md-6">
                            <label for="expiry" class="form-label">Expiry Date</label>
                            <input type="text" class="form-control" id="expiry" placeholder="MM/YY" required>
                        </div>
                        <div class="col-md-6">
                            <label for="cvv" class="form-label">CVV</label>
                            <input type="text" class="form-control" id="cvv" required>
                        </div>
                    </div>
                    <button type="submit" class="btn btn-primary w-100">Place Order</button>
                </form>
            </div>
        </div>
    </div>
</div>
@endsection

Order Views

Create resources/views/orders/index.blade.php:

@extends('layouts.app')

@section('content')
<div class="row mb-4">
    <div class="col-12">
        <h1>My Orders</h1>
    </div>
</div>

<div class="row">
    <div class="col-12">
        @if($orders->count() > 0)
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Order #</th>
                    <th>Date</th>
                    <th>Total</th>
                    <th>Status</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                @foreach($orders as $order)
                <tr>
                    <td>{{ $order->id }}</td>
                    <td>{{ $order->created_at->format('M d, Y') }}</td>
                    <td>${{ number_format($order->total, 2) }}</td>
                    <td>
                        <span class="badge bg-{{ $order->status == 'completed' ? 'success' : 'warning' }}">
                            {{ ucfirst($order->status) }}
                        </span>
                    </td>
                    <td>
                        <a href="{{ route('orders.show', $order) }}" class="btn btn-sm btn-primary">View</a>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
        {{ $orders->links() }}
        @else
        <div class="alert alert-info">
            You haven't placed any orders yet. <a href="{{ route('products.index') }}">Browse our products</a>.
        </div>
        @endif
    </div>
</div>
@endsection

Create resources/views/orders/show.blade.php:

@extends('layouts.app')

@section('content')
<div class="row mb-4">
    <div class="col-12">
        <h1>Order #{{ $order->id }}</h1>
        <p class="text-muted">Placed on {{ $order->created_at->format('F j, Y \a\t g:i a') }}</p>
    </div>
</div>

<div class="row mb-4">
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h4>Order Details</h4>
            </div>
            <div class="card-body">
                <p><strong>Status:</strong> 
                    <span class="badge bg-{{ $order->status == 'completed' ? 'success' : 'warning' }}">
                        {{ ucfirst($order->status) }}
                    </span>
                </p>
                <p><strong>Total:</strong> ${{ number_format($order->total, 2) }}</p>
            </div>
        </div>
    </div>
</div>

<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-header">
                <h4>Order Items</h4>
            </div>
            <div class="card-body">
                <table class="table">
                    <thead>
                        <tr>
                            <th>Product</th>
                            <th>Price</th>
                            <th>Quantity</th>
                            <th>Total</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach($order->items as $item)
                        <tr>
                            <td>{{ $item->product->name }}</td>
                            <td>${{ number_format($item->price, 2) }}</td>
                            <td>{{ $item->quantity }}</td>
                            <td>${{ number_format($item->price * $item->quantity, 2) }}</td>
                        </tr>
                        @endforeach
                    </tbody>
                    <tfoot>
                        <tr>
                            <td colspan="3" class="text-end"><strong>Total:</strong></td>
                            <td>${{ number_format($order->total, 2) }}</td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        </div>
    </div>
</div>
@endsection

Step 9: Set Up Routes

Edit routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\CartController;
use App\Http\Controllers\CheckoutController;
use App\Http\Controllers\OrderController;

Route::get('/', function () {
    return view('welcome');
})->name('home');

Auth::routes();

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

// Products
Route::resource('products', ProductController::class)->only(['index', 'show']);

// Cart
Route::prefix('cart')->group(function () {
    Route::get('/', [CartController::class, 'index'])->name('cart.index');
    Route::post('/add/{product}', [CartController::class, 'add'])->name('cart.add');
    Route::post('/update/{productId}', [CartController::class, 'update'])->name('cart.update');
    Route::post('/remove/{productId}', [CartController::class, 'remove'])->name('cart.remove');
});

// Checkout
Route::prefix('checkout')->group(function () {
    Route::get('/', [CheckoutController::class, 'index'])->name('checkout.index');
    Route::post('/', [CheckoutController::class, 'store'])->name('checkout.store');
});

// Orders
Route::prefix('orders')->group(function () {
    Route::get('/', [OrderController::class, 'index'])->name('orders.index');
    Route::get('/{order}', [OrderController::class, 'show'])->name('orders.show');
});

Step 10: Add Some Styling

Create resources/sass/app.scss:

// Fonts
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');

// Variables
@import 'variables';

// Bootstrap
@import 'bootstrap/scss/bootstrap';

body {
    font-family: 'Open Sans', sans-serif;
}

.card {
    transition: transform 0.3s ease;
    
    &:hover {
        transform: translateY(-5px);
    }
}

.product-image {
    height: 200px;
    object-fit: contain;
}

.badge {
    font-size: 0.8rem;
}

.form-control:focus {
    box-shadow: none;
    border-color: #86b7fe;
}

Step 11: Test the Application

Now that everything is set up, let's test our application:

  1. Start the development server:
    php artisan serve
    
  2. Visit http://localhost:8000 in your browser
  3. Register or log in with the test user we created (admin@example.com / password)
  4. Browse products, add them to your cart, and proceed to checkout
  5. Place an order and view it in your orders list

Step 12: Optional Enhancements

Here are some additional features you could add to make your e-commerce application more robust:

  1. Product Search: Implement a search functionality
  2. Product Filtering: Add filters by category, price range, etc.
  3. User Profiles: Allow users to manage their profile information
  4. Product Reviews: Add a review system for products
  5. Admin Panel: Create an admin interface to manage products, orders, etc.
  6. Payment Integration: Integrate with Stripe or PayPal for real payments
  7. Shipping Options: Add different shipping methods and costs
  8. Discount Codes: Implement coupon/discount code functionality

Conclusion

Congratulations! You've successfully built a simple e-commerce application with Laravel 12. This application includes:

  • Product listings with categories
  • Shopping cart functionality
  • User authentication
  • Order processing
  • Basic checkout flow

This is just the beginning of what you can do with Laravel for e-commerce. From here, you can continue to expand and enhance your application with more advanced features as you become more comfortable with the framework.

Remember to always:

  • Keep security in mind (validate all user input, use prepared statements, etc.)
  • Write tests for your application
  • Follow Laravel best practices
  • Keep your dependencies updated

Happy coding with Laravel!

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts