VirtueMart Forum

VirtueMart 2 + 3 + 4 => Virtuemart Development and bug reports => Coding Central => Topic started by: dude92 on March 03, 2015, 12:18:17 PM

Title: Duplicate orders on custom payment method
Post by: dude92 on March 03, 2015, 12:18:17 PM
Hello all! This is my first task with VirtueMart, never used it before, not even Joomla. My task is to create a payment plugin for a bank. I managed the redirection to the bank from the shop and to the shop back from the bank, also got the transaction datas from the bank. The goal is to save the order as confirmed if the transaction is succesful and save it as cancelled if the transaction fails. I reused the standard plugin from the aio package and modified the plgVmConfirmedOrder function. Now when the user clicks the confirm order button, he gets redirected to the bank, then back to the page with an answer object. The only problem, the orders get stored twice with as pending. I never used VM before, any help is apreciated. The code:
function plgVmConfirmedOrder ($cart, $order) {
               
if (!($method = $this->getVmPluginMethod ($order['details']['BT']->virtuemart_paymentmethod_id))) {
return NULL; // Another method was selected, do nothing
}
if (!$this->selectedThisElement ($method->payment_element)) {
return FALSE;
}

VmConfig::loadJLang('com_virtuemart',true);
VmConfig::loadJLang('com_virtuemart_orders', TRUE);

if (!class_exists ('VirtueMartModelOrders')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'orders.php');
}
               
$this->getPaymentCurrency($method);
$currency_code_3 = shopFunctions::getCurrencyByID($method->payment_currency, 'currency_code_3');
$email_currency = $this->getEmailCurrency($method);
               
$totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total,$method->payment_currency);
               
$dbValues['payment_name'] = $this->renderPluginName ($method) . '<br />' . $method->payment_info;
$dbValues['order_number'] = $order['details']['BT']->order_number;
$dbValues['virtuemart_paymentmethod_id'] = $order['details']['BT']->virtuemart_paymentmethod_id;
$dbValues['cost_per_transaction'] = $method->cost_per_transaction;
$dbValues['cost_percent_total'] = $method->cost_percent_total;
$dbValues['payment_currency'] = $currency_code_3;
$dbValues['email_currency'] = $email_currency;
               
$dbValues['payment_order_total'] = $totalInPaymentCurrency['value'];
$dbValues['tax_id'] = $method->tax_id;

$payment_info='';
if (!empty($method->payment_info)) {
$lang = JFactory::getLanguage ();
if ($lang->hasKey ($method->payment_info)) {
$payment_info = vmText::_ ($method->payment_info);
} else {
$payment_info = $method->payment_info;
}
}
if (!class_exists ('VirtueMartModelCurrency')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'currency.php');
}
$currency = CurrencyDisplay::getInstance ('', $order['details']['BT']->virtuemart_vendor_id);
                if(!array_key_exists("fizetesValasz", $_REQUEST)){
                    $transaction_id = $this->getTransactionID();
                    //the banks framework builds the data up from the given $_REQUEST parameters
                    $_REQUEST['tranzakcioAzonosito'] = $transaction_id;
                    $price = $cart->cartPrices['billTotal'];
                    $_REQUEST['osszeg'] = round($price);
                    $_REQUEST['devizanem'] = 'HUF';
                    $_REQUEST['backURL'] = "http://" . $_SERVER['SERVER_NAME'] . '/component/virtuemart/cart/confirm.html?Itemid=' . $_REQUEST['Itemid'];
                    $_REQUEST['nyelvkod'] = 'hu';
                    $dbValues['transaction_id'] = $transaction_id;
                    //this is where I redirect the user to the bank interface
                    process();
                }
                else{
                    //this is where I get the transaction datas, processDirectedToBackUrl redirects to the $_REQUEST['backURL']
                    $transaction_datas = processDirectedToBackUrl(false);
                    $status_code = $transaction_datas->getStatuszKod();
                    $dbValues['otp_response'] = $status_code;
                    $this->storePSPluginInternalData ($dbValues);
                    $modelOrder = VmModel::getModel ('orders');
                    switch ($status_code) {
                        case 'FELDOLGOZVA':
                            if($transaction_datas->isSuccessful()){
                                $message = 'Sikeres Tranzakció!';
                               
                                $new_status = $this->getNewStatus($method);
                                $order['customer_notified'] = 1;
                                $order['comments'] = '';
                                $modelOrder->updateStatusForOneOrder ($order['details']['BT']->virtuemart_order_id, $order, TRUE);
                                $message = getMessageText(($transaction_datas->getPosValaszkod()));
                                $cart->emptyCart();
                                $html = $this->renderByLayout('post_payment_success', array(
                                    'message' =>$message,
                                    'order_number' =>$order['details']['BT']->order_number,
                                    'order_pass' =>$order['details']['BT']->order_pass,
                                    'payment_name' => $dbValues['payment_name'],
                                    'displayTotalInPaymentCurrency' => round($totalInPaymentCurrency['display'])
                                ));
                               
                                vRequest::setVar ('html', $html);
                                return TRUE;
                            }
                            else{
                                $new_status = $method->status_pending;
                                $modelOrder->updateStatusForOneOrder($order['details']['BT']->virtuemart_order_id, $order, TRUE);
                                $message = 'Sajnos a bank visszautasította a tranzakciót.';
                                $html = $this->renderByLayout('post_payment_failure', array(
                                    'message' => $message
                                   
                                ));
                                vRequest::setVar('html', $html);
                                return FALSE;
                            }
                            break;
                        case 'VEVOOLDAL_VISSZAVONT':
                           
                            return FALSE;
                            break;
                        case 'VEVOOLDAL_TIMEOUT':
                           
                            return FALSE;
                            break;
                    }
                   
                   
                }
               
                return FALSE;
               
}

Thanks in advance!
Title: Re: Duplicate orders on custom payment method
Post by: dude92 on March 03, 2015, 14:28:13 PM
Ok. So I figured this out so far: the order is duplicated because the form sends the data to the url, that I send the user back, so (maybe) the functions that save the order get called twice. How can I avoid that?
Title: Re: Duplicate orders on custom payment method
Post by: GJC Web Design on March 03, 2015, 14:31:22 PM
the std payment plug doesn't use all the features  -
check something like the Authorize plugin to see how return to the site is handled