Jump to content

[SOLVED] Cart and paypal not adding up


Recommended Posts

Hi
Ive found a slight problem with the discount part of prestashop and using paypal. I'm using presta 1.2.5 and paypal to take payment but the problem i have is this.
I sell an item for £15.99 each, with discounts set to 10% off for ordering 5 or more, postage is 99p, so a customer orders 5 items £15.99 x 5 = £79.95 - 10% = £71.955 + 0.99p = £72.945 which presta rounds up to £72.95.
the problem comes when this is sent to paypal because it works it out as,
5 items £15.99 - 10% = £14.39 x 5 = £71.95 + 0.99p = £72.94 which doesn't need rounding.

The 1p difference causes a payment error to be marked in presta back office.

Does anyone know how to sot this out?
Any help appreciated.
Thanks
Mike

Link to comment
Share on other sites

Encountering same exact issue. It's not something taking place on the Paypal end. I've taken a look at the variables being passed to Paypal, in the HTML, and they're slightly off, from what the price(s) should be. Rounding error, somewhere?

Link to comment
Share on other sites

  • 1 month later...
Is there any news of a fix on this. It would be nice to have the discounts working correctly.


I have fixed this issue for a store using PS 1.1.0.5 in the past, try making the following change and let me know if it works for you (I don't remember what the prices were set, so I can't reproduce the error locally)

In /classes/Cart.php (around line # 570) you will see the following code

foreach ($products AS $product)
{
   $price = floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity']));
   $total_price = $price * intval($product['quantity']);
   $order_total += $total_price;
}



Comment out the $price = ... line (add // in front of it) and add the new line below it.

foreach ($products AS $product)
{
   //$price = floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity']));
   $price = round(floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity'])),2);
   $total_price = $price * intval($product['quantity']);
   $order_total += $total_price;
}



This will round the price of each product (with taxes) to 2 decimal points and should resolve this issue.

If it doesn't make a different just remove the new line, and un-comment the old one.

Let me know how it goes.

Link to comment
Share on other sites

  • 2 weeks later...
Is there any news of a fix on this. It would be nice to have the discounts working correctly.


I have fixed this issue for a store using PS 1.1.0.5 in the past, try making the following change and let me know if it works for you (I don't remember what the prices were set, so I can't reproduce the error locally)

In /classes/Cart.php (around line # 570) you will see the following code

foreach ($products AS $product)
{
   $price = floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity']));
   $total_price = $price * intval($product['quantity']);
   $order_total += $total_price;
}



Comment out the $price = ... line (add // in front of it) and add the new line below it.

foreach ($products AS $product)
{
   //$price = floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity']));
   $price = round(floatval(Product::getPriceStatic(intval($product['id_product']), $withTaxes, intval($product['id_product_attribute']), 6, NULL, false, true, $product['quantity'])),2);
   $total_price = $price * intval($product['quantity']);
   $order_total += $total_price;
}



This will round the price of each product (with taxes) to 2 decimal points and should resolve this issue.

If it doesn't make a different just remove the new line, and un-comment the old one.

Let me know how it goes.


Thank you very much, so far the code is working we have only tested it a few times and have a lot more testing to run but so far it looks like you saved our bacon :D

-----------------------------------------
EDIT

after some more testing we are still unable to make it fail, so it looks like on prestashop 1.2.4 and 1.2.5 this works only tested it on two versions though
Link to comment
Share on other sites

  • 3 weeks later...
  • 2 weeks later...
Oh ok.
I was hoping that this solution will solve the problem with the price calculation.
I was wrong. Sorry for posting this here...


i believe 1.2.4 has a special bug, which my changes wont fix, there is a topoc about it somewhere, i think you may need to upgrade to 1.2.5
Link to comment
Share on other sites

i believe 1.2.4 has a special bug, which my changes wont fix, there is a topoc about it somewhere, i think you may need to upgrade to 1.2.5


I see that the 1.2.5 has only 3 security fixes.
[-] Security : XSS vulnerability on the contact form fixed
[-] Security : XSS vulnerability on the sendtoafriend module fixed
[-] Security : Pathtransversal on the Back Office fixed

Nothing about the price calculation.

I'm lost ... and a little bit disappointed .
I will go on searching how to solve this. If I find I will post the solution.

Thanks.
Link to comment
Share on other sites

While the code change above does indeed resolve the difference between PayPal and the Backoffice cart, it doesn't entirely resolve the issue. The totals for the discounted items in the cart summary page or the ajax cart will still be incorrect slightly.

If for example you add an item that has a value of $0.50 to the cart with a quantity of 11 and which has a discount of 5% for 10 or more items, the unit price will be reflected as $0.48 in the cart summary, but the prestashop underlying calculations will be done using $0.475. As a result the cart will have one item with a QTY of 11 with a unit cost $0.48 for a total of $5.23, which is really a rounded value of (11 * 0.475 = 5.225). In reality this value should be 0.48 * 11 = 5.28.

While the code change suggested above overcomes this issue with respect to the totals, the individual item totals are not correct, and an astute shopper may raise this as a concern.

Instead of the above suggested change I found that the following will resolve both the total and individual item calculations in both the cart summary and ajax cart.

File: classes/Product.php
Function: getPriceStatic (approx line 1229)
Immediately BEFORE the last line of the function which is:

return self::$_prices[$cacheId];



Insert:

self::$_prices[$cacheId] = round(self::$_prices[$cacheId],2);



As you can see this statically rounds to 2 decimal places. I was tempted to use the $decimal variable to specify the number of decimal places for rounding, but this would require additional code changes in other modules to ensure I called this module with the correct decimal setting. Someone with a more holistic understanding of prestashop will probably come with a more permanent solution, but since none of my prices are greater that 2 decimals it has not created any issues for me.

MS

Link to comment
Share on other sites

So this part of the function then looks like this?

        // Group reduction
       if ($id_customer)
           $price *= ((100 - Group::getReduction($id_customer))/100);

       self::$_prices[$cacheId] = ($divisor AND $divisor != 'NULL') ? number_format($price/$divisor, $decimals, '.', '') : number_format($price, $decimals, '.', '');
       self::$_prices[$cacheId] = round(self::$_prices[$cacheId],2); 
       return self::$_prices[$cacheId];

Link to comment
Share on other sites

I still seem to get the problem..

I have applied a 30% discount to my profile and when I add a discounted item to my cart with the above code change, the orders are still 1c out.
But it seems to vary. If I add 2 discounted items to my cart sometimes it is the same in paypal and presta, but other times it is 1c out.

This seems like a pretty fundamental flaw with the paypal module?
I've already had a customer try and order twice out of confusion after getting a payment error..

I did notice though that that code was applied in the 'Group Reduction' section.. should I be adding it anywhere else aswell?

Link to comment
Share on other sites

I notice there are some changes in the Classes/Product.php file with the latest release in these areas.
Is it possible to simply replace my product.php file with the new one or can anyone suggest how to apply the changes from the new release to the v1.2.5 presta release to fix this rounding problem?

Any help greatly appreciated.

Thanks

Link to comment
Share on other sites

Had same problem more than a month ago, spent very long time on building my shop and still can't go live cause of this rounding PayPal error. Very dissapointing that PS is running forward in developments when such a basic feture as payment is not functioning properly. I hope for a mirical :-)

Link to comment
Share on other sites

  • 2 months later...
  • 2 weeks later...

        // Group reduction
       if ($id_customer)
           $price *= ((100 - Group::getReduction($id_customer))/100);

       self::$_prices[$cacheId] = ($divisor AND $divisor != 'NULL') ? number_format($price/$divisor, $decimals, '.', '') : number_format($price, $decimals, '.', '');
       self::$_prices[$cacheId] = round(self::$_prices[$cacheId],2); 
       return self::$_prices[$cacheId];




When I make this change, my whole store is crashing.
Every page now shows a white page with nothing.
I use PS 1.2.5.

Anyone has an idea ?
Link to comment
Share on other sites

There must be a PHP error. You should check your PHP errorlog, or edit config/config.inc.php and temporarily change 'display_errors' from 'off' to 'on', so that you get an error message instead of a blank page. Post the error message here.

Link to comment
Share on other sites

It looks like the round function doesn't like you using the self keyword. I suggest that you try the following code instead:

self::$_prices[$cacheId] = round($price, 2);
return self::$_prices[$cacheId];

Link to comment
Share on other sites

Yea. This code works :

self::$_prices[$cacheId] = $price;
return round($price, 2); 



But unfortunately, it doesn't solve my initial problem.
Single item price is rounded and multiplied correctly, but total cart price still has a 1 cent difference beetween Paypal and PS.

Link to comment
Share on other sites

  • 7 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...