One Page Checkout Script Free with Example Template in PHP

by Vincy. Last modified on September 27th, 2022.

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.

One Page Checkout Script Free with Example Template in PHP

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.

What is inside?

  1. What is one page checkout?
  2. About this example
  3. One page checkout example demo
  4. PHP checkout example files
  5. Creating one page checkout template
  6. jQuery script to handle cart events and prepare AJAX request
  7. Process checkout in PHP
  8. Enhancements
  9. One page template example output

What is one page checkout?

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.

Checkout Cart Abandonment Stats

Source: Baymard Institute

About this example

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.

One page checkout example demo

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.

  • Add-to-cart
  • Edit cart item quantity
  • Remove a single item
  • Empty cart
  • Checkout

You can try all the above with this demo.

View Demo

PHP checkout example files

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.

One Page Checkout Example Files

Creating one page checkout template

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>

Product gallery with Add-to-Cart button

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>

Shopping cart items with edit delete

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>

jQuery script to handle cart events and prepare AJAX request

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);
		}
	});
}

Process checkout in PHP

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;
    }
}

Enhancements

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.

One page template example output

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.

One Page Checkout Example Output

View DemoDownload

Comments to “One Page Checkout Script Free with Example Template in PHP”

  • Zafer says:

    Hello,
    It was a successful work, thank you.
    But the basket can not be -1
    How do I integrate this project in Codeigniter?

    • Vincy says:

      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.

  • Esteban says:

    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.

    • Vincy says:

      Hi Esteban,

      You need to customize the cart logic to suit this.

    • SWAPNIL AKOLKAR says:

      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.

  • rino says:

    hi, how can I add “max product in magazine” ? and sold-out?

    • Vincy says:

      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.

  • Aubrey says:

    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

    • Vincy says:

      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.

  • John says:

    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

    • Vincy says:

      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.

  • ryan says:

    Will it also be easy to have the order number and content mailed on checkout

  • Xianglin Li says:

    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.

    • Vincy says:

      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.

  • Radha says:

    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.

  • Ajay Singh says:

    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 :)

  • Srdjan says:

    Hi, this tutorial is great! How to add my email that items from chart will go to that email?

  • Najim says:

    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?

    • Vincy says:

      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.

  • Shufkat says:

    Great demonstration! Thanks so much!

  • Ajay Singh says:

    How to email the cart data after Checkout?

  • Nilesh says:

    very Good..

Leave a Reply to Esteban Cancel reply

Your email address will not be published. Required fields are marked *

↑ Back to Top

Share this page