AAAA_loggable = TRUE; $this->tableFields = array_keys($this->getTableSQLFields()); $this->_tablepkey = 'id'; //virtuemart_sofort_id'; $this->_tableId = 'id'; //'virtuemart_sofort_id'; $varsToPush = array('payment_logos' => array('', 'char'), 'configuration_key' => array('', 'char'), 'buyer_protection' => array('', 'int'), 'payment_currency' => array('', 'int'), 'email_currency' => array('', 'int'), 'countries' => array('', 'char'), 'min_amount' => array('', 'float'), 'max_amount' => array('', 'float'), 'cost_per_transaction' => array('', 'char'), 'cost_percent_total' => array('', 'char'), 'tax_id' => array('', 'int'), 'status_pending' => array('', 'char'), 'status_received' => array('', 'char'), 'status_loss' => array('', 'char'), 'status_refunded' => array('', 'char'), 'debug' => array('', 'int'), ); $this->setConfigParameterable($this->_configTableFieldName, $varsToPush); } /** * @return string */ public function getVmPluginCreateTableSQL () { return $this->createTableSQL('Payment Sofort Table'); } /** * @return array */ function getTableSQLFields () { $SQLfields = array( 'id' => 'int(11) UNSIGNED NOT NULL AUTO_INCREMENT', 'virtuemart_order_id' => 'int(1) UNSIGNED', 'order_number' => 'char(64)', 'virtuemart_paymentmethod_id' => 'mediumint(1) UNSIGNED', 'payment_name' => 'varchar(1000)', 'payment_order_total' => 'decimal(15,5) NOT NULL', 'payment_currency' => 'smallint(1)', 'email_currency' => 'smallint(1)', 'cost_per_transaction' => 'decimal(10,2)', 'cost_percent_total' => 'decimal(10,2)', 'tax_id' => 'smallint(1)', 'sofort_custom' => 'varchar(255)', 'security' => 'varchar(50)', 'sofort_response_amount' => 'decimal(15,5) NOT NULL', 'sofort_response_currency' => 'varchar(50)', 'sofort_response_status' => 'varchar(50)', 'sofort_response_status_reason' => 'varchar(50)', 'sofort_response_transaction' => 'varchar(100)', 'sofort_response_invoice' => 'varchar(1000)' ); return $SQLfields; } /** * @param $cart * @param $order * @return bool|null */ 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; } $this->sendTransactionRequest($method,$cart, $order); } function displayErrors ($errors) { foreach ($errors as $error) { vmError(JText::sprintf('VMPAYMENT_SOFORT_ERROR_FROM', $error ['message'], $error ['field'], $error ['code'])); vmInfo(JText::sprintf('VMPAYMENT_SOFORT_ERROR_FROM', $error ['message'], $error ['field'], $error ['code'])); if ($error ['message'] == 401) { vmdebug('check you payment parameters: custom_id, project_id, api key'); } } } function sendTransactionRequest ($method, $cart, $order, $doRedirect = true) { $session = JFactory::getSession(); $return_context = $session->getId(); //$this->_debug = $method->debug; //$this->logInfo('plgVmConfirmedOrder order number: ' . $order['details']['BT']->order_number, 'message'); vmdebug('SOFORT sendTransactionRequest'); if (!class_exists('VirtueMartModelOrders')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); } if (!class_exists('VirtueMartModelCurrency')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'currency.php'); } if (!class_exists ('CurrencyDisplay')) { require(JPATH_VM_ADMINISTRATOR . DS . 'helpers' . DS . 'currencydisplay.php'); } if (!class_exists('TableVendors')) { require(JPATH_VM_ADMINISTRATOR . DS . 'tables' . DS . 'vendors.php'); } $this->getPaymentCurrency($method); $email_currency = $this->getEmailCurrency($method); $currency_code_3 = shopFunctions::getCurrencyByID($method->payment_currency, 'currency_code_3'); $totalInPaymentCurrency = vmPSPlugin::getAmountInCurrency($order['details']['BT']->order_total,$method->payment_currency); $cd = CurrencyDisplay::getInstance($cart->pricesCurrency); // Prepare data that should be stored in the database $dbValues['order_number'] = $order['details']['BT']->order_number; $dbValues['payment_name'] = $this->renderPluginName($method, 'create_order'); $dbValues['virtuemart_paymentmethod_id'] = $cart->virtuemart_paymentmethod_id; $dbValues['cost_per_transaction'] = $method->cost_per_transaction; $dbValues['cost_percent_total'] = $method->cost_percent_total; $dbValues['payment_currency'] = $method->payment_currency; $dbValues['email_currency'] = $email_currency; $dbValues['payment_order_total'] = $totalInPaymentCurrency['value']; $dbValues['tax_id'] = $method->tax_id; $dbValues['sofort_custom'] = $return_context; $security = self::getSecurityKey(); $dbValues['security'] = $security; vmdebug('SOFORT sendTransactionRequest ... after storePSPluginInternalData', $security); if (!class_exists('SofortLib')) { require(JPATH_ROOT . DS . 'plugins' . DS . 'vmpayment' . DS . 'sofort' . DS . 'sofort' . DS . 'library' . DS . 'sofortLib.php'); } $sofort = new SofortLib_Multipay($method->configuration_key); $sofort->setVersion(self::RELEASE); $sofort->setAmount($totalInPaymentCurrency['value'], $currency_code_3); $sofort->setReason($order['details']['BT']->order_number); $sofort->setSuccessUrl(self::getSuccessUrl($order)); $sofort->setAbortUrl(self::getCancelUrl($order)); $sofort->setNotificationUrl(self::getNotificationUrl($security, $order['details']['BT']->order_number)); $sofort->setSofortueberweisung(); $sofort->setSofortueberweisungCustomerprotection($method->buyer_protection); $jlang = JFactory::getLanguage (); $lang = $jlang->getTag (); $langArray = explode ("-", $lang); $lang = strtolower ($langArray[1]); $sofort->setLanguageCode($lang); $sofort->sendRequest(); vmdebug('SOFORT sendTransactionRequest ... SofortLib_Multipay ... sendRequest()'); if ($sofort->isError()) { $errors = $sofort->getErrors(); vmdebug('SOFORT sendTransactionRequest ... SofortLib_Multipay ... getErrors()', $errors); $this->displayErrors($errors); // TODO redirect to cancel URL //return $cancel_url; return; } $url = $sofort->getPaymentUrl(); $dbValues['sofort_response_transaction'] = $sofort->getTransactionId(); vmdebug('storePSPluginInternalData', $dbValues); $this->storePSPluginInternalData($dbValues); if ($doRedirect) { $mainframe = JFactory::getApplication(); $mainframe->redirect($url); } } /** * @param $virtuemart_paymentmethod_id * @param $paymentCurrencyId * @return bool|null */ function plgVmgetPaymentCurrency ($virtuemart_paymentmethod_id, &$paymentCurrencyId) { if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($method->payment_element)) { return FALSE; } $this->getPaymentCurrency($method); $paymentCurrencyId = $method->payment_currency; } /** * @param $virtuemart_paymentmethod_id * @param $paymentCurrencyId * @return bool|null */ function plgVmgetEmailCurrency ($virtuemart_paymentmethod_id, $virtuemart_order_id, &$emailCurrencyId) { if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($method->payment_element)) { return FALSE; } if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return ''; } //vmdebug('plgVmgetEmailCurrency', $payments); if (empty($payments[0]->email_currency)) { $vendorId = 1; //VirtueMartModelVendor::getLoggedVendor(); $db = JFactory::getDBO(); $q = 'SELECT `vendor_currency` FROM `#__virtuemart_vendors` WHERE `virtuemart_vendor_id`=' . $vendorId; $db->setQuery($q); $emailCurrencyId = $db->loadResult(); } else { $emailCurrencyId = $payments[0]->email_currency; } } /** * @param $html * @return bool|null|string */ function plgVmOnPaymentResponseReceived (&$html) { if (!class_exists('VirtueMartCart')) { require(JPATH_VM_SITE . DS . 'helpers' . DS . 'cart.php'); } if (!class_exists('shopFunctionsF')) { require(JPATH_VM_SITE . DS . 'helpers' . DS . 'shopfunctionsf.php'); } if (!class_exists('VirtueMartModelOrders')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); } // the payment itself should send the parameter needed. $virtuemart_paymentmethod_id = JRequest::getInt('pm', 0); $order_number = JRequest::getString('on', 0); if (!($method = $this->getVmPluginMethod($virtuemart_paymentmethod_id))) { //vmdebug('plgVmOnPaymentResponseReceived NOT getVmPluginMethod'); return NULL; // Another method was selected, do nothing } if (!$this->selectedThisElement($method->payment_element)) { //vmdebug('SOFORT plgVmOnPaymentResponseReceived NOT selectedThisElement'); return NULL; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { //vmdebug('SOFORT plgVmOnPaymentResponseReceived NOT getOrderIdByOrderNumber'); return NULL; } if (!($paymentTables = $this->getDatasByOrderId($virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return ''; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); // may be we did not receive the notification // Thus the call of the success-URL should check, if the notification has already been arrived at the shop . //If this is not true, a transaction detail request (step 4) should be triggered with the call of the success-URL, if (count($paymentTables) == 1) { $cart = VirtueMartCart::getCart(); $this->sendTransactionRequest($method,$cart, $order, false); } $html = $this->_getPaymentResponseHtml($method, $order, $paymentTables); //We delete the old stuff // get the correct cart / session $cart = VirtueMartCart::getCart(); $cart->emptyCart(); return TRUE; } /** * @return bool|null */ function plgVmOnUserPaymentCancel () { $order_number = JRequest::getString('on', ''); $virtuemart_paymentmethod_id = JRequest::getInt('pm', ''); if (empty($order_number) or empty($virtuemart_paymentmethod_id) or !$this->selectedThisByMethodId($virtuemart_paymentmethod_id)) { vmdebug('plgVmOnUserPaymentCancel', $order_number, $virtuemart_paymentmethod_id); return NULL; } if (!class_exists('VirtueMartModelOrders')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { return NULL; } if (!($paymentTable = $this->getDataByOrderId($virtuemart_order_id))) { return NULL; } vmdebug('plgVmOnUserPaymentCancel', 'VMPAYMENT_SOFORT_PAYMENT_CANCELLED'); VmInfo(Jtext::_('VMPAYMENT_SOFORT_PAYMENT_CANCELLED')); $session = JFactory::getSession(); $return_context = $session->getId(); if (strcmp($paymentTable->sofort_custom, $return_context) === 0) { vmDebug('handlePaymentUserCancel'); $this->handlePaymentUserCancel($virtuemart_order_id); } else { vmDebug('Return context', $paymentTable->sofort_custom, $return_context); } return TRUE; } /* * plgVmOnPaymentNotification() - This event is fired by Offline Payment. It can be used to validate the payment data as entered by the user. * Return: * Parameters: * None * @author Valerie Isaksen */ /** * @return bool|null */ function plgVmOnPaymentNotification () { //$this->_debug = true; if (!class_exists('VirtueMartModelOrders')) { require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); } $order_number = JRequest::getString('on', ''); if (empty($order_number)) { return FALSE; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { return FALSE; } if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { return FALSE; } $this->logInfo('plgVmOnPaymentNotification OK ', 'message'); $method = $this->getVmPluginMethod($payments[0]->virtuemart_paymentmethod_id); if (!$this->selectedThisElement($method->payment_element)) { return FALSE; } if (!class_exists('SofortLib')) { require(JPATH_ROOT . DS . 'plugins' . DS . 'vmpayment' . DS . 'sofort' . DS . 'sofort' . DS . 'library' . DS . 'sofortLib.php'); } $sofortLib_Notification = new SofortLib_Notification(); $transactionId = $sofortLib_Notification->getNotification(); //no valid parameters/xml if (empty($transactionId) || $sofortLib_Notification->isError()) { $this->logInfo('plgVmOnPaymentNotification NO transaaction or $sofortLib_Notification is error \n', 'message'); return FALSE; } $this->logInfo('plgVmOnPaymentNotification transaction ' . $transactionId, 'message'); $sofortLib_TransactionData = new SofortLib_TransactionData($method->configuration_key); $sofortLib_TransactionData->setTransaction($transactionId)->sendRequest(); $this->logInfo('plgVmOnPaymentNotification setTransaction OK', 'message'); // check that secret , and order are identical $security = JRequest::getString('security', ''); if ($security != $payments[0]->security) { $this->logInfo('plgVmOnPaymentNotification SECURITY not the one expected GOT: ' . $security . ' stored: ' . $payments[0]->security, 'message'); $emailBody = "Hello,\n\nerror while receiving a SOFORT NOTIFICATION" . "\n"; $emailBody .= "for order number: " . $order_number . "\n"; $emailBody .= "security token received: " . $security . "\n"; $emailBody .= "security token expected: " . $payments[0]->security . "\n"; $this->sendEmailToVendorAndAdmins(JText::_('VMPAYMENT_SOFORT_ERROR_NOTIFICATION'), $emailBody); return false; } $paymentMethod = $sofortLib_TransactionData->getPaymentMethod(); if ($paymentMethod != self::SU_SOFORTBANKING) { // answer not expected $this->logInfo('plgVmOnPaymentNotification not the one one expected?' . $paymentMethod . ' ' . self::SU_SOFORTBANKING, 'message'); $emailBody = "Hello,\n\nerror while receiving a SOFORT NOTIFICATION" . "\n"; $emailBody .= "Payment method is " . $paymentMethod . " Should be SU \n"; $this->sendEmailToVendorAndAdmins(JText::_('VMPAYMENT_SOFORT_ERROR_NOTIFICATION'), $emailBody); return false; } $this->logInfo('plgVmOnPaymentNotification so', 'message'); $sofort_data['sofort_response_amount'] = $sofortLib_TransactionData->getAmount(); $sofort_data['sofort_response_currency'] = $sofortLib_TransactionData->getCurrency(); // check that the amount is the same if (!$this->_checkAmountAndCurrency($sofort_data, $payments)) { return false; } $modelOrder = VmModel::getModel('orders'); $order = array(); $status = 'status_' . $sofortLib_TransactionData->getStatus(); //$this->logInfo('plgVmOnPaymentNotification getStatus:' .$status. ' '.var_export($method, true) , 'message'); $order['customer_notified'] = true; $order['order_status'] = $method->$status; $order['comments'] = JText::_('VMPAYMENT_SOFORT_RESPONSE_STATUS_REASON_' . $sofortLib_TransactionData->getStatusReason()); $sofort_data['sofort_response_status_reason'] = $sofortLib_TransactionData->getStatusReason(); $sofort_data['sofort_response_transaction'] = $sofortLib_TransactionData->getTransaction(); $sofort_data['payment_name'] = str_replace(array('\t', '\n'), '', $this->renderPluginName($method)); $sofort_data['virtuemart_order_id'] = $payments[0]->virtuemart_order_id; $sofort_data['order_number'] = $payments[0]->order_number; $sofort_data['virtuemart_paymentmethod_id'] = $payments[0]->virtuemart_paymentmethod_id; $sofort_data['sofort_response_status'] = $sofortLib_TransactionData->getStatus();; $sofort_data['sofort_response_status_reason'] = $sofortLib_TransactionData->getStatusReason(); $this->logInfo('storePSPluginInternalData before storePSPluginInternalData ' . var_export($sofort_data, true), 'message'); $this->storePSPluginInternalData($sofort_data); $modelOrder->updateStatusForOneOrder($payments[0]->virtuemart_order_id, $order, TRUE); } function _checkAmountAndCurrency ($sofort_data, $payments) { $payment_currency_code_3 = shopFunctions::getCurrencyByID($payments[0]->payment_currency, 'currency_code_3'); if (($sofort_data['sofort_response_amount'] != $payments[0]->payment_order_total) or ($sofort_data['sofort_response_currency'] != $payment_currency_code_3)) { $this->logInfo('plgVmOnPaymentNotification _checkAmountAndCurrency' . $sofort_data['sofort_response_amount'] . ' ' . $payments[0]->payment_order_total, 'message'); $this->logInfo('plgVmOnPaymentNotification _checkAmountAndCurrency' . $sofort_data['sofort_response_currency'] . ' ' . $payment_currency_code_3, 'message'); $emailBody = "Hello,\n\nerror while receiving a SOFORT NOTIFICATION" . "\n"; $emailBody .= "for order number: " . $payments[0]->order_number . "\n"; $emailBody .= "Amount received: " . $sofort_data['sofort_response_amount'] . "\n"; $emailBody .= "Amount expected: " . $payments[0]->payment_order_total . "\n"; $emailBody .= "Currency received: " . $sofort_data['sofort_response_currency'] . "\n"; $emailBody .= "Currency expected: " . $payment_currency_code_3 . "\n"; $this->sendEmailToVendorAndAdmins(JText::_('VMPAYMENT_SOFORT_ERROR_NOTIFICATION'), $emailBody); return false; } return true; } /** * Display stored payment data for an order * @param int $virtuemart_order_id * @param int $payment_method_id * @see components/com_virtuemart/helpers/vmPSPlugin::plgVmOnShowOrderBEPayment() */ function plgVmOnShowOrderBEPayment ($virtuemart_order_id, $payment_method_id) { if (!$this->selectedThisByMethodId($payment_method_id)) { return NULL; // Another method was selected, do nothing } if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { // JError::raiseWarning(500, $db->getErrorMsg()); return ''; } $html = '
| ' . JText::_('COM_VIRTUEMART_DATE') . ' | ' . $payment->created_on . ' |