Adding discount code system to cart

Hello all,
I have been working on a simple code to implement a discount code to my website for weeks and have been experiencing error A non-numeric value encountered when calculating the maths.
The cart system is working, however when I added the discount code addition the sites works but when entering a code am having problems.
My aim is to achieve
$discount = $Discount ($row[Discount]) / 100
$discountamt = $cartTotal * $discount
$grossTotal = $$cartTotal - $discountamt
The problem is with the $cartTotal variable.
The $ cartTotal works on its own and is made up by
$pricetotal = $List_Price * (int)$each_item[‘quantity’];// removed int form $each_item[quantity]
$cartTotal = $pricetotal + $cartTotal;// removed int form $cartTotal
$itemsTotal = count($_SESSION[“cart_array”]);

There is a difference between
$$cartTotal and $cartTotal

You probably want the later, not the former.

Thank you very much for your reply. When posting the code I mage the mistake with double $ but the code uses a sing $ as you have mentioned.
The $cartTotal is made up of $pricetotal + $cartTotal which works well, however the problems only occurs when $discountcode = “”;
$discountamt = 0;
$grossTotal = 0;
$discount = 0;

//$number = $cartTotal;
if (isset($_POST["promocode"])){  
 $mycode = $_POST['promocode'];
 
 
 		$sql4 = mysqli_query($db, "SELECT * FROM promo_codes WHERE promo_codes.activate='1'");
	$productCount = mysqli_num_rows($sql4); // count the output amount
		if ($productCount > 0){
				while($row = mysqli_fetch_array($sql4)){ 
				 $id = $row["id"];			
				 $code = $row["code"];
				 $Discount = $row["Discount"];
				 $activate = $row["activate"];					

					if ($mycode == $code && $activate == 1){
						
							/////// notes to myself  ///////////
							// Subtotal = $cartTotal
							// $discount = $Discount ($row[Discount]) / 100
							// $discountamt = $cartTotal * $discount
							// $grossTotal = $cartTotal - $discountamt
					
							//working section 
							$Discount = $row["Discount"] /100;
							setlocale(LC_MONETARY, 'en_GB');
    						$Discount =  utf8_encode(money_format('%n', $Discount));
						echo $Discount;
							
							
							$discountamt = $cartTotal * $Discount;							
							setlocale(LC_MONETARY,"en_GB");
							$discountamt = utf8_encode(money_format('%n' , $discountamt));//%.2n							
						echo $discountamt;
						
							
							$grossTotal = $cartTotal - $discountamt;
							setlocale(LC_MONETARY,"en_GB");
							$grossTotal = utf8_encode(money_format('%n' , $grossTotal));//%.2
					echo $grossTotal;
							
							
						
							{
												
								}
			}// while					
		}// productcount
	} // if sql4
}// if isset

The $cartTotal is displaying the warning as a non numeric value. Individually the $Discount is working, The $cartTotal is working but when multiplying or adding/subtracting is causeing the error.
Please help.

So what are these values when that occurs?

$pricetotal is the cost of the item, in pounds and i have tried the value as a float and as a decimal in the Mysql database. The $cartTotal adds all the items in the cart and is also in pounds. I have tried (int) and (float) and the error still occurs. So as an example the item price is £9.99 with one item in the basket the $cartTotal id £9.99. I hope that was the question.

Can I attach my cart.php file for you to get a better picture?

I need more info.

I need to know the inputs and outputs as well as see the code it follows through on how this gets to the error state.

What value does $cartTotal have when it holds a non numeric value?

I can not see the non numeric value. I will attach the file for your attention and your help will be appreciated.
I have never used any help sites before and this is the first time, so please forgive me if there are any typos etc.temp home page as I am still developing the site
I can not see where to attach the file, so please advice.

You can add anything into the cart and use a code like

test

in the “enter a discount code area”

copy it and paste it in.

It is saying new user can only put 2 links and one picture in the posts.

include "storeadmin/connect_to_mysql.php";  
$cartOutput = "";
$cartOutput2 = "";
$message1 = "";
$message2 = "";
$cartTotal = 0;
$pp_checkout_btn = '';
$product_id_array = '';
$itemsTotal = '';
//$discountamt = 0;

if (!isset($_SESSION["cart_array"]) || count($_SESSION["cart_array"]) < 1) {
	// when cart empty display just top bar and bar your cart is empty.
    
	$cartOutput2 .= '<div id="shoppingcrtb" style=""><p>Shopping Basket</p></div>    	
					<div class="cartemptybarb" style=""><h9>You have no items in your shopping basket</h9></div>
  					<!-- <div id="pageContent"> -->
  					<div style="margin:0 0 0 0px; text-align:left;"> 
  						<br /> 
					<div id="contshopping">
					<div class="contshoppingbar"><a href="http://www.magic-makeup.co.uk/indexN.php"><h9>Continue shopping</h9></a></div>					
					</div>	
  					<div id="shoppingcartmenu" style="display:none;"> 
  					<div id="shoppingcrtc" style=""><p>Shopping Basket</p></div>
					<div id="cartheading">
					<div class="cartproduct"><p>Product</p></div>
					<div class="cartunitprice"><p>Unit Price</p></div>	
					<div class="cartquantity"><p>Quantity</p></div>	   
					<div class="carttotal"><p>Total</p></div>
				   	<div class="cartremove"><p>Remove</p></div>	   
					</div>
					<div id="cartproduct">
				   	<div class="product">product</div>
				   	<div class="productdesc">productdesc</div>
					<div class="unitprice">unitprice</div>
					<div class="quantity">quantity</div>
					<div class="total">total</div>
					<div class="remove">remove</div> 
					</div>  ';
   
$message1 .= '<a href="cart.php?cmd=emptycart" style="display:none";>Click Here to Empty Your Shopping Cart</a>';
} else {
	// Start PayPal Checkout Button
	//$pp_checkout_btn .= '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
	// input type="hidden" name="cmd" value="_xclick"
	//input type="hidden" name="business" value="[email protected]">';
	// input type="hidden" name="business" value="R8X2EVCQW9S82">';
	$pp_checkout_btn .= '<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
   <input type="hidden" name="cmd" value="_cart">
   <input type="hidden" name="upload" value="1">
   <input type="hidden" name="hosted_button_id" value="APJX39EMDU9VA">
   <input type="hidden" name="business" value="[email protected]">';
	// Start the For Each loop
	
	$i = 0; 
    foreach ($_SESSION["cart_array"] as $each_item) { 
		$item_id = $each_item['item_id'];
		$quantity = (int)$each_item['quantity'];
		$sql = mysqli_query($db, "SELECT * FROM products WHERE id='$item_id' LIMIT 1");
		while ($row = mysqli_fetch_array($sql)) {
			$Product_Name = $row["Product_Name"];
			$product_type = $row["product_type"];
			$List_Price = $row["List_Price"];
			$colour = $row["colour"];
			$top_message = $row["top_message"];
		}
		
		$pricetotal = $List_Price * (int)$each_item['quantity'];// removed int form $each_item[quantity]
		$cartTotal = $pricetotal + $cartTotal;// removed int form $cartTotal
		$itemsTotal = count($_SESSION["cart_array"]);
		 
		setlocale(LC_MONETARY, "en_GB");
        $List_Price = utf8_encode(money_format('%n', $List_Price));
		setlocale(LC_MONETARY, "en_GB");
        $pricetotal = utf8_encode(money_format('%n', $pricetotal));
		
			//Dynamic Checkout Btn Assembly
		$x = $i + 1;
		$pp_checkout_btn .= '<input type="hidden" name="item_name_' . $x . '" value="' . $Product_Name . '">
        <input type="hidden" name="amount_' . $x . '" value="' . $List_Price . '">		 
		<input type="hidden" name="quantity_' . $x . '" value="' . $each_item['quantity'] . '">';
		// Create the product array variable
		$product_id_array .= "$item_id-".$each_item['quantity'].","; 
		
		// ------------------ Dynamic table row assembly when something in the cart -------------------------- //		
			
		$cartOutput .= '<div id="cartproduct"> ';
		$cartOutput .= '<div class="product"><a href="indexN.php?id=' . $item_id . '"></a><br /><img src="shop/images/' . $item_id . '.jpg" alt="' . $Product_Name. '"/></div>';
		$cartOutput .= '<div class="productdesc">' .$product_type . ' - ' . $Product_Name . '</div>';
	//	$cartOutput .= '<div class="unitprice">&pound;' . $List_Price . '</div>';
		$cartOutput .= '<div class="unitprice">' . $List_Price . '</div>';
		$cartOutput .= '<div class="quantity_minus"><a href="cart.php?remove='. $item_id.'"><p>-</p></a></div>';
		$cartOutput .= '<div class="quantity"><p> '.$each_item['quantity'].'</p></div>';
		$cartOutput .= '<div class="quantity_plus"><a  href="cart.php?add='. $item_id.'"><p>+</p></a></div>';
		$cartOutput .= '<div class="total">' . $pricetotal . '</div>';
		$cartOutput .= '<div class="remove"></div><form action="cart.php" method="post"><input class="deleteBtn" name="deleteBtn' . $item_id . '" type="submit" value="X" /><input name="index_to_remove" type="hidden" value="' . $i . '" /></form>';
		$cartOutput .='</div> ';
		$i++; 
		} 
	setlocale(LC_MONETARY,"en_GB"); // causing problems
    $cartTotal = utf8_encode(money_format('%n',$cartTotal)); // causing problems	
	$cartTotal = "<div style='font-size:18px; color:#666; margin-top:12px;' align='right' class='carttotal' >Sub Total : ". $cartTotal ."</div>"; // had removed it
	
//	$discountamt ="<div style='font-size:18px; color:#666; margin-top:12px;' align='right' float:'left'>Discount : " .$discountamt."</div>";
//<div style='font-size:18px; color:#666; margin-top:12px;' align='right' class="carttotal">
   
  
  // </div>

	
    // Finish the Paypal Checkout Btn original button x-click-but01.gif 
	$pp_checkout_btn .= '<input type="hidden" name="custom" value="' . $product_id_array . '">
	<input type="hidden" name="notify_url" value="http://www.magic-makeup.co.uk/storescripts/my_ipn.php">
	<input type="hidden" name="return" value="http://www.magic-makeup.co.uk/checkout_complete.php">
	<input type="hidden" name="rm" value="2">
	<input type="hidden" name="cbt" value="Return to The Store">
	<input type="hidden" name="cancel_return" value="http://www.magic-makeup.co.uk/paypal_cancel.php">
	<input type="hidden" name="lc" value="GB">
	<input type="hidden" name="currency_code" value="GBP">
	<input type="image" src="http://www.magic-makeup.co.uk/images/checkout_with_paypal.gif" name="submit" alt="Make payments with PayPal - its fast, free and secure!">
	</form>';
}

////////////////////////////////
/*  
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="APJX39EMDU9VA">
<input type="image" src="http://www.magic-makeup.co.uk/images/paypal-checkout.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online!">
<img alt="" border="0" src='/uploads/default/original/2X/5/56d45f8a17f5078a20af9962c992ca4678450765.gif' width="1" height="1">
</form>


 */

/////////////////////////
//
?>
<?php
 /////////////////////////////// Discount code ////////////////////////////////////////////// 
// include "storeadmin/connect_to_mysql.php"; 
 $discountcode = ""; 
 $discountamt = 0;
 $grossTotal = 0;
 $discount = 0;


//$number = $cartTotal;
if (isset($_POST["promocode"])){  
 $mycode = $_POST['promocode'];
 
 
 		$sql4 = mysqli_query($db, "SELECT * FROM promo_codes WHERE promo_codes.activate='1'");
	$productCount = mysqli_num_rows($sql4); // count the output amount
		if ($productCount > 0){
				while($row = mysqli_fetch_array($sql4)){ 
				 $id = $row["id"];			
				 $code = $row["code"];
				 $Discount = $row["Discount"];
				 $activate = $row["activate"];					

					if ($mycode == $code && $activate == 1){
						
							/////// notes to myself  ///////////
							// Subtotal = $cartTotal
							// $discount = $Discount ($row[Discount]) / 100
							// $discountamt = $cartTotal * $discount
							// $grossTotal = $cartTotal - $discountamt
					
							//working section 
							$Discount = $row["Discount"] /100;
							setlocale(LC_MONETARY, 'en_GB');
    						$Discount =  utf8_encode(money_format('%n', $Discount));
						echo $Discount;
							
							
							$discountamt = $cartTotal * $Discount;							
							setlocale(LC_MONETARY,"en_GB");
							$discountamt = utf8_encode(money_format('%n' , $discountamt));//%.2n							
						echo $discountamt;
						
							
							$grossTotal = $cartTotal - $discountamt;
							setlocale(LC_MONETARY,"en_GB");
							$grossTotal = utf8_encode(money_format('%n' , $grossTotal));//%.2
					echo $grossTotal;
							
							
						
							{
												
								}
			}// while					
		}// productcount
	} // if sql4
}// if isset

?>

That worked as a partial paste.

I have sent you the initial cart page with the outputs and the discount code. The PayPal checkout works without the discount code and i have not got to the testing stage to check if the discount is added to paypal.

make these changes and test it,

// $cartTotal = utf8_encode(money_format('%n',$cartTotal)); // causing problems	
	$cartTotal = "<div style='font-size:18px; color:#666; margin-top:12px;' align='right' class='carttotal' >Sub Total : ". $cartTotal ."</div>"; // had removed it

If it is in non numeric format, the money_format won’t work. You need to see what it is before you do that formatting.

I removed the money format before and the error still remained. The £ sign disappeared as expected.
The figures still remained as 10.99 and the error still persisted.

I have been playing with the money formats for the last 2 weeks and different errors occurred like parameter 2 expect to a float, string is given.

At some point a string is being introduced into that variable. You may need to print the value in the loop to see when it changes over.

The errors are because you are trying to use formatted numbers in math expressions.

Number/money formatting is for the humans reading the final output. The format characters being added result in non-numbers that are treated as zeros and cause the php errors.

You should do the math on the raw numerical values and only format the numbers when you output the final values on a web page.

Next, the SELECT query to find the discount amount from the discount code should NOT query for all the rows and loop over them. Add AND code = ? (using a prepared query) expression to the WHERE clause and use the discount amount if one is found. You will need to learn how to use a prepared query to do this, and it will be much simpler if you switch to the PDO database extension.

1 Like

Hi

Thank you for your help. The problem was as phdr suggested, the calculations were on formatted numbers and I have managed to get the calculations working. Unfortunately I can not get $cartTotal to format with the money format to display the £ symbol. Any help would be appreciated and thank you once again.

I was unable to reply yesterday as the phphelp group would not let me post as i had exceeded my limit as a new user.

You would need to post the current code, from the point where $cartTotal is being produced through to the point where it is being displayed.

Some points about the previously posted code -

  1. If you change the cart definition, so that the item_id is the cart’s array index, all the code dealing with the cart, add, update, delete, and display, will be simpler.
  2. The display cart code should NOT run the SELECT query inside of a loop. You should get all the item ids from the cart at one time, use one query to get all the item details, then loop over the result from this one query to display the contents of the cart.
  3. If you did have a good reason to run a query inside of a loop, you would use a prepared query, prepared before the start of the loop, then just supply each set of input data value(s) when the query gets executed inside of the loop.
  4. Since the code to display the cart is using the item_id(s) in the query, this could be open to sql injection, which would allow anyone to access any of your database tables, such as getting all your user’s email addresses and hashed passwords. You need to use a prepared query anytime you supply external/unknown data values to a query.
  5. You are using a loop to retrieve a single row from a query. Any time you have a query that will at most match one row, just fetch the data without using a loop.
  6. You are repeating the setlocale() statement. This should be done once, in a common ‘initialization’ section of code, near that top of your file.
  7. You are copying variables to other variables without any purpose. Just use the original variables.

The above suggestions will greatly simplify the code and add security to the sql query(ies).

Sponsor our Newsletter | Privacy Policy | Terms of Service