You may pay someone to create your store, or you visit our seminar and become a professional yourself with the silver certification

Main Menu

Duplicate orders on custom payment method

Started by dude92, March 03, 2015, 12:18:17 PM

Previous topic - Next topic


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_orders', TRUE);

if (!class_exists ('VirtueMartModelOrders')) {
require(VMPATH_ADMIN . DS . 'models' . DS . 'orders.php');
$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;

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
                    //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':
                                $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()));
                                $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;
                                $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;
                        case 'VEVOOLDAL_VISSZAVONT':
                            return FALSE;
                        case 'VEVOOLDAL_TIMEOUT':
                            return FALSE;
                return FALSE;

Thanks in advance!


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?

GJC Web Design

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
GJC Web Design
VirtueMart and Joomla Developers - php developers
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
Contact for any VirtueMart or Joomla development & customisation