Crear un carrito de compra Ajax con jQuery y PHP

El carrito de compra es una parte esencial de cualquier comercio electrónico que vende bienes y servicios durante todos los días en internet, pero la tasa de éxito de una tienda online se rige, en gran medida, dependiendo de la experiencia del usuario al finalizar la compra. Por lo tanto, un carrito de compra Ajax puede ser una gran función que ayude a tus visitantes a comprar sin esfuerza alguno, mejorando así, su experiencia a la hora de navegar por la web. En este tutorial vamos a ver cómo implementar un carrito de compra Ajax que, más tarde, podrás incluir en tus propios proyectos. ¿Estás preparado? Pues vamos a ello.

Crea la tabla en la base de datos MySQL

Antes de empezar, necesitamos crear una tabla en una base de datos MySQL, que almacerá toda la información relativa a los productos que vayas a vender, como el nombre del producto, el id, la descripción, el precio... Para este tutorial, he creado una tabla llamada products_list

CREATE TABLE IF NOT EXISTS 'products_list' (
'id' INT(11) NOT NULL,
  'product_name' VARCHAR(60) NOT NULL,
  'product_desc' text NOT NULL,
  'product_code' VARCHAR(60) NOT NULL,
  'product_image' VARCHAR(60) NOT NULL,
  'product_price' DECIMAL(10,2) NOT NULL
) AUTO_INCREMENT=1 ;

Puedes ejecutar el código anterior en tu PhpMyAdmin para crear la tabla products_list automáticamente, sin necesidad de ir creándola campo a campo.

Archivo de configuración

Vamos a empezar creando un archivo de configuración llamado config.inc.php en el que almacenaremos las credenciales de la base de datos y demás configuraciones que utilizaremos más tarde. En este mismo fichero, aprovecharemos para conectar con la base de datos y definir valores como el tipo de moneda, o los gastos de envío.

$db_username        = 'root'; //MySql database username
$db_password        = ''; //MySql dataabse password
$db_name            = 'test'; //MySql database name
$db_host            = 'localhost'; //MySql hostname or IP

$currency           = '₹ '; //currency symbol
$shipping_cost      = 1.50; //shipping cost
$taxes              = array( //List your Taxes percent here.
                            'VAT' => 12, 
                            'Service Tax' => 5,
                            'Other Tax' => 10
                            );

$mysqli_conn = new mysqli($db_host, $db_username, $db_password,$db_name); //connect to MySql
if ($mysqli_conn->connect_error) {//Output any connection error
    die('Error : ('. $mysqli_conn->connect_errno .') '. $mysqli_conn->connect_error);
}

Listado de productos

Podemos organizar nuestros productos como nos plazca. Para ello vamos a incluir un poco de CSS para darle un poco de diseño. Ya que vamos a utilizar sesiones, necesitamos incluir session_start(); en la parte superior de estos archivos, seguido de include( "config.inc.php") ;.

<?php
session_start(); //start session
include("config.inc.php"); //include config file
?>
<!DOCTYPE HTML>
<html>
<head><title>Ajax Shopping Cart</title></head>
<body>
<?php
//List products from database
$results = $mysqli_conn->query("SELECT product_name, product_desc, product_code, product_image, product_price FROM products_list");
//Display fetched records as you please
$products_list =  '<ul class="products-wrp">';
while($row = $results->fetch_assoc()) {
$products_list .= <<<EOT
<li>
<form class="form-item">
<h4>{$row["product_name"]}</h4>
<div><img src="images/{$row["product_image"]}"></div>
<div>Price : {$currency} {$row["product_price"]}<div>
<div class="item-box">
    <div>
    Color :
    <select name="product_color">
    <option value="Red">Red</option>
    <option value="Blue">Blue</option>
    <option value="Orange">Orange</option>
    </select>
    </div><div>
    Qty :
    <select name="product_qty">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    </select>
    </div><div>
    Size :
    <select name="product_size">
    <option value="M">M</option>
    <option value="XL">XL</option>
    <option value="XXL">XLL</option>
    </select>
    </div>
    
    <input name="product_code" type="hidden" value="{$row["product_code"]}">
    <button type="submit">Add to Cart</button>
</div>
</form>
</li>
EOT
;

}
$products_list .= '</ul></div>';
echo $products_list;
?>
</body>
</html>

Más tarde, utilizaremos jQuery para capturar valores de estos elementos, que luego utilizaremos para actualizar el carrito de compra.

Añadiendo la caja del carrito de compra

Una vez hemos creado la página de productos, podemos añadir la caja del carrito en donde queramos. Esta caja se actualizará automáticamente cuando el usuario añada/elimine elementos del listado de productos

<a href="#" class="cart-box" id="cart-info" title="View Cart">
<?php 
if(isset($_SESSION["products"])){
    echo count($_SESSION["products"]); 
}else{
    echo 0; 
}
?>
</a>
<div class="shopping-cart-box">
<a href="#" class="close-shopping-cart-box" >Close</a>
<h3>Your Shopping Cart</h3>
    <div id="shopping-cart-results">
    </div>
</div>

Recuerda darle un poco de estilo para que se vea atractivo.

Implementando Ajax con jQuery

Para actualizar el carrito de compra con los productos sin recargar la página, necesitamos enviar información al servidor utilizando una petición HTTP (Ajax). Dado que la mayoría de nosotros utilizamos jQuery en nuestros sitios web, vamos a ponerlo en práctica utilizando el método ajax de jQuery. El siguiente código realizará la petición Ajax al servidor y actualizará nuestro carrito de compra.

$(".form-item").submit(function(e){ //user clicks form submit button
    var form_data = $(this).serialize(); //prepare form data for Ajax post
    var button_content = $(this).find('button[type=submit]'); //get clicked button info
    button_content.html('Adding...'); //Loading button text //change button text 

    $.ajax({ //make ajax request to cart_process.php
        url: "cart_process.php",
        type: "POST",
        dataType:"json", //expect json value from server
        data: form_data
    }).done(function(data){ //on Ajax success
        $("#cart-info").html(data.items); //total items count fetch in cart-info element
        button_content.html('Add to Cart'); //reset button text to original text
        alert("Item added to Cart!"); //alert user
        if($(".shopping-cart-box").css("display") == "block"){ //if cart box is still visible
            $(".cart-box").trigger( "click" ); //trigger click to update the cart box.
        }
    })
    e.preventDefault();
});

Para eliminar un elemento del carrito, necesitamos ejecutar el siguiente código jQuery. Como puedes ver he utilizado el método $.getJSON, ya que esperamos que los datos devueltos por el servidor sean en formato JSON.

$("#shopping-cart-results").on('click', 'a.remove-item', function(e) {
    e.preventDefault(); 
    var pcode = $(this).attr("data-code"); //get product code
    $(this).parent().fadeOut(); //remove item element from box
    $.getJSON( "cart_process.php", {"remove_code":pcode} , function(data){ //get Item count from Server
        $("#cart-info").html(data.items); //update Item count in cart-info
        $(".cart-box").trigger( "click" ); //trigger click on cart-box to update the items list
    });
});

Si quieres que el usuario vea su carrito, simplemente muestra la caja del carrito utilizando el código de más abajo.

$( ".cart-box").click(function(e) { //when user clicks on cart box
    e.preventDefault(); 
    $(".shopping-cart-box").fadeIn(); //display cart box
    $("#shopping-cart-results").html('<img src="images/ajax-loader.gif">'); //show loading image
    $("#shopping-cart-results" ).load( "cart_process.php", {"load_cart":"1"}); //Make ajax request using jQuery Load() & update results
});

El siguiente código de jQuery cierra la caja del carrito cuando el cliente hace clic en el botón de cerrar.

$( ".close-shopping-cart-box").click(function(e){ //user click on cart box close link
    e.preventDefault(); 
    $(".shopping-cart-box").fadeOut(); //close cart-box
});

Proceso PHP

Nuestra página de producto está lista para actualizar el carrito, pero no hay un script de fondo para procesar los datos enviados a través de Ajax. Para eso es necesario crear un script PHP del lado del servidor, que procese y envie los datos relevantes otra vez a la página del cliente. Vamos a crear un fichero PHP llamado cart_process.php.

session_start(); //start session
include_once("config.inc.php"); //include config file
setlocale(LC_MONETARY,"en_US"); // US national format (see : http://php.net/money_format)
############# add products to session #########################
if(isset($_POST["product_code"]))
{
    foreach($_POST as $key => $value){
        $new_product[$key] = filter_var($value, FILTER_SANITIZE_STRING); //create a new product array 
    }
    
    //we need to get product name and price from database.
    $statement = $mysqli_conn->prepare("SELECT product_name, product_price FROM products_list WHERE product_code=? LIMIT 1");
    $statement->bind_param('s', $new_product['product_code']);
    $statement->execute();
    $statement->bind_result($product_name, $product_price);
    

    while($statement->fetch()){ 
        $new_product["product_name"] = $product_name; //fetch product name from database
        $new_product["product_price"] = $product_price;  //fetch product price from database
        
        if(isset($_SESSION["products"])){  //if session var already exist
            if(isset($_SESSION["products"][$new_product['product_code']])) //check item exist in products array
            {
                unset($_SESSION["products"][$new_product['product_code']]); //unset old item
            }           
        }
        
        $_SESSION["products"][$new_product['product_code']] = $new_product; //update products with new item array   
    }
    
    $total_items = count($_SESSION["products"]); //count total items
    die(json_encode(array('items'=>$total_items))); //output json 

}

################## list products in cart ###################
if(isset($_POST["load_cart"]) && $_POST["load_cart"]==1)
{

    if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){ //if we have session variable
        $cart_box = '<ul class="cart-products-loaded">';
        $total = 0;
        foreach($_SESSION["products"] as $product){ //loop though items and prepare html content
            
            //set variables to use them in HTML content below
            $product_name = $product["product_name"]; 
            $product_price = $product["product_price"];
            $product_code = $product["product_code"];
            $product_qty = $product["product_qty"];
            $product_color = $product["product_color"];
            $product_size = $product["product_size"];
            
            $cart_box .=  "<li> $product_name (Qty : $product_qty | $product_color  | $product_size ) &mdash; $currency ".sprintf("%01.2f", ($product_price * $product_qty)). " <a href="#" class="remove-item" data-code="$product_code">&times;</a></li>";
            $subtotal = ($product_price * $product_qty);
            $total = ($total + $subtotal);
        }
        $cart_box .= "</ul>";
        $cart_box .= '<div class="cart-products-total">Total : '.$currency.sprintf("%01.2f",$total).' <u><a href="view_cart.php" title="Review Cart and Check-Out">Check-out</a></u></div>';
        die($cart_box); //exit and output content
    }else{
        die("Your Cart is empty"); //we have empty cart
    }
}

################# remove item from shopping cart ################
if(isset($_GET["remove_code"]) && isset($_SESSION["products"]))
{
    $product_code   = filter_var($_GET["remove_code"], FILTER_SANITIZE_STRING); //get the product code to remove

    if(isset($_SESSION["products"][$product_code]))
    {
        unset($_SESSION["products"][$product_code]);
    }
    
    $total_items = count($_SESSION["products"]);
    die(json_encode(array('items'=>$total_items)));
}

Resumen del pedido

Finalmente vamos a crear una página de resumen del pedido para mostrar el coste total incluyendo impuestos. Esta es la página que los usuarios visitarán para saber exáctamente cuánto tendrán que pagar por su pedido.

if(isset($_SESSION["products"]) && count($_SESSION["products"])>0){
    $total          = 0;
    $list_tax       = '';
    $cart_box       = '<ul class="view-cart">';

    foreach($_SESSION["products"] as $product){ //Print each item, quantity and price.
        $product_name = $product["product_name"];
        $product_qty = $product["product_qty"];
        $product_price = $product["product_price"];
        $product_code = $product["product_code"];
        $product_color = $product["product_color"];
        $product_size = $product["product_size"];
        
        $item_price     = sprintf("%01.2f",($product_price * $product_qty));  // price x qty = total item price
        
        $cart_box       .=  "<li> $product_code &ndash;  $product_name (Qty : $product_qty | $product_color | $product_size) <span> $currency$item_price </span></li>";
        
        $subtotal       = ($product_price * $product_qty); //Multiply item quantity * price
        $total          = ($total + $subtotal); //Add up to total price
    }
    
    $grand_total = $total + $shipping_cost; //grand total
    
    foreach($taxes as $key => $value){ //list and calculate all taxes in array
            $tax_amount     = round($total * ($value / 100));
            $tax_item[$key] = $tax_amount;
            $grand_total    = $grand_total + $tax_amount; 
    }
    
    foreach($tax_item as $key => $value){ //taxes List
        $list_tax .= $key. ' '. $currency. sprintf("%01.2f", $value).'<br />';
    }
    
    $shipping_cost = ($shipping_cost)?'Shipping Cost : '.$currency. sprintf("%01.2f", $shipping_cost).'<br />':'';
    
    //Print Shipping, VAT and Total
    $cart_box .= "<li class="view-cart-total">$shipping_cost  $list_tax <hr>Payable Amount : $currency ".sprintf("%01.2f", $grand_total)."</li>";
    $cart_box .= "</ul>";
    
    echo $cart_box;
}else{
    echo "Your Cart is empty";
}

Fuente: sanwebe.com

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP