VirtueMart Forum

VirtueMart 1.1.x [ Old version - no longer supported ] => Payment VM 1.1 => PayPal / PayPal Pro VM 1.1 => Topic started by: entalzar on October 29, 2012, 11:00:00 AM

Title: PayPal IPN Error: Order Currency Check failed. Modified PayPal VM code settings
Post by: entalzar on October 29, 2012, 11:00:00 AM
My customer had another vendor setup his VirtueMart store and he modified a lot of code. In this case my customer has receive two separate errors when a person completes their orders which are over 25,000 JPY. Below is one example:

During a paypal transaction on your site the received amount didn't match the order total.
                        Order ID: 159_b1bf5beea774983c4d5ebfeb1ac2.
                        Order Number: 159_b1bf5beea774983c4d5ebfeb1ac2.
                        The amount received was: 27090 JPY.
                        It should be: 0 .


I checked the PayPal configuration in VM and noticed a lot of extra code. Please see the below code:

<?php

/** Read current Configuration ***/
include_once(CLASSPATH ."payment/ps_paypal_conf.cfg.php");
include_once(CLASSPATH ."payment/ps_paypal_conf.php");

$db_conf = new ps_DB;
$ps_paypal_conf = new ps_paypal_conf();
$NOTIFY_DEBUG = false;

if ($my->id == null){
    $id_user = $_SESSION['auth']["user_id"];
}else {
    $id_user = $my->id;
}

$url = "https://www.paypal.com/cgi-bin/webscr";
$return_url = SECUREURL ."index.php?option=com_virtuemart&page=checkout.result_confirmation&order_number=";
$notify_url = SECUREURL ."administrator/components/com_virtuemart/notify_gen_transaction.php";
$cancel_return = SECUREURL ."index.php?option=com_virtuemart&page=checkout.result_confirmation&cancel=1";
$errorurl = $return_url;

//$_SESSION["payement_transid"] ="";
isset($_SESSION["payement_transid"])? $transid = $_SESSION["payement_transid"]: $transid = 0;
isset($_SESSION["payement_order_number"])? $order_number = $_SESSION["payement_order_number"]: $order_number=0;

//Calc total for paypal

if (!isset ($discount_total)) $discount_total = 0;
if (!isset ($total)) $total = 0;
if (!isset ($shipping_total)) $shipping_total = 0;

$paypal_total = $total-$discount_total;
if ($auth["show_price_including_tax"] == 0) $paypal_total += $tax_total;

$_SESSION['total_amount'] = round( $paypal_total, 2);
$_SESSION['shipping_amount'] = sprintf("%.2f", $shipping_total);


//Create URL string to save all Request parameters
$requests = JRequest::get();
$confirmurl="";
foreach( $requests as $name => $value ) {
    $confirmurl .= $name . "=" . $value . "&";
}
if(!empty($zone_qty)) $confirmurl .= "&zone_qty=$zone_qty";


//If transaction has already been confirm then User payed and hit back button => Clean up session and redirect to thankyou
if($ps_paypal_conf->payement_is_confirmed($transid, $db_conf)){
         if ($NOTIFY_DEBUG) echo "payement is confirmed";
        //Order has been confirmed so clean up and reload modified SESSION from database
        $order_number = $ps_paypal_conf->cleanup_session($transid, $db_conf);
        // Redirect to thankyou page
        if ($NOTIFY_DEBUG) echo "should redirect to $return_url . $order_number";
        vmRedirect( $return_url . $order_number);

}elseif (!(empty($transid))){
        //User Came back to checkout without having payed, simply update session data in DB
        $sql = "SELECT * from #__vm_orders_temp WHERE id='".$transid."'";
        $db_conf->query($sql);
        if(!$db_conf->next_record()){
            //Transaction is not in DB at all, something is wrnog clean up ...
            $ps_paypal_conf->cleanup_session_vars();
            $transid = "";
            $_SESSION['total_amount'] = round( $paypal_total, 2);
            $_SESSION['shipping_amount'] = sprintf("%.2f", $shipping_total);
        }else{
            if ($NOTIFY_DEBUG) echo "TransID not empty updating DB transid = $transid";
            $sessioncontent=base64_encode(serialize($_SESSION));
            $sql = "UPDATE #__vm_orders_temp SET urlpost='".addslashes($confirmurl)."', urlerror='".addslashes($errorurl)."', sessioncontent='".addslashes($sessioncontent)."' , modifiedtime=NOW() WHERE id='".$transid."'";
            $db_conf->query($sql);
        }

}

if (empty($transid)){
    //First time on Checkout page save temporary transaction information

    //Get Order Number using default checkout function
    include_once(CLASSPATH ."ps_checkout.php");
    $ps_checkout = new ps_checkout();
    $order_number = $ps_checkout->get_order_number();
    if ($NOTIFY_DEBUG) echo "New ORDER NUMBER  = $order_number";

    // Add order Number to session value before saving to db
    $_SESSION["payement_order_number"]=$order_number ;
    $sessioncontent=base64_encode(serialize($_SESSION));

    //Save temporary transaction data to DB
    $sql = "INSERT INTO #__vm_orders_temp (`status`,`urlpost`,`urlerror`,`createdtime`,`modifiedtime`, `sessioncontent`, `order_number` , `user_id`) VALUES
   ('0','".addslashes($confirmurl)."','".addslashes($errorurl)."',NOW(),NOW(),'".addslashes($sessioncontent)."','".$order_number."','".$id_user. "')";
    $db_conf->query($sql);

    $_SESSION["payement_transid"] = $transid = $db_conf->last_insert_id();
}

if ($NOTIFY_DEBUG) print $_SESSION["payement_order_number"];



//Get user infos
$dbbt = new ps_DB;
$q = "SELECT * FROM jos_vm_user_info ";
$q .= "WHERE user_id ='".$id_user."' ";
$dbbt->query($q);


//Get coutry code
$db1 = new ps_DB();
$q = "SELECT country_2_code FROM #__vm_country WHERE country_3_code='".$dbbt->f('country'). "' ORDER BY country_2_code ASC";
$db1->query($q);


//**** START FORM CREATION *****//


if (GENERATE_TRANSACTION_ON_CONFIRMATION == 1) {
    //Form for including directly into checkout.index form
    //Defines all input variables off form
    $post_variables = Array(
        "cmd" => "_ext-enter",
        "charset" => "utf-8",
        "redirect_cmd" => "_xclick",
        "upload" => "1",
        "business" => PAYPAL_EMAIL,
        "receiver_email" => PAYPAL_EMAIL,
        "item_name" => $VM_LANG->_('PHPSHOP_ORDER_PRINT_PO_LBL').": ". $vendor_name,
        "order_id" => $transid,
        "invoice" => $order_number,
        "amount" => round( $paypal_total, 2),
        "shipping" => sprintf("%.2f", $shipping_total),
        "currency_code" => (!empty($_SESSION['product_currency']))? $_SESSION['product_currency'] : $_SESSION['vendor_currency'],

        "address_override" => "1",
        "first_name" => $dbbt->f('first_name'),
        "last_name" => $dbbt->f('last_name'),
        "address1" => $dbbt->f('address_1'),
        "address2" => $dbbt->f('address_2'),
        "zip" => $dbbt->f('zip'),
        "city" => $dbbt->f('city'),
        "state" => $dbbt->f('state'),
        "country" => $db1->f('country_2_code'),
        "email" => $dbbt->f('user_email'),
        "night_phone_b" => $dbbt->f('phone_1'),
        "cpp_header_image" => $vendor_image_url,

        "return" => $return_url . $order_number,
        "notify_url" => $notify_url,
        "cancel_return" => $cancel_return,
        "undefined_quantity" => "0",

        "test_ipn" => PAYPAL_DEBUG,
        "pal" => "NRUBJXESJTY24",
        "no_shipping" => "1",
        "no_note" => "1",
        "rm" => "2"
    );
}else{
//Form for using when Transaction already saved
    $tax_total = $db->f("order_tax") + $db->f("order_shipping_tax");
    $discount_total = $db->f("coupon_discount") + $db->f("order_discount");
    //Defines all input variables off form
    $post_variables = Array(
        "cmd" => "_xclick",
        "charset" => "utf-8",
        "business" => PAYPAL_EMAIL,
        "receiver_email" => PAYPAL_EMAIL,
        "item_name" => $VM_LANG->_PHPSHOP_ORDER_PRINT_PO_NUMBER.": ". $db->f("order_id"),
        "order_id" => $db->f("order_id"),
        "invoice" => $db->f("order_number"),
        "amount" => round( $db->f("order_subtotal")+$tax_total-$discount_total, 2),
        "shipping" => sprintf("%.2f", $db->f("order_shipping")),
        "currency_code" => $_SESSION['vendor_currency'],
        "first_name" => $dbbt->f('first_name'),
        "last_name" => $dbbt->f('last_name'),
        "address_street" => $dbbt->f('address_1'),
        "address_zip" => $dbbt->f('zip'),
        "address_city" => $dbbt->f('city'),
        "address_state" => $dbbt->f('state'),
        "address_country" => $dbbt->f('country'),
        "image_url" => $vendor_image_url,
        "return" => SECUREURL ."index.php?option=com_virtuemart&page=checkout.result&order_id=".$db->f("order_id"),
        "notify_url" => SECUREURL ."administrator/components/com_virtuemart/notify.php",
        "cancel_return" => SECUREURL ."index.php",
        "undefined_quantity" => "0",
        "test_ipn" => PAYPAL_DEBUG,
        "pal" => "NRUBJXESJTY24",
        "no_shipping" => "1",
        "no_note" => "1",
        "rm" => "2"
    );
}

//OLD WAY OF DOING chekout..... If in thankyou page then Transaction was already confirmed and we redirect to PAYPAL
if( $page == "checkout.thankyou" ) {
    $query_string = "?";
    foreach( $post_variables as $name => $value ) {
        $query_string .= $name. "=" . urlencode($value) ."&";
    }
    vmRedirect( $url . $query_string );
} elseif ($page=="checkout.index" )  {
    // Generate The form for the checkout button
    ?>
    <script type="text/javascript">
        var VIRTUEMART_URL="administrator/components/com_virtuemart/notify_gen_transaction.php";
        var VIRTUEMART_REQ_VAL ="save_transaction=1&transid=<?php echo $transid?>";
        var immoxmlhttp;
        var nb_tries=0;
        var max_tries=3;

        <?php if (GENERATE_TRANSACTION_ON_CONFIRMATION == 1) echo 'remove_original_submit_button();'; ?>

        function remove_original_submit_button(){
            document.adminForm.formSubmit.style.display="none";
            //document.getElementsByName("formSubmit")[1].style.display = "none";
        }

        function myXmlHttpReq(){
            if (window.XMLHttpRequest){
                var req = new XMLHttpRequest();
            }else if (window.ActiveXObject){
                var req = new ActiveXObject("Microsoft.XMLHTTP");
            }
            return req;
        }

        function sendReq(){
            immoxmlhttp = new myXmlHttpReq();
            immoxmlhttp.onreadystatechange = processCommentReqChange;
            immoxmlhttp.open("POST", VIRTUEMART_URL, true);
            immoxmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            immoxmlhttp.send(VIRTUEMART_REQ_VAL);
            setLoadingImg();
        }

        function setLoadingImg(){
            img_req='<img src="images/stories/spin.gif">';
            ldimgdiv=document.getElementById("loadimgdivid");
            ldimgdiv.innerHTML=img_req;
        }

        function validateAndSentForm(){
            if(submit_order( document.adminForm )){
               VIRTUEMART_REQ_VAL += "&customernote=" + document.adminForm.customer_note.value;
               sendReq();
               return true;
            }
            else
                return false;
        }

        function processCommentReqChange(){
            if (immoxmlhttp.readyState == 4){
                 try{
                    // only if "OK"
                    if (immoxmlhttp.status == 200){
                       //alert(immoxmlhttp.responseText);
                        var r=immoxmlhttp.responseText;
                       var haserror=r.substring(r.indexOf("<error>"),r.indexOf("</error>")).replace("<error>","");
                        if(haserror==1){
                            errmsg= r.substring(r.indexOf("<errormsg>"),r.indexOf("</errormsg>")).replace("<errormsg>","");
                            alert(errmsg);
                        }
                        else{
                            //we submit the form
                            //document.forms[2].submit();
                            //postform=document.getElementById("postfinanceformid");

                          /*$transid = r.substring(r.indexOf("<errormsg>"),r.indexOf("</errormsg>")).replace("<errormsg>","");
                          $form=document.getElementById("payment_method_form");
                          $form.order_id.value=$transid;
                          $form.invoice.value=$transid;
                            */
                            document.getElementById("payment_method_form").submit();
                            //postform.submit();
                        }
                    }else{
                        if(nb_tries >= max_tries){
                            //Send an error message
                            ldimgdiv=document.getElementById("loadimgdivid");
                            ldimgdiv.innerHTML += ' Connection lost, retrying connection ... <br>';
                            nb_tries=0;
                        }else{
                            nb_tries++;
                        }
                        setTimeout('sendReq()', 3000);
                    }
                }catch(E){
                    alert(E);
                    if(nb_tries >= max_tries){
                        ldimgdiv=document.getElementById("loadimgdivid");
                        ldimgdiv.innerHTML="Connection lost, retrying connection ...";
                        nb_tries=0;
                    }else{
                        nb_tries++;
                    }
                        setTimeout('sendReq()', 3000);
                }
            }
        }

    </script>

    <?php
    // Close the Checkout Form, which was opened in the first checkout template using the variable $basket_html
    echo '</form>';

    if (GENERATE_TRANSACTION_ON_CONFIRMATION == 1){
        echo '<form action="'.$url.'" method="post" id="payment_method_form">';
        echo '<div align="center" id="loadimgdivid"><input type="button" name="confirmbutton" value="'.$VM_LANG->_('PHPSHOP_ORDER_CONFIRM_MNU').'" onclick="return( validateAndSentForm());" class="css3button" style="align:middle;"></div>';
        //echo '<input type="image" name="submit" src="https://www.paypal.com/en_US/i/btn/x-click-but6.gif" onclick="return( validateAndSentForm()) alt="Click to pay with PayPal - it is fast, free and secure!" />';
        //<div id="loadimgdivid"><input type="css3button" name="confirmbutton" value="Confirmer" onclick="return( validateAndSentForm() );" style="text-align:middle;width:115px;height:15px;cursor:pointer;border:none;font-weight:bold;color:#b9298b;font-size:10px;font-family:inherit;background: url('{TEMPLATEPATH}/images/bouton.png') no-repeat top right transparent;margin-top:10px;"></div>
        foreach( $post_variables as $name => $value ) {
            echo '<input type="hidden" name="'.$name.'" value="'.htmlspecialchars($value).'" />
            ';
        }
        echo '</form>';
    }
}
//**** END  FORM CREATION *****//



?>

If anyone has any suggestions I would really appreciate your assistance.
Title: Re: PayPal IPN Error: Order Currency Check failed. Modified PayPal VM code settings
Post by: stinga on October 29, 2012, 18:59:14 PM
The
'During a paypal transaction on your site the received amount didn't match the order total.'
Is not generated by the code above, it comes from notify.php

If 'During a paypal transaction on your site the received amount didn't match the order total.' is correct then the order total must be wrong.
What it wrong? the 27090 or the 0?