One page checkout reduces friction in the buying process, increases conversion and improves the sales. Do you know the cart abandonment rate of the customers during their purchase? Unnecessary, lengthy checkout process is one of the main reason which increases this rate.
Just by fine-tuning your checkout process, you can increase the sales by a staggering 23%. This could be a game changer for many eCommerce websites. I have cited the Baymard Institute research statistics below. Just check it out.
The right ecommerce software and a shopping cart script will definitely have an option for one page checkout. By increasing steps in the checkout flow, you do not have anything to gain. Then why not one page checkout? Not only Baymard Institute’s research, check any parties research statistics in this area and everything points towards a seamless checkout process.
Before going to provide one page checkout for your shopping cart application, we have to know what it is and the significance behind its usage. This article will help you to know about it and its advantages.
Also, I have created an example script in PHP for the implementation of this one page checkout. In a previous article, we have seen a simple PHP shopping cart code and this is its enhanced version.
One page checkout is a way to make the eCommerce checkout process easier. It reduces the navigation effort, page redirects. It gets the job done by retaining the buyer in a single page.
This makes the checkout experience easier with a single checkout click. We will not compromise any feature to implement one page checkout. It may include add-to-cart control, customer’s cart, payment and shipping and more.
Source: Baymard Institute
This example is for creating a one page checkout in PHP. On a single page, I have covered the product gallery and the entire cart flow. It is a lightweight script.
The gallery will show the product tiles with an add-to-cart option. Then the added cart items will have options to edit and delete.
I used jQuery AJAX for requesting the server-side code to perform the cart actions. We have already seen how to perform cart edit with AJAX.
The cart detail table will also a preview for confirmation before checkout. The checkout will need the mandatory billing details customer name and email.
A simple JavaScript validates the billing and payment form. Once the validation step got passed then it will allow the continuing process to checkout in PHP.
I have deployed a demo for this one-page checkout example.
The below button link will redirect you to see this demo. It has the following functionality.
You can try all the above with this demo.
This is the complete file structure on this PHP one-page checkout example.
The figure shows the PHP endpoints, CSS and JS assets, images, data and vendor directories. It also shows the home and other HTML views and PHP classes.
In the following sections, we will see the file’s code and its purpose.
The one-page checkout template includes three major parts. Those are the gallery, cart and the billing & payment form.
I have created separate files for these three display components. Then, I included all into a landing page that is index.php.
index.php
<?php
session_start();
if (isset($_POST["checkout-btn"])) {
$order_number = rand(100, 999);
}
?>
<HTML>
<HEAD>
<TITLE>One Page Checkout Script Free Template</TITLE>
<link href="./assets/css/phppot-style.css" type="text/css"
rel="stylesheet" />
<link href="./assets/css/one-page-checkout.css" type="text/css"
rel="stylesheet" />
<script src="./vendor/jquery/jquery.min.js" type="text/javascript"></script>
<script src="./vendor/jquery/jquery-ui.js"></script>
</HEAD>
<BODY>
<div class="phppot-container">
<div class="page-heading">One Page Checkout Script Free Template</div>
<form name="one-page-checkout-form" id="one-page-checkout-form"
action="" method="post" onsubmit="return checkout()">
<?php if(!empty($order_number)){?>
<div class="order-message order-success">
You order number is <?php echo $order_number;?>.
<span class="btn-message-close"
onclick="this.parentElement.style.display='none';"
title="Close">×</span>
</div>
<?php }?>
<div class="section product-gallery">
<?php require_once './view/product-gallery.php'; ?>
</div>
<div class="billing-details">
<?php require_once './view/billing-details.php'; ?>
</div>
<div class="cart-error-message" id="cart-error-message">Cart
must not be emty to checkout</div>
<div id="shopping-cart" tabindex="1">
<div id="tbl-cart">
<div id="txt-heading">
<div id="cart-heading">Your Shopping Cart</div>
<div id="close"></div>
</div>
<div id="cart-item">
<?php require_once './view/shopping-cart.php'; ?>
</div>
</div>
</div>
<div class="payment-details">
<div class="payment-details-heading">Payment details</div>
<div class="row">
<div class="inline-block">
<div>
<input class="bank-transfer" type="radio"
checked="checked"
value="Direct bank transfer"
name="direct-bank-transfer">Direct bank
transfer
</div>
<div class="info-label">Specify your order
number when you make the bank transfer. Your
order will be shippied after the amount is
credited to us.</div>
</div>
</div>
</div>
<div class="row">
<div id="inline-block">
<input type="submit" class="checkout"
name="checkout-btn" id="checkout-btn"
value="Checkout">
</div>
</div>
</form>
</div>
<script src="./assets/js/cart.js"></script>
<script>
function checkout() {
var valid = true;
$("#first-name").removeClass("error-field");
$("#email").removeClass("error-field");
$("#shopping-cart").removeClass("error-field");
$("#cart-error-message").hide();
var firstName = $("#first-name").val();
var cartItem = $("#cart-item-count").val();
var email = $("#email").val();
var emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
$("#first-name-info").html("").hide();
$("#email-info").html("").hide();
if (firstName.trim() == "") {
$("#first-name-info").html("required.").css("color", "#ee0000").show();
$("#first-name").addClass("error-field");
valid = false;
}
if (email == "") {
$("#email-info").html("required").css("color", "#ee0000").show();
$("#email").addClass("error-field");
valid = false;
} else if (email.trim() == "") {
$("#email-info").html("Invalid email address.").css("color", "#ee0000").show();
$("#email").addClass("error-field");
valid = false;
} else if (!emailRegex.test(email)) {
$("#email-info").html("Invalid email address.").css("color", "#ee0000")
.show();
$("#email").addClass("error-field");
valid = false;
}
if(cartItem == 0){
$("#cart-error-message").show();
$("#shopping-cart").addClass("error-field");
valid = false;
}
if (valid == false) {
$('.error-field').first().focus();
valid = false;
}
return valid;
}
</script>
</BODY>
</HTML>
This file will show a catalog to display available products in a gallery. I have shown three products in this example gallery.
These products are static from a PHP array. You can also include your database component to make it dynamic.
Each tile contains an add-to-cart button. It calls cartAction() jQuery function on its click event.
product-gallery.php
<div id="product-grid">
<div class="txt-heading">Choose your products</div>
<div class="product-item">
<div class="product-image">
<img src="data/camera.jpg" id="<?php echo "3DcAM01";?>"
class="product-img">
</div>
<div>
<strong><?php echo "FinePix Pro2 3D Camera";?></strong>
</div>
<div class="product-price"><?php echo "1500.00";?></div>
<input type="button" id="add_<?php echo "3DcAM01";?>"
value="Add to cart" class="btnAddAction"
onClick="cartAction('add', '<?php echo "3DcAM01";?>','<?php echo "FinePix Pro2 3D Camera";?>','<?php echo "1500.00";?>')" />
</div>
<div class="product-item">
<div class="product-image">
<img src="data/watch.jpg" id="<?php echo "wristWear03";?>"
class="product-img">
</div>
<div>
<strong><?php echo "Luxury Ultra thin Wrist Watch";?></strong>
</div>
<div class="product-price"><?php echo "300.00";?></div>
<input type="button" id="add_<?php echo "wristWear03";?>"
value="Add to cart" class="btnAddAction"
onClick="cartAction('add', '<?php echo "wristWear03";?>','<?php echo "Luxury Ultra thin Wrist Watch";?>','<?php echo "300.00";?>')" />
</div>
<div class="product-item">
<div class="product-image">
<img src="data/laptop.jpg" id="<?php echo "LPN45";?>"
class="product-img">
</div>
<div>
<strong><?php echo "XP 1155 Intel Core Laptop";?></strong>
</div>
<div class="product-price"><?php echo "800.00";?></div>
<input type="button" id="add_<?php echo "LPN45";?>"
value="Add to cart" class="btnAddAction"
onClick="cartAction('add', '<?php echo "LPN45";?>','<?php echo "XP 1155 Intel Core Laptop";?>','<?php echo "800.00";?>')" />
</div>
</div>
I used the PHP session for managing the cart items. The below code shows an HTML code by embedding the cart details into it from the session array.
The cart must have at least one item to proceed with checkout. So I stored the total cart item count in a hidden field. I update this field after every successful cart action.
When you submit with an empty cart, then this example will prevent checkout. It will display validation error by focusing on the empty cart section.
shopping-cart.php
<?php
use Phppot\Cart;
require_once __DIR__ . './../Model/Cart.php';
$cartModel = new Cart();
?>
<input type="hidden" id="cart-item-count"
value="<?php echo $cartModel->cartSessionItemCount; ?>">
<?php
if ($cartModel->cartSessionItemCount > 0) {
?>
<table width="100%" id="cart-table" cellpadding="10" cellspacing="1"
border="0">
<tbody>
<tr>
<th>Name</th>
<th>Quantity</th>
<th class="text-right">Price</th>
<th class="text-right">Action</th>
</tr>
<?php
$item_total = 0;
$i = 1;
foreach ($_SESSION["cart_item"] as $item) {
?>
<tr>
<td><?php echo $item["name"]; ?></td>
<td><input type="number" name="quantity" class="quantity"
value="<?php echo $item['quantity']; ?>"
data-code='<?php echo $item["code"]; ?>' size=2
onChange="updatePrice(this)" /> <input type="hidden" class='total'
name="total" value="<?php echo $item["price"]; ?>" /></td>
<td class="prc text-right" id="price" <?php echo $i;?>><?php echo $item["price"]; ?></td>
<?php $i++; ?>
<td class="text-right"><a
onClick="cartAction('remove','<?php echo $item["code"]; ?>')"
class="btnRemoveAction"><img src="./view/images/icon-delete.png"
alt="Remove Item" /></a></td>
</tr>
<?php
$item_total += ($item["price"] * $item['quantity']);
}
?>
<tr id="tot">
<td class="text-right" colspan="3"><strong>Total (USD): </strong> <span
id="total"><?php echo $item_total;?></span></td>
<td class="text-right"><a id="btnEmpty"
onClick="cartAction('empty', '');">Empty Cart</a></td>
</tr>
</tbody>
</table>
<?php
} else {
?>
<div id="empty-cart">Your cart is empty</div>
<?php
}
This HTML code is for displaying the billing and payment form to the user. The user has to enter the billing details and select the payment method before checkout.
In this example, I have provided only one payment option, Bank Transfer. At the time of processing payment via direct bank transfer, the users refer to the order number.
billing-details.php
<div class="billing-detail-heading">Billing details</div>
<div class="row">
<div class="form-label inline-block">
Name <span class="required error"></span>
</div>
<div class="inline-block">
<div id="first-name-info"></div>
<input class="input-box-330" type="text" name="first-name"
id="first-name">
</div>
</div>
<div class="row">
<div class="form-label">Address</div>
<div class="inline-block">
<input class="input-box-330" class="input-box-330" type="text"
name="address">
</div>
</div>
<div class="row">
<div class="form-label">City</div>
<div class="inline-block">
<input class="input-box-330" type="text" name="city">
</div>
</div>
<div class="row">
<div class="form-label">State</div>
<div class="inline-block">
<input class="input-box-330" type="text" name="state">
</div>
</div>
<div class="row">
<div class="form-label">Zipcode</div>
<div class="inline-block">
<input class="input-box-330" type="text" name="zipcode">
</div>
</div>
<div class="row">
<div class="form-label">
Email Address<span class="required error"></span>
</div>
<div class="inline-block">
<div id="email-info"></div>
<input class="input-box-330" type="text" name="email" id="email">
</div>
</div>
The cartAction() method is for handling the add, edit, remove and empty-cart actions. It has a switch case to perform these actions.
It receives the action parameter and sends the control flow to the appropriate case. It also gets the product title, code and price.
I prepare a query string by using the product details and request PHP via AJAX. After performing the cart action, the PHP code will return the response.
In the success block, we can receive this response for updating the cart.
cart.js
function cartAction(action, product_code, productTitle, productPrice) {
var queryString = "";
if (action != "") {
switch (action) {
case "add":
queryString = 'action=' + action + '&code=' + product_code
+ '&quantity=' + 1 + '&productTitle=' + productTitle
+ '&productPrice=' + productPrice;
break;
case "remove":
queryString = 'action=' + action + '&code=' + product_code;
break;
case "empty":
queryString = 'action=' + action;
break;
}
}
jQuery.ajax({
url : "ajax/handle-cart-ep.php",
data : queryString,
type : "POST",
success : function(data) {
$("#cart-item").html(data);
$("#count").text($("#cart-item-count").val());
},
error : function() {
}
});
}
function updatePrice(obj) {
var quantity = $(obj).val();
var code = $(obj).data('code');
queryString = 'action=edit&code=' + code + '&quantity=' + quantity;
$.ajax({
type : 'post',
url : "ajax/handle-cart-ep.php",
data : queryString,
success : function(data) {
$("#total").text(data);
}
});
}
This is the PHP endpoint called via AJAX. As like as the JavaScript method, this PHP file also contains a switch case to control the cart action.
The Cart.php included in this file is a Model class that executes all the cart operations.
In this endpoint, I instantiate this model and invoke its methods based on the request.
On each cart action, it iterates the latest cart session to prepare the response.
ajax/handle-cart-ep.php
<?php
namespace Phppot;
use \Phppot\Cart;
require_once __DIR__ . './../Model/Cart.php';
$cartModel = new Cart();
session_start();
if (! empty($_POST["action"])) {
switch ($_POST["action"]) {
case "add":
$cartModel->addToCart();
break;
case "edit":
$totalPrice = $cartModel->editCart();
print $totalPrice;
exit;
break;
case "remove":
$cartModel->removeFromCart();
break;
case "empty":
$cartModel->emptyCart();
break;
}
}
require_once '../view/shopping-cart.php';
The below code shows the Cart class. It handles and updates the cart session on each cart action.
The emptyCart() method wipes out the cart by clearing the current session.
Model/Cart.php
<?php
namespace Phppot;
class Cart
{
public $cartSessionItemCount = 0;
function __construct()
{
if (! empty($_SESSION["cart_item"]) && is_array($_SESSION["cart_item"])) {
$this->cartSessionItemCount = count($_SESSION["cart_item"]);
}
}
function addToCart()
{
if (isset($_POST)) {
$productCode = $_POST["code"];
$productTitle = $_POST["productTitle"];
$poductQuantity = $_POST["quantity"];
$productPrice = $_POST["productPrice"];
}
$cartItem = array(
'code' => $productCode,
'name' => $productTitle,
'quantity' => $poductQuantity,
'price' => $productPrice
);
$_SESSION["cart_item"][$productCode] = $cartItem;
if (! empty($_SESSION["cart_item"]) && is_array($_SESSION["cart_item"])) {
$this->cartSessionItemCount = count($_SESSION["cart_item"]);
}
}
function editCart()
{
if (! empty($_SESSION["cart_item"])) {
$total_price = 0;
foreach ($_SESSION["cart_item"] as $k => $v) {
if ($_POST["code"] == $k) {
$_SESSION["cart_item"][$k]["quantity"] = $_POST["quantity"];
}
$total_price = $total_price + ($_SESSION["cart_item"][$k]["quantity"] * $_SESSION["cart_item"][$k]["price"]);
}
return $total_price;
}
if (! empty($_SESSION["cart_item"]) && is_array($_SESSION["cart_item"])) {
$this->cartSessionItemCount = count($_SESSION["cart_item"]);
}
}
function removeFromCart()
{
if (! empty($_SESSION["cart_item"])) {
foreach ($_SESSION["cart_item"] as $k => $v) {
if ($_POST["code"] == $k)
unset($_SESSION["cart_item"][$k]);
if (empty($_SESSION["cart_item"]))
unset($_SESSION["cart_item"]);
}
}
if (! empty($_SESSION["cart_item"]) && is_array($_SESSION["cart_item"])) {
$this->cartSessionItemCount = count($_SESSION["cart_item"]);
}
}
function emptyCart()
{
unset($_SESSION["cart_item"]);
$this->cartSessionItemCount = 0;
}
}
In this example code, there are places to bring the database into the picture. For example, the product gallery and the cart.
I have managed the gallery with a PHP array. And, I handled the cart session with PHP $_SESSION.
If you manage the shopping cart with a database, then it will help you to have a persistent cart. I have already given an example of building a persistent shopping cart in PHP.
You can plugin your database module into this example code to store products. If you want to show your shopping cart products gallery from a database, this link has an example.
See the screenshot shows the product gallery, cart and checkout on one page. The gallery shows three product tiles.
By clicking the Add to cart button, the cart will have a new entry as shown below.
The Checkout button click will place the order for the added cart items.
Hello,
It was a successful work, thank you.
But the basket can not be -1
How do I integrate this project in Codeigniter?
Hi Zafer,
Welcome. Yes, you need to plugin a validation to check for negative quantity in the cart. Converting it to CodeIgniter should be a straightforward job, developers have done it and has shown me examples. Also for Laravel too. You should have good understanding of the framework.
Thanks for this example, I have learned a lot. But I’m wondering: If I change with the inspector the values of price it passes to the cart (the modified price). How can we avoid this, Because I could make any item cost whatever I want.
Hi Esteban,
You need to customize the cart logic to suit this.
Yes you are right, but that can be solved while updating cart you must update it from database use ajax to avoid page reload. So even user changes the price quantity still at checkout and in the cart field we can have real values from database.
hi, how can I add “max product in magazine” ? and sold-out?
Hi Rino,
You should define a constant for each product id wise. You may choose to have it in a database or a constant file. Then you to maintain current stock on every sale and based on that the sold-out message can be shwon.
Hi there,
Thank you for this as I am trying to put a simple one product cart together. I managed to put it all in good working order but cannot seem to get the Form Action to work properly. Please do you have a Form Action script that I can use with the php file that I can just place?
Please can you help?
warmest
Aubrey
Hi Aubrey,
I have published everything in the article and the download zip file. There are a bunch of tutorials on building shopping cart. You can browse around and get code from different articles and integrate them together to build a fullfledged cart.
You really need to sanitize the incoming POST variables.
Youre code is too vulnervulable now , one could easily add a ‘ and get out of the variable.
Use filter_var to sanitize them.
https://www.php.net/manual/en/function.filter-var.php
Yes John, I agree with you. All the POST input variables should be sanitized. These were written in a hurry to showcase checkout flow alone. I have not invested time on the security side as it is not meant for production directly. But I agree with you that the input should be sanitized. I may have to add CSRF tokens and then XSS sanitization and lot more. But it will amount to building a full-fledged application. Hope you get the point.
Will it also be easy to have the order number and content mailed on checkout
Yes Ryan,
You can have a custom logic for the order number and an email on checkout.
Hi Vincy,
Thank you so much for your free shopping cart php code on this website, that’s very useful and helpful to me, as I am learning to use it. I think you have done a fantastic job. Thank you. Anyway, I got one question actually two questions to ask: in your ‘PHP Shopping Cart with PayPal Payment Gateway Integration’ code, why there is a hard coded memebe_id ( in your code is $member_id = 2;) and what it is for please? Your any response would be highly appreciated. Thank you in advance.
Hi Xianglin,
That is for the users to easily hook a member id from their own implementation. Its just a hooking point. You may or may not use it as per your convenience.
Really good work, you did great! Some awesome stuff and I highly recommend ALL of it… Thank you for that post. It has plenty of information to consider. And thank you.
Welcome Radha.
How we can link a wallet adress with this form??
Hi Muhammad,
Are you referring to Apple pay? If so, check this out https://phppot.com/php/stripe-apple-pay/
Hii, I am a beginner and I was trying to figure out where to input my EMAIL ID on which the above form will be sent after submission.
Please help. Thank You :)
Hi Ajay,
Hook it on order success and you can use this code to send email https://phppot.com/php/send-email-with-multiple-attachments-using-php/
Hi, this tutorial is great! How to add my email that items from chart will go to that email?
Hi Srdjan,
You can add it on order success and use https://phppot.com/php/send-email-with-multiple-attachments-using-php/ for sending email.
Nice setup, Appreciate. Can you help me on the below subject?
I have already customer login setup. But I wants to replace with your page. How can I do that?
Hi Najim,
Thank you for the appreciations. Sure it can be done. I would like to have a look at the setup of what you have got. Email me the details and we can take it forward from there.
Great demonstration! Thanks so much!
Welcome Shufkat.
How to email the cart data after Checkout?
Hi Ajay,
You can use PhpMailer component and send a SMTP email. Use a mail template for the body and send it out. Check this https://phppot.com/php/send-email-with-multiple-attachments-using-php/ and it has example code to send email.
Hi Vincy!
I have tried to send the cart data using the PhpMailer component but I am failed to do it. I did send the e-mail using the component alone but I couldn’t do it to send the cart. Do you have any tutorial on this?
Thank you in advance for your time.
Best Regards.
Hi Niczous,
Yes, I do have a tutorial, Check this https://phppot.com/php/sendmail-in-php-using-mail-smtp-with-phpmailer/ to know how to send email using PHPmailer.
very Good..
Thank you Nilesh.
This was so helpful for a project I was working on. Thank you very much!
Welcome Wilfred.
HI Vincy,
fantastic tutorial, this is what a shopping cart should be – simple, user friendly and light in size. I have one query, however – I am trying to add one more argument to the cartAction() function after productPrice, let call it productID (product-gallery.php). Consequently, I did the following:
– cart.js – add productID in the list of arguments as well as on the queryString of the ADD case
– Cart.php – add $productID = $_POST[‘productID’] in addToCart function and ‘productID’=>$productID in $cartItem array.
I thought that would be enough, however, each time I get an error – Undefined index: productID in Cart.php. What am I doing wront? Thanks in advance for your reply…..
Hi Dan,
Thank you. Possible error could be,
1) Check the field name if it is exactly productID
2) or you might have an array of products and have defined the same name for all the products as productID. When you are processing on action, you might have handled it as a single product, instead of an array of items.
Awesome job! between all the stuffs I found on the internet this is pretty well organized.
In which section we can include INSERT function to save cart to mysql ?
Thank you in advance!
I mean once the button checkout is clicked the data goes to mysql.
Mehdi,
You should see
Model/Cart.php
, it has all the logic that interacts with the MySql database. For your partaddToCart
is the function.Thank you Mehdi.
ajax/handle-cart-ep.php
this file takes of the action branching. There is a switch case “add”, that takes care of the add-to-cart part.super project
Thank you Liju Mathew.
nice
Thank you.
hello am student trying out Checkout Script with the html website i have done for my course work.
how should i past the script so that it can work
Hi Eyu,
I need more context to help you out. Explain me about your project and show me the code structure. May be, you can send an email to me with details.
Great Work
Thank you Spark.
good morning ma,
Your tutorials are simple and enriching thank you for making this information FREE.
My questions is: How can i implement the product gallery using form tag
for example
……..
i earnestly need guide on how to implement this.
i can handle the css part.
Thanks once more
Hi Kinze,
Thank you. I have implemented using AJAX. I have a function named
cartAction
, instead of that you should use form submit and redirect to the action url handle-cart-ep.php