Jump to content
moneytree

checkout_confirmation calculation incorrect for paypal

Recommended Posts

When I check out using PayPal, and have a discount applied, checkout_confirmation incorrectly calculates the "amount" output to PayPal.

 

$1.00 Price

$1.00 Sub Total

$2.25 Shipping

-$2.25 Shipping Discount Applied

 

$1.00 Total

 

I am giving a FREE SHIPPING ON FIRST ORDER incentive.

 

checkout_confirmation.php calculates this amount as -$1.25 as follows;

<input name="cmd" value="_xclick" type="hidden"><input name="business" value="me@mystore.com" type="hidden">

<input name="item_name" value="MYSTORE" type="hidden"><input name="amount" value="-1.25" type="hidden">

<input name="shipping" value="2.25" type="hidden"><input name="currency_code" value="USD" type="hidden">

<input name="return" value="http://www.mystore.com/catalog/checkout_process.php" type="hidden">

<input name="cancel_return" value="http://www.mystore.com/catalog/checkout_payment.php" type="hidden">

<input src="includes/languages/english/images/buttons/button_confirm_order.gif" alt="Confirm Order" title=" Confirm Order " border="0" type="image">

 

When clicking through to PayPal, PayPal doesn't like this -$1.25 and throws the following message;

"The link you have used to enter the PayPal system contains an incorrectly formatted item amount."

 

As long as the product purchased price is greater than the discount, everything works great, but when the discount is greater than the product price, the above error appears.

 

Where and how is the "amount" value calculated and how should I change it to output...

<input name="cmd" value="_xclick" type="hidden"><input name="business" value="me@mystore.com" type="hidden">

<input name="item_name" value="MYSTORE" type="hidden"><input name="amount" value="1.00" type="hidden">

<input name="shipping" value="0" type="hidden"><input name="currency_code" value="USD" type="hidden">

<input name="return" value="http://www.mystore.com/catalog/checkout_process.php" type="hidden">

<input name="cancel_return" value="http://www.mystore.com/catalog/checkout_payment.php" type="hidden">

<input src="includes/languages/english/images/buttons/button_confirm_order.gif" alt="Confirm Order" title=" Confirm Order " border="0" type="image">

 

OSC 2.2 RC1

Discount Coupon Codes 3.3

 

Thanks for any and all help!

Share this post


Link to post
Share on other sites

Hi

 

Not to be trying to revive a topic, but I've been searching on Google for a solution to this problem also and haven't found one - only this post contains the problem that I'm experiencing and I'm hoping someone will be able to find a resolution.

 

I'm currently running osCommerce Bootstrap 3 in 2.3.4 Responsive Master

http://forums.oscommerce.com/topic/396152-bootstrap-3-in-234-responsive-from-the-get-go/

 

I am currently trying to look for a working discount code and gift voucher model, but haven't found one (2.3.3.4 was the closest I found but it hasn't been formatted for BS codes yet - I'm not advanced enough to work out every difference required)

So in the mean time, I'm using Discount Codes 4.2.1 BS

http://addons.oscommerce.com/info/9460/v,23

 

I'm using PayPal to process my transactions - at first, I was using PayPal Express - but for some odd reason, it would never include the shipping. Going into my PayPal account, I've set a profile for shipping, still it charges for the total cost of items. I tried ticking that override profile issue, same thing. I read somewhere to click on Clear Settings and leave it all blank, same issue.

So I gave up on it and tried PayPal Standard.

 

Everything works fine, except when the discount is somehow greater than the total cost of items. Of course, realistically, this probably won't happen for any order, but whilst I was testing the module and codes, and to make sure PayPal was receiving transactions, that's when I encountered the problem below.

 

Again, this probably won't affect me, but I still would like to resolve this problem as a precaution, just in case.

 

Anyone ever found a solution to this problem yet?

My store front is http://davidtran.com.au/shop just so you know and can see for yourself.

 

Thanks

David

Share this post


Link to post
Share on other sites

@@davidtranlds

 

Discount Codes 4.2.1 BS works for Paypal. 

 

Paypal has an easy way to offer gift certificates.

https://www.paypal.com/cgi-bin/webscr?cmd=xpt/Merchant/merchant/GCIntro-outside

 

For the problem mentioned below, you can try leaving out the $ symbol. 

When clicking through to PayPal, PayPal doesn't like this -$1.25 and throws the following message;

"The link you have used to enter the PayPal system contains an incorrectly formatted item amount."

Share this post


Link to post
Share on other sites

@@ecommunlimited

I'm currently using Discount Codes 4.2.1 BS and it's this module that's giving the problem.

I've tested live by placing an order for regular items, and the payment and order does go through, so there's no issue really.

However, when using a test product that only costs $1, shipping of $15, and the discount is free shipping, thus there's a -$15 for the discount, that's when I receive the error.

Again, realistically, a normal order goes through, but in the case of an emergency where I have a very cheap item, or the discount is somehow too much, and I get an error like this on a real order, that's what I want to ready for - thus I want to correct this error.

 

So in correcting it, you mention to remove the $ symbol, so how do I do that? In the language files?

 

Here's a snippet of the code from ot_discount.php, which is where I think all the calculations get done (but I could be wrong). Maybe someone's able to deduce hopw the calculations are done to correct the issue?

 


if ( (empty($check['newsletter']) || $newsletter == 1) && (empty($check['order_number']) || $orders == $check['order_number']) ) {
              if (in_array($customer_id, $customers)) {
                if (!empty($check['products_id']) || !empty($check['categories_id']) || !empty($check['manufacturers_id'])) {
 
                  $products = array();
                  if (!empty($check['products_id'])) {
                    $products = explode(',', $check['products_id']);
                  } elseif (!empty($check['categories_id'])) {
                    $product_query = tep_db_query("select products_id from products_to_categories where categories_id in (" . $check['categories_id'] . ")" . (empty($check['excluded_products_id']) ? '' : " and products_id not in (" . $check['excluded_products_id'] . ")"));
                    while ($product = tep_db_fetch_array($product_query)) {
                      $products[] = $product['products_id'];
                    }
                  } elseif (!empty($check['manufacturers_id'])) {
                    $product_query = tep_db_query("select products_id from products where manufacturers_id in (" . $check['manufacturers_id'] . ")" . (empty($check['excluded_products_id']) ? '' : " and products_id not in (" . $check['excluded_products_id'] . ")"));
                    while ($product = tep_db_fetch_array($product_query)) {
                      $products[] = $product['products_id'];
                    }
                  }
 
                  if ((int)$check['exclude_specials'] == 1) {
                    $specials = array();
                    $product_query = tep_db_query("select p.products_id from products p, specials s where p.products_id = s.products_id and s.status = '1' and ifnull(s.expires_date, now()) >= now()");
                    while ($product = tep_db_fetch_array($product_query)) {
                      $specials[] = $product['products_id'];
                    }
                    if (sizeof($specials) > 0) {
                      $products = array_diff($products, $specials);
                    }
                  }
 
                  if (empty($check['number_of_products'])) {
                    $k = PHP_INT_MAX;
                  } else {
                    $k = $check['number_of_products'];
                  }
 
                  for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {
                    if (in_array(tep_get_prid($order->products[$i]['id']), $products)) {
                      if ($k >= $order->products[$i]['qty']) {
                        $products_discount = $this->format_raw(strpos($check['discount_values'], '%') === false ? $check['discount_values'] * $order->products[$i]['qty'] : tep_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']) * str_replace('%', '', $check['discount_values']) / 100 * $order->products[$i]['qty']);
                        $k -= $order->products[$i]['qty'];
                      } else {
                        $products_discount = $this->format_raw(strpos($check['discount_values'], '%') === false ? $check['discount_values'] * $k : tep_add_tax($order->products[$i]['final_price'], $order->products[$i]['tax']) * str_replace('%', '', $check['discount_values']) / 100 * $k);
                        $k = 0;
                      }
 
                      if (!empty($order->products[$i]['tax'])) {
                        if (DISPLAY_PRICE_WITH_TAX != 'true') {
                          $tax_correction = $this->format_raw(($products_discount * ($order->products[$i]['tax'] / 100)));
                          $order->info['total'] -= $tax_correction;
                        } else {
                          $tax_correction = $this->format_raw($products_discount - $products_discount / (1.0 + $order->products[$i]['tax'] / 100));
                        }
                      }
                      $subtotal_correction +=  $order->products[$i]['final_price']; //use for tax calculation only products which have taxes
                      $order->info['tax'] -= $tax_correction;
                      $order->info['tax_groups'][$order->products[$i]['tax_description']] -= $tax_correction;
                      $discount += $products_discount;
                    }
                  }
 
                  $order->info['total'] -= $discount;
 
                } elseif (!empty($check['orders_total'])) {
                  if ($check['orders_total'] == 2) {
                    $discount = (strpos($check['discount_values'], '%') === false ? $check['discount_values'] : $order->info['subtotal'] * str_replace('%', '', $check['discount_values']) / 100);
                    if ($discount > $order->info['subtotal']) {
                      $discount = $order->info['subtotal'];
                    }
                    $order_tax = 0;
                    for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) {
                      if (!empty($order->products[$i]['tax'])) {
                        //here it gets complicate, we have to find the proportional part of the global discount for each product
                        $global_tax_correction = $this->format_raw($order->products[$i]['qty']*(( $order->products[$i]['final_price']/$order->info['subtotal'])*$discount)+(($order->products[$i]['qty']* $order->products[$i]['final_price']/$order->info['subtotal'])*$discount) * ($order->products[$i]['tax'] / 100));
                        $order->info['total'] -= $global_tax_correction;
                      }
                    }
                  
                    if (is_array($order->info['tax_groups']) && count($order->info['tax_groups']) > 0) {
                      foreach ($order->info['tax_groups'] as $key => $value) {
                        if (!empty($value)) {
                          $order->info['tax_groups'][$key] = $this->format_raw(($order->info['subtotal'] - $discount) * ($value / $order->info['subtotal']));
                          $order_tax += $order->info['tax_groups'][$key];
                        }
                      }
                    }
                    if (!empty($order_tax)) {
                      $order->info['tax'] = $order_tax;
                    } else {
                      $order->info['total'] -= $discount;
                    }
                  }
                  $shipping_discount = 'false';
                } elseif (!empty($check['shipping'])) { //.eof $check['orders_total']
                  if ($check['shipping'] == 2) {
                    $module = substr($GLOBALS['shipping']['id'], 0, strpos($GLOBALS['shipping']['id'], '_'));
                    if (tep_not_null($order->info['shipping_method'])) {
                      if ($GLOBALS[$module]->tax_class > 0) {
                        $shipping_tax = tep_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
                      }
                    }
                $discount = $order->info['shipping_cost'] * str_replace('%', '', strtolower($check['discount_values'])) / 100;
                    if ($discount > $order->info['shipping_cost']) {
                      $discount = $order->info['shipping_cost'];
                    }
                    if (DISPLAY_PRICE_WITH_TAX == 'true' && MODULE_ORDER_TOTAL_DISCOUNT_SORT_ORDER <= MODULE_ORDER_TOTAL_SHIPPING_SORT_ORDER ) $discount += tep_calculate_tax($discount, $shipping_tax);
                    $order_tax = 0;
                    if (is_array($order->info['tax_groups']) && count($order->info['tax_groups']) > 0) {
                      if ( MODULE_ORDER_TOTAL_DISCOUNT_SORT_ORDER <= MODULE_ORDER_TOTAL_SHIPPING_SORT_ORDER ) { // discount before shipping
                        foreach ($order->info['tax_groups'] as $key => $value) {
                          if (!empty($value)) {
                            if ($shipping_tax > 0) {
                              $order->info['tax_groups'][$key] = $this->format_raw(($order->info['subtotal'] - $discount) * ($value / $order->info['subtotal']));
                            } else {
                              $order->info['tax_groups'][$key] = $this->format_raw(($order->info['subtotal']) * ($value / $order->info['subtotal']));
                            }
                            $order_tax += $order->info['tax_groups'][$key];
                          }
                        }
                      } else { // shipping before discount
                        foreach ($order->info['tax_groups'] as $key => $value) {
                          if (!empty($value)) {
                            if ($shipping_tax > 0) {
                              $order->info['tax_groups'][$key] = $this->format_raw(($order->info['subtotal']) * (($value - tep_calculate_tax(((DISPLAY_PRICE_WITH_TAX == 'true')? $discount / (1 + $shipping_tax / 100) : $discount ), $shipping_tax)) / $order->info['subtotal']));
                            } else {
                              $order->info['tax_groups'][$key] = $this->format_raw(($order->info['subtotal']) * ($value / $order->info['subtotal']));
                            }
                            $order_tax += $order->info['tax_groups'][$key];
                          }
                        }
                      }
                    }
                    $order->info['total'] -= $discount;
                    if (DISPLAY_PRICE_WITH_TAX != 'true') $order->info['total'] -= tep_calculate_tax($order->info['shipping_cost'], $shipping_tax);
                    if (!empty($order_tax)) $order->info['tax'] = $order_tax;
                    $shipping_discount = 'true';
                  }
                } //.eof $check['shipping']
              } // eof check newsletter and order number
            }
          }
        }
      }
Edited by davidtranlds

Share this post


Link to post
Share on other sites

Hello David @@davidtranlds,

 

I checked this and the problem only exists until the customer logs in into his PayPal account.  The shipping discount is passed to PayPal as a line item, this means as a kind of product with negative price. Before the customer logs in, no shipping costs apply to the PayPal total calculation meanwhile the discount is already applied. That's why the total shows the negative amount. Once the customer has logged in all shows correct and also when he comes back to checkout_confirmation (if PayPal App is used).

So it is not a real issue other than on the first view when coming to PayPal.

There is no way to fix it as it's how the discount is passed to PayPal and how PayPal express works.

Otherwise you should try PayPal standard, there it should show always correct.

 

rgds

Rainer

Edited by raiwa

Share this post


Link to post
Share on other sites

@@davidtranlds

 

You said "the shipping of $15, and the discount is free shipping, thus there's a -$15 for the discount" I understand your normal price for the shipping is $15 and the discount is free shipping which is causing the negative number. But, are you setting the shipping discount to 100% to get free shipping or are you using a dollar value? As far as I'm aware, you have to use a percentage for the Discount Codes. My discount mod says "Shipping discounts can only be set as percentage. Type 100% for free shipping."

 

Off the top of my head I can't remember where at PayPal, I changed a setting for them to use my shipping rates and not there's.

 

Removing the $ symbol was just a suggestion, I'm not for sure it will work or not. There's other things that helped me with PayPal more. I changed the Admin -Tax Rate to 2 decimals. I changed the Admin - Localization - Currencies to 2 decimals. I set every single database table that had a column with a decimal value to 2 decimal places. They were set at 15,4 and I changed them all to 15,2. It seemed to help with PayPal. Some add-ons people use have the value set to 15,2 when the core uses 15,4. I think it confuses PayPal.

 

If you want to try to see if it will help to remove the $ go to: Admin - Localization - Currencies and make your change there.

 

These are just suggestions you can try.

 

Take care Bill

Share this post


Link to post
Share on other sites

Sorry for the late response - I'm currently using PayPal Standard, as PayPal Express wasn't working to begin with anyways - will try some more testing when I get a chance.

 

I also did put 100% and not 15 as the value. I'm going to play around with it some more though and see how it goes, and will try the Admin changes suggested - thanks.

Share this post


Link to post
Share on other sites

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

×