Author
Sahil Kumar
Publihsed On
Aug 16, 2024
Updated On
Aug 18, 2024
Category
PHP
Shopping Cart With Checkout System Using PHP, MySQLi & Ajax
Today in this post, I'm going to develop a small web application that is Shopping Cart With Checkout System Using PHP, MySQLi & Ajax, In this application, I'll show you how to display all the products from the database on the home page and I'll show you how to add a product into the cart and then I'll also show you how to checkout with cart products.
So, in this application, I'm using Bootstrap 4 for designing all the pages and I'm using PHP as a back-end language, I'm using MySQLi Prepared Statement for database operation like inserting, fetching, deleting items, I'm using jQuery - Ajax to send the HTTP request to the server and I'm also using Fontawesome library for icons.
Before proceeding, let me tell you what I'm using as a local server, I'm using Xampp Server in which PHP Version > 7.0, So if you are using an older version of PHP then first update your PHP version then start this tutorial.
Now, let's start this tutorial, here I'll post all the source codes of this application. So just follow all the steps carefully.
If you want to watch videos tutorials of this project, then click here.
1. Creating Database & Table
First of all, we'll create a Database and Tables for this project, so for this just open your phpmyadmin in the browser and create a new database with the name "cart_system". After creating the database We'll now create some tables into it, so don't worry I'm giving you the SQL file you just have to import this file into the created database. You can download the SQL file by clicking here. Once you download the SQL file then just click on your database and then click on the Import tab and then click on Choose File and select the downloaded SQL file and finally click on go. After that, you will see three tables have created the cart, orders and product.
2. Creating a Project Directory
In this step, we'll create our project directory inside the htdocs folder, for this just open the htdocs folder and create a new folder with the name "shopping-cart" or anything you want. Now open this folder inside your favourite code editor.
3. Downloading Products Images
When you created a database and table then you can see a product table was there and some records are present in the table, like the below image.
You can see there is a column product_image in which I've written the path of product images. And I've kept the image folder inside my project root directory with all the images. So, you can download all the images from here. Once you download this image.zip then extract this inside your project root directory. You can also add more product into the product table just enter all the details and also write the image path in the product_image column and keep the image in the image folder.
4. Connecting to the Database
In this step, we'll create a new config.php file inside the root of the project directory. By using this file We'll connect our application with the database. Just use the below codes.
<?php
$conn = new mysqli("localhost","root","","cart_system");
if($conn->connect_error){
die("Connection Failed!".$conn->connect_error);
}
?>
5. Creating Home Page & Displaying All Products
In this step, we'll create a new home page index.php file inside the root of the project directory. In this file, we'll design a navbar on the top and then We'll fetch all the products from the database and display them on this page with some product details and an Add to Cart button. Just copy the below codes and paste them into your index.php file and save them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="Sahil Kumar">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Shopping Cart System</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css' />
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css' />
</head>
<body>
<!-- Navbar start -->
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<a class="navbar-brand" href="index.php"><i class="fas fa-mobile-alt"></i> Mobile Store</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="index.php"><i class="fas fa-mobile-alt mr-2"></i>Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-th-list mr-2"></i>Categories</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php"><i class="fas fa-money-check-alt mr-2"></i>Checkout</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php"><i class="fas fa-shopping-cart"></i> <span id="cart-item" class="badge badge-danger"></span></a>
</li>
</ul>
</div>
</nav>
<!-- Navbar end -->
<!-- Displaying Products Start -->
<div class="container">
<div id="message"></div>
<div class="row mt-2 pb-3">
<?php
include 'config.php';
$stmt = $conn->prepare('SELECT * FROM product');
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()):
?>
<div class="col-sm-6 col-md-4 col-lg-3 mb-2">
<div class="card-deck">
<div class="card p-2 border-secondary mb-2">
<img src="<?= $row['product_image'] ?>" class="card-img-top" height="250">
<div class="card-body p-1">
<h4 class="card-title text-center text-info"><?= $row['product_name'] ?></h4>
<h5 class="card-text text-center text-danger"><i class="fas fa-rupee-sign"></i> <?= number_format($row['product_price'],2) ?>/-</h5>
</div>
<div class="card-footer p-1">
<form action="" class="form-submit">
<div class="row p-2">
<div class="col-md-6 py-1 pl-4">
<b>Quantity : </b>
</div>
<div class="col-md-6">
<input type="number" class="form-control pqty" value="<?= $row['product_qty'] ?>">
</div>
</div>
<input type="hidden" class="pid" value="<?= $row['id'] ?>">
<input type="hidden" class="pname" value="<?= $row['product_name'] ?>">
<input type="hidden" class="pprice" value="<?= $row['product_price'] ?>">
<input type="hidden" class="pimage" value="<?= $row['product_image'] ?>">
<input type="hidden" class="pcode" value="<?= $row['product_code'] ?>">
<button class="btn btn-info btn-block addItemBtn"><i class="fas fa-cart-plus"></i> Add to
cart</button>
</form>
</div>
</div>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
<!-- Displaying Products End -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
// Send product details in the server
$(".addItemBtn").click(function(e) {
e.preventDefault();
var $form = $(this).closest(".form-submit");
var pid = $form.find(".pid").val();
var pname = $form.find(".pname").val();
var pprice = $form.find(".pprice").val();
var pimage = $form.find(".pimage").val();
var pcode = $form.find(".pcode").val();
var pqty = $form.find(".pqty").val();
$.ajax({
url: 'action.php',
method: 'post',
data: {
pid: pid,
pname: pname,
pprice: pprice,
pqty: pqty,
pimage: pimage,
pcode: pcode
},
success: function(response) {
$("#message").html(response);
window.scrollTo(0, 0);
load_cart_item_number();
}
});
});
// Load total no.of items added in the cart and display in the navbar
load_cart_item_number();
function load_cart_item_number() {
$.ajax({
url: 'action.php',
method: 'get',
data: {
cartItem: "cart_item"
},
success: function(response) {
$("#cart-item").html(response);
}
});
}
});
</script>
</body>
</html>
In the above coding, you can see I've used bootstrap 4 CDN links, font awesome CDN link and in the below, I've also included jQuery CDN link and Bootstrap 4 JS CDN link.
I've also sent some request to the server using jQuery - Ajax. Once you created this file and open your project in the browser then you'll see something like the below image.
6. Creating an action.php file
Before going further 1st, We'll create a new action.php file in the root of the project directory. In this file, we'll write all the actions like add item to the cart, remove items from the cart, checkout etc. So just copy all the below codes and paste into your action.php file and save them.
<?php
session_start();
require 'config.php';
// Add products into the cart table
if (isset($_POST['pid'])) {
$pid = $_POST['pid'];
$pname = $_POST['pname'];
$pprice = $_POST['pprice'];
$pimage = $_POST['pimage'];
$pcode = $_POST['pcode'];
$pqty = $_POST['pqty'];
$total_price = $pprice * $pqty;
$stmt = $conn->prepare('SELECT product_code FROM cart WHERE product_code=?');
$stmt->bind_param('s',$pcode);
$stmt->execute();
$res = $stmt->get_result();
$r = $res->fetch_assoc();
$code = $r['product_code'] ?? '';
if (!$code) {
$query = $conn->prepare('INSERT INTO cart (product_name,product_price,product_image,qty,total_price,product_code) VALUES (?,?,?,?,?,?)');
$query->bind_param('ssssss',$pname,$pprice,$pimage,$pqty,$total_price,$pcode);
$query->execute();
echo '<div class="alert alert-success alert-dismissible mt-2">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>Item added to your cart!</strong>
</div>';
} else {
echo '<div class="alert alert-danger alert-dismissible mt-2">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>Item already added to your cart!</strong>
</div>';
}
}
// Get no.of items available in the cart table
if (isset($_GET['cartItem']) && isset($_GET['cartItem']) == 'cart_item') {
$stmt = $conn->prepare('SELECT * FROM cart');
$stmt->execute();
$stmt->store_result();
$rows = $stmt->num_rows;
echo $rows;
}
// Remove single items from cart
if (isset($_GET['remove'])) {
$id = $_GET['remove'];
$stmt = $conn->prepare('DELETE FROM cart WHERE id=?');
$stmt->bind_param('i',$id);
$stmt->execute();
$_SESSION['showAlert'] = 'block';
$_SESSION['message'] = 'Item removed from the cart!';
header('location:cart.php');
}
// Remove all items at once from cart
if (isset($_GET['clear'])) {
$stmt = $conn->prepare('DELETE FROM cart');
$stmt->execute();
$_SESSION['showAlert'] = 'block';
$_SESSION['message'] = 'All Item removed from the cart!';
header('location:cart.php');
}
// Set total price of the product in the cart table
if (isset($_POST['qty'])) {
$qty = $_POST['qty'];
$pid = $_POST['pid'];
$pprice = $_POST['pprice'];
$tprice = $qty * $pprice;
$stmt = $conn->prepare('UPDATE cart SET qty=?, total_price=? WHERE id=?');
$stmt->bind_param('isi',$qty,$tprice,$pid);
$stmt->execute();
}
// Checkout and save customer info in the orders table
if (isset($_POST['action']) && isset($_POST['action']) == 'order') {
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$products = $_POST['products'];
$grand_total = $_POST['grand_total'];
$address = $_POST['address'];
$pmode = $_POST['pmode'];
$data = '';
$stmt = $conn->prepare('INSERT INTO orders (name,email,phone,address,pmode,products,amount_paid)VALUES(?,?,?,?,?,?,?)');
$stmt->bind_param('sssssss',$name,$email,$phone,$address,$pmode,$products,$grand_total);
$stmt->execute();
$stmt2 = $conn->prepare('DELETE FROM cart');
$stmt2->execute();
$data .= '<div class="text-center">
<h1 class="display-4 mt-2 text-danger">Thank You!</h1>
<h2 class="text-success">Your Order Placed Successfully!</h2>
<h4 class="bg-danger text-light rounded p-2">Items Purchased : ' . $products . '</h4>
<h4>Your Name : ' . $name . '</h4>
<h4>Your E-mail : ' . $email . '</h4>
<h4>Your Phone : ' . $phone . '</h4>
<h4>Total Amount Paid : ' . number_format($grand_total,2) . '</h4>
<h4>Payment Mode : ' . $pmode . '</h4>
</div>';
echo $data;
}
?>
7. Creating Cart Page
In this step, we'll design our cart page and display all the items present in the cart table. So, for this just create a new file cart.php in the root of the project directory and just copy the below codes and paste in your cart.php file and save.
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="Sahil Kumar">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Cart</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css' />
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css' />
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<!-- Brand -->
<a class="navbar-brand" href="index.php"><i class="fas fa-mobile-alt"></i> Mobile Store</a>
<!-- Toggler/collapsibe Button -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navbar links -->
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="index.php"><i class="fas fa-mobile-alt mr-2"></i>Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-th-list mr-2"></i>Categories</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php"><i class="fas fa-money-check-alt mr-2"></i>Checkout</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php"><i class="fas fa-shopping-cart"></i> <span id="cart-item" class="badge badge-danger"></span></a>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10">
<div style="display:<?php if (isset($_SESSION['showAlert'])) {
echo $_SESSION['showAlert'];
} else {
echo 'none';
} unset($_SESSION['showAlert']); ?>" class="alert alert-success alert-dismissible mt-3">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong><?php if (isset($_SESSION['message'])) {
echo $_SESSION['message'];
} unset($_SESSION['showAlert']); ?></strong>
</div>
<div class="table-responsive mt-2">
<table class="table table-bordered table-striped text-center">
<thead>
<tr>
<td colspan="7">
<h4 class="text-center text-info m-0">Products in your cart!</h4>
</td>
</tr>
<tr>
<th>ID</th>
<th>Image</th>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Total Price</th>
<th>
<a href="action.php?clear=all" class="badge-danger badge p-1" onclick="return confirm('Are you sure want to clear your cart?');"><i class="fas fa-trash"></i> Clear Cart</a>
</th>
</tr>
</thead>
<tbody>
<?php
require 'config.php';
$stmt = $conn->prepare('SELECT * FROM cart');
$stmt->execute();
$result = $stmt->get_result();
$grand_total = 0;
while ($row = $result->fetch_assoc()):
?>
<tr>
<td><?= $row['id'] ?></td>
<input type="hidden" class="pid" value="<?= $row['id'] ?>">
<td><img src="<?= $row['product_image'] ?>" width="50"></td>
<td><?= $row['product_name'] ?></td>
<td>
<i class="fas fa-rupee-sign"></i> <?= number_format($row['product_price'],2); ?>
</td>
<input type="hidden" class="pprice" value="<?= $row['product_price'] ?>">
<td>
<input type="number" class="form-control itemQty" value="<?= $row['qty'] ?>" style="width:75px;">
</td>
<td><i class="fas fa-rupee-sign"></i> <?= number_format($row['total_price'],2); ?></td>
<td>
<a href="action.php?remove=<?= $row['id'] ?>" class="text-danger lead" onclick="return confirm('Are you sure want to remove this item?');"><i class="fas fa-trash-alt"></i></a>
</td>
</tr>
<?php $grand_total += $row['total_price']; ?>
<?php endwhile; ?>
<tr>
<td colspan="3">
<a href="index.php" class="btn btn-success"><i class="fas fa-cart-plus"></i> Continue
Shopping</a>
</td>
<td colspan="2"><b>Grand Total</b></td>
<td><b><i class="fas fa-rupee-sign"></i> <?= number_format($grand_total,2); ?></b></td>
<td>
<a href="checkout.php" class="btn btn-info <?= ($grand_total > 1) ? '' : 'disabled'; ?>"><i class="far fa-credit-card"></i> Checkout</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
// Change the item quantity
$(".itemQty").on('change', function() {
var $el = $(this).closest('tr');
var pid = $el.find(".pid").val();
var pprice = $el.find(".pprice").val();
var qty = $el.find(".itemQty").val();
location.reload(true);
$.ajax({
url: 'action.php',
method: 'post',
cache: false,
data: {
qty: qty,
pid: pid,
pprice: pprice
},
success: function(response) {
console.log(response);
}
});
});
// Load total no.of items added in the cart and display in the navbar
load_cart_item_number();
function load_cart_item_number() {
$.ajax({
url: 'action.php',
method: 'get',
data: {
cartItem: "cart_item"
},
success: function(response) {
$("#cart-item").html(response);
}
});
}
});
</script>
</body>
</html>
In this file also you can see I've designed the same navbar that was on the home page and then I've fetched all the products from the cart table and displayed them in the tabular format. and then you can also see I'm sending two ajax request 1st one is for changing the quantity of the item and 2nd one is for showing the number of items present in the cart table. Once you completed this file then you can see the output like the below image.
8. Creating Checkout Page
In this step, we'll design our checkout page. So, for this just create a new file checkout.php in the root of the project directory. In this file, we'll design a form, and We'll also display some added products information with the total price. In this checkout system I'm not implementing any payment gateway I'm only showing you the concept. You can implement any payment gateway very easily. Just use the below codes and paste them into your checkout.php file and save.
<?php
require 'config.php';
$grand_total = 0;
$allItems = '';
$items = [];
$sql = "SELECT CONCAT(product_name, '(',qty,')') AS ItemQty, total_price FROM cart";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$grand_total += $row['total_price'];
$items[] = $row['ItemQty'];
}
$allItems = implode(', ', $items);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="Sahil Kumar">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Checkout</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css' />
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css' />
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<!-- Brand -->
<a class="navbar-brand" href="index.php"><i class="fas fa-mobile-alt"></i> Mobile Store</a>
<!-- Toggler/collapsibe Button -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navbar links -->
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link active" href="index.php"><i class="fas fa-mobile-alt mr-2"></i>Products</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#"><i class="fas fa-th-list mr-2"></i>Categories</a>
</li>
<li class="nav-item">
<a class="nav-link" href="checkout.php"><i class="fas fa-money-check-alt mr-2"></i>Checkout</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php"><i class="fas fa-shopping-cart"></i> <span id="cart-item" class="badge badge-danger"></span></a>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-6 px-4 pb-4" id="order">
<h4 class="text-center text-info p-2">Complete your order!</h4>
<div class="jumbotron p-3 mb-2 text-center">
<h6 class="lead"><b>Product(s) : </b><?= $allItems; ?></h6>
<h6 class="lead"><b>Delivery Charge : </b>Free</h6>
<h5><b>Total Amount Payable : </b><?= number_format($grand_total,2) ?>/-</h5>
</div>
<form action="" method="post" id="placeOrder">
<input type="hidden" name="products" value="<?= $allItems; ?>">
<input type="hidden" name="grand_total" value="<?= $grand_total; ?>">
<div class="form-group">
<input type="text" name="name" class="form-control" placeholder="Enter Name" required>
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" placeholder="Enter E-Mail" required>
</div>
<div class="form-group">
<input type="tel" name="phone" class="form-control" placeholder="Enter Phone" required>
</div>
<div class="form-group">
<textarea name="address" class="form-control" rows="3" cols="10" placeholder="Enter Delivery Address Here..."></textarea>
</div>
<h6 class="text-center lead">Select Payment Mode</h6>
<div class="form-group">
<select name="pmode" class="form-control">
<option value="" selected disabled>-Select Payment Mode-</option>
<option value="cod">Cash On Delivery</option>
<option value="netbanking">Net Banking</option>
<option value="cards">Debit/Credit Card</option>
</select>
</div>
<div class="form-group">
<input type="submit" name="submit" value="Place Order" class="btn btn-danger btn-block">
</div>
</form>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js'></script>
<script type="text/javascript">
$(document).ready(function() {
// Sending Form data to the server
$("#placeOrder").submit(function(e) {
e.preventDefault();
$.ajax({
url: 'action.php',
method: 'post',
data: $('form').serialize() + "&action=order",
success: function(response) {
$("#order").html(response);
}
});
});
// Load total no.of items added in the cart and display in the navbar
load_cart_item_number();
function load_cart_item_number() {
$.ajax({
url: 'action.php',
method: 'get',
data: {
cartItem: "cart_item"
},
success: function(response) {
$("#cart-item").html(response);
}
});
}
});
</script>
</body>
</html>
In the above file, you can see I'm fetching some product information and displaying it on this page. You can also see I'm sending an ajax request to the server with form data. Once you have done this file then you can see something like the below image.
Once the customer enters his details in the above form and clicks on the place order then the customer's information will be saved in the orders table. And customer sees something like the below image.
Now this project has been finished, try to add any item to the cart and then go to checkout fill out the form and place your order. All your data will be saved to the database.
If you have any issues regarding this project then you can comment down your issues, I'll try to fix them as soon as possible. And If you liked this post then share this post with your friends.
If you want to learn advanced Web Design & Development by watching the video tutorial, then you can visit my YouTube Channel.
Sahil Kumar
Full Stack Web Developer
Hello! I'm a part-time blogger & YouTuber living in India. This is my personal blog where I write Web Design & Development tutorial posts!
Know more about me
SUBMIT GUEST POST 🚀
Ready to contribute? Head to the article dashboard to publish your own insightful articles and share them with our audience!
Go to dashboardRECENT POSTS
Building a Secure Authentication System with PHP OOP, PDO, MySQL, and Bootstrap 5
3 months ago
10 Essential Web Design Principles for Creating a User-Friendly Website
3 months ago
Send Mail with Contact Form Using PHPMailer & Gmail SMTP | 2023
3 months ago
Full Stack Laravel 10 & React JS | SPA Authentication | Part 2
3 months ago
Full Stack Laravel 10 & React JS | SPA Authentication | Part 1
3 months ago