| Server IP : 85.158.181.41 / Your IP : 216.73.217.12 Web Server : Apache System : Linux cloud9-vm129 6.1.178+1-ph #ph SMP PREEMPT_DYNAMIC Wed Jul 29 09:00:54 UTC 2026 x86_64 User : moncbefd ( 1024) PHP Version : 7.3.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/moncbefd/www.moneta.at/callback/sofort/ |
Upload File : |
<?php
/* --------------------------------------------------------------
sofort.php 2017-04-05
Gambio GmbH
http://www.gambio.de
Copyright (c) 2017 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
/**
* @version SOFORT Gateway 5.2.0 - $Date: 2013-05-22 15:21:58 +0200 (Wed, 22 May 2013) $
* @author SOFORT AG (integration@sofort.com)
* @link http://www.sofort.com/
*
* Copyright (c) 2012 SOFORT AG
*
* Released under the GNU General Public License (Version 2)
* [http://www.gnu.org/licenses/gpl-2.0.html]
*
* $Id: sofort.php 6157 2013-05-22 13:21:58Z rotsch $
*/
require_once(DIR_FS_CATALOG.'callback/sofort/helperFunctions.php');
$language = HelperFunctions::getSofortLanguage($_SESSION['language']);
$coo_lang_file_master = MainFactory::create_object('LanguageTextManager', array(), true);
$coo_lang_file_master->init_from_lang_file('lang/' . $language . '/modules/payment/sofort_general.php');
/**
* Superclass of xt-commerce modules
*/
class sofort {
//Shop-Vars
var $form_action_url, $tmpOrders, $tmpStatus, $icons_available, $enabled, $code, $description, $title, $sort_order;
//SOFORT-Vars
var $title_extern, $sofort, $invoice, $paymentMethod;
function sofort(){
if (!isset($_SESSION['sofort'])) $_SESSION['sofort'] = array();
$this->form_action_url = '';
$this->tmpOrders = true;
$tmpStatusId = (defined('MODULE_PAYMENT_SOFORT_MULTIPAY_TEMP_STATUS_ID') ? HelperFunctions::checkStatusId(MODULE_PAYMENT_SOFORT_MULTIPAY_TEMP_STATUS_ID) : (int)DEFAULT_ORDERS_STATUS_ID);
//dont set a new status? -> then use DEFAULT_ORDERS_STATUS_ID
if (HelperFunctions::statusIsUnchangedStatus($tmpStatusId)) $tmpStatusId = DEFAULT_ORDERS_STATUS_ID;
$this->tmpStatus = HelperFunctions::checkStatusId($tmpStatusId);
$this->icons_available = '';
$this->sofort = '';
$this->invoice = '';
//all other class-vars are initialized in child
//first status in history - set if needed (and add to class-vars) @see class order -> function cart()
//$this->order_status = 'MyStatus';
}
/**
* check if payment method is allowed in the payment zone
* if not: module will be disabled
*/
function update_status() {
global $order;
$constantValue = constant ('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_ZONE');
if (($this->enabled == true) && ((int) $constantValue > 0)) {
$checkFlag = false;
$checkQuery = xtc_db_query("SELECT zone_id FROM " . HelperFunctions::escapeSql(TABLE_ZONES_TO_GEO_ZONES) . " WHERE geo_zone_id = '" . HelperFunctions::escapeSql($constantValue) . "' AND zone_country_id = '" . HelperFunctions::escapeSql($order->billing['country']['id']) . "' ORDER BY zone_id");
while ($check = xtc_db_fetch_array($checkQuery)) {
if ($check['zone_id'] < 1) {
$checkFlag = true;
break;
} elseif ($check['zone_id'] == $order->billing['zone_id']) {
$checkFlag = true;
break;
}
}
if ($checkFlag == false) $this->enabled = false;
}
}
function javascript_validation() {
return '';
}
/**
* extended in all modules "by sofort"
*/
function pre_confirmation_check($vars = '') {
}
/**
* call with parent::selection() in child
*/
function selection() {
//$this->_checkCancelOrder(); //DONT ENABLE! - not compatible with Gambio because selection() is (always) called in class payment->constructor!
//return false, if modulfiles are incompatible with installed version or was not correct updated
if (!$this->_modulVersionCheck()) {
if (is_object($this->sofort)) {
$this->sofort->logWarning("Paymentmodul was updated by seller but not correct installed. Installed-version in DB does not match file-versions. Please take a look at MODULE_PAYMENT_SOFORT_MULTIPAY_UPDATE_NOTICE or read the manual!");
} elseif (is_object($this->invoice)) {
$this->invoice->logWarning("Paymentmodul was updated by seller but not correct installed. Installed-version in DB does not match file-versions. Please take a look at MODULE_PAYMENT_SOFORT_MULTIPAY_UPDATE_NOTICE or read the manual!");
}
return false;
}
if (isset($_SESSION['sofort']['apiKeyIsValid'])) {
return $_SESSION['sofort']['apiKeyIsValid'];
} else if (!isset($_SESSION['sofort']['apiKeyIsValid'])) {
$apiTestResult = HelperFunctions::apiKeyIsValid(MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY);
if (!$apiTestResult) {
if (is_object($this->sofort)) {
$this->sofort->log("Notice: Function apiKeyIsValid() returned false.");
} elseif (is_object($this->invoice)) {
$this->invoice->log("Notice: Function apiKeyIsValid() returned false.");
}
}
$_SESSION['sofort']['apiKeyIsValid'] = $apiTestResult;
return $apiTestResult;
}
}
function confirmation () {
$this->_checkCancelOrder();
return false;
}
function process_button() {
return false;
}
/**
* does nothing
* overwritten by SV
*/
function before_process() {
}
function payment_action() {
global $order, $insert_id, $order_totals;
$orderId = $insert_id;
$customerId = $_SESSION['customer_id'];
$currency = $_SESSION['currency'];
//if buyer will not successfully abort the payment (e.g. close the SOFORT-Wizard) and the go to the
//shop-index.php and want to pay again -> set the orderStatus to "aborted"
$_SESSION['sofort']['cart_pn_sofortueberweisung_id'] = $_SESSION['cart']->cartID . '-' . $orderId;
$reasons = $this->_getReasons($this->paymentMethod, $customerId, $order, $orderId);
$paymentSecret = md5(mt_rand().microtime());
$userVariable_0 = $orderId;
$userVariable_1 = $customerId;
$userVariable_2 = $_SESSION['cart']->cartID;
$userVariable_3 = $paymentSecret;
$amount = $this->_getShopTotal($order_totals, $order);
$successUrl = xtc_href_link('callback/sofort/ressources/scripts/sofortReturn.php', 'sofortaction=success&sofortcode='.$this->code, 'SSL', true, false);
$successUrl = HelperFunctions::cleanUrlParameter($successUrl);
$cancelUrl = xtc_href_link('callback/sofort/ressources/scripts/sofortReturn.php', 'sofortaction=cancel&sofortcode='.$this->code, 'SSL', true, false);
$cancelUrl = HelperFunctions::cleanUrlParameter($cancelUrl);
$notificationUrl = xtc_href_link('callback/sofort/callback.php', 'paymentSecret='.$paymentSecret.'&action=multipay', 'SSL', true, false);
$notificationUrl = HelperFunctions::cleanUrlParameter($notificationUrl);
$this->sofort->setAmount($amount, $currency);
$this->sofort->setReason(HelperFunctions::convertEncoding($reasons[0],3), HelperFunctions::convertEncoding($reasons[1],3));
$this->sofort->setSuccessUrl(HelperFunctions::convertEncoding($successUrl,3));
$this->sofort->setAbortUrl(HelperFunctions::convertEncoding($cancelUrl,3));
$this->sofort->setTimeoutUrl(HelperFunctions::convertEncoding($cancelUrl,3));
$this->sofort->setNotificationUrl(HelperFunctions::convertEncoding($notificationUrl,3));
$this->sofort->addUserVariable(HelperFunctions::convertEncoding($userVariable_0,3));
$this->sofort->addUserVariable(HelperFunctions::convertEncoding($userVariable_1,3));
$this->sofort->addUserVariable(HelperFunctions::convertEncoding($userVariable_2,3));
$this->sofort->addUserVariable(HelperFunctions::convertEncoding($userVariable_3,3));
$this->sofort->setEmailCustomer(HelperFunctions::convertEncoding($order->customer['email_address'],3));
$this->sofort->setPhoneNumberCustomer(HelperFunctions::convertEncoding($order->customer['telephone'],3));
//set special settings for every payment-method
switch($this->paymentMethod) {
case 'SU' :
$this->sofort->setSofortueberweisung($amount);
// see if customer protection is enabled, set it as parameter to sofortlib
// 2018-01-29: feature disabled, Customer Protection is no longer available in this module
$this->sofort->setSofortueberweisungCustomerprotection(false);
break;
case 'SL' :
$this->sofort->setSofortlastschrift();
$this->sofort->setSenderAccount(
'',
'',
HelperFunctions::convertEncoding($order->billing['firstname'],3) . ' ' . HelperFunctions::convertEncoding($order->billing['lastname'],3)
);
break;
case 'LS' :
$this->sofort->setLastschrift();
$this->sofort->setSenderAccount(
HelperFunctions::convertEncoding($_SESSION['sofort']['ls_bank_code'],3),
HelperFunctions::convertEncoding($_SESSION['sofort']['ls_account_number'],3),
HelperFunctions::convertEncoding($_SESSION['sofort']['ls_sender_holder'],3)
);
$billingSalutation = $this->_getGenderFromAddressBook(
$order->billing['firstname'],
$order->billing['lastname'],
$order->billing['company'],
$order->billing['street_address'],
$order->billing['postcode'],
$order->billing['city'],
$order->billing['country_id'],
$order->billing['zone_id']
);
//split street and number
if (!preg_match('#(.+)[ .](.+)#i', trim($order->billing['street_address']), $streetparts)) {
$streetparts = array();
$streetparts[1] = trim($order->billing['street_address']);
$streetparts[2] = '';
}
//currently $order->billing['suburb'] (german: "Adresszusatz") is not supported by sofortLib
$this->sofort->setLastschriftAddress(
HelperFunctions::convertEncoding($order->billing['firstname'],3),
HelperFunctions::convertEncoding($order->billing['lastname'],3),
HelperFunctions::convertEncoding($streetparts[1],3),
HelperFunctions::convertEncoding($streetparts[2],3),
HelperFunctions::convertEncoding($order->billing['postcode'],3),
HelperFunctions::convertEncoding($order->billing['city'],3),
HelperFunctions::convertEncoding($billingSalutation,3),
HelperFunctions::convertEncoding($order->billing['country']['iso_code_2'],3)
);
break;
case 'SV' :
$this->sofort->setSofortvorkasse();
// if this is called a 'test transaction', add a sender account
if (getenv('test_sv') == true) $this->sofort->setSenderAccount('00000', '12345', 'Tester Testaccount');
//notice: customer-protection with SV is currently not supported and not shown to seller for activation
//@see function keys()
$this->sofort->setSofortvorkasseCustomerprotection(MODULE_PAYMENT_SOFORT_SV_KS_STATUS == 'True');
break;
}
//send all data against the SOFORT-API
$this->sofort->sendRequest();
if ($this->sofort->isError()) {
$this->sofort->logWarning("API-Call returned false. Redirect to cancel-URL. API-Errors: ".print_r($this->sofort->getErrors(), true)." Time: ".date("d.m.Y, G:i:s"));
xtc_redirect(HelperFunctions::getCancelUrl($this->code, $this->sofort->getErrors()));
} else {
$url = $this->sofort->getPaymentUrl();
$transactionId = $this->sofort->getTransactionId();
//seller and customer comment
$time = date("d.m.Y, G:i:s");
//set temp-status (only table orders_history, not table orders)
$tmpStatusId = MODULE_PAYMENT_SOFORT_MULTIPAY_TEMP_STATUS_ID;
//dont set a new status? -> then use the last order status
if (HelperFunctions::statusIsUnchangedStatus($tmpStatusId)) $tmpStatusId = HelperFunctions::getLastOrderStatus($orderId);
$tmpStatusId = HelperFunctions::checkStatusId($tmpStatusId);
//comment only for buyer and seller
$tmpComment = constant('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TMP_COMMENT').' '.MODULE_PAYMENT_SOFORT_TRANSLATE_TIME.': '.$time;
HelperFunctions::insertHistoryEntry((int) $orderId, $tmpStatusId, $tmpComment);
//comment only for seller
$tmpCommentSeller = constant('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TMP_COMMENT_SELLER').' '.MODULE_PAYMENT_SOFORT_TRANSLATE_TIME.': '.$time;
HelperFunctions::insertHistoryEntry((int) $orderId, -1, $tmpCommentSeller, 0);
xtc_db_query("UPDATE ".HelperFunctions::escapeSql(TABLE_ORDERS)." SET orders_ident_key='".HelperFunctions::escapeSql($transactionId)."' WHERE orders_id='".HelperFunctions::escapeSql($orderId)."'");
//save all important data in our sofort-tables
$sofortOrderId = HelperFunctions::insertSofortOrder($orderId, $paymentSecret, $transactionId, $this->paymentMethod);
if (!$sofortOrderId) $this->sofort->logWarning("Warning: Saving of orderdetails in table sofort_orders failed. Function insertSofortOrder() returned false.Given params: OrderId: $orderId, PaymentSecret: $paymentSecret, TransId: $transactionId, PaymentMethod:".$this->paymentMethod);
$_SESSION['sofort']['sofort_payment_url'] = $url;
$_SESSION['sofort']['sofort_payment_method'] = $this->code;
//following file will always redirect to SOFORT-Wizard
xtc_redirect(xtc_href_link('callback/sofort/ressources/scripts/processSofortPayment.php', '', 'SSL', true, false));
}
}
/**
* called by core after successful payment
* overwritten by SV
*/
function after_process() {
global $insert_id;
//unset all sofort-session-vars for all payment-methods
if (isset($_SESSION['sofort']['sofort_conditions_sr'])) unset($_SESSION['sofort']['sofort_conditions_sr']);
if (isset($_SESSION['sofort']['sofort_conditions_sv'])) unset($_SESSION['sofort']['sofort_conditions_sv']);
if (isset($_SESSION['sofort']['sofort_conditions_ls'])) unset($_SESSION['sofort']['sofort_conditions_ls']);
if (isset($_SESSION['sofort']['ls_sender_holder'])) unset($_SESSION['sofort']['ls_sender_holder']);
if (isset($_SESSION['sofort']['ls_account_number'])) unset($_SESSION['sofort']['ls_account_number']);
if (isset($_SESSION['sofort']['ls_bank_code'])) unset($_SESSION['sofort']['ls_bank_code']);
if (isset($_SESSION['sofort']['cart_pn_sofortueberweisung_id'])) unset($_SESSION['sofort']['cart_pn_sofortueberweisung_id']);
//we dont want to wait until first(!) notification comes: we will set the first status and comments like
//the callback would do
//but if the buyer will close the wizard after successful payment, this code here will never be
//called: in this case, the callback will set the correct status
//Notice: sometimes the notification is faster than the call of the success-URL!
$this->_insertPaidStatus();
return true;
}
/**
* check if there is an error with this paymentMethod - called in checkout_payment.php
* @return array with title and description of the found error(s)
*/
function get_error () {
$this->_checkCancelOrder();
if (!isset($_GET['payment_error']) || $_GET['payment_error'] != $this->code) return false;
//there is an error with this paymentMethod...
$this->enabled = false;
$errormsgArray = array();
if (isset($_GET['error_codes'])) {
$langConstantExist = true;
$errorCodes = array_unique (explode(',', $_GET['error_codes']));
foreach ($errorCodes as $errorCode) {
$errorCode = trim($errorCode);
$code = substr($errorCode, 0, strpos($errorCode, '.'));
if ($code === false || empty($code)) $code = $errorCode;
if (defined ('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . strtoupper($errorCode) ) ) {
$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.strtoupper($errorCode) ).' ('.$code.')';
} else if (defined('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_' . $code) ) {
$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.strtoupper($code)).' ('.$code.')';
} else {
$langConstantExist = false;
}
//show this paymentMethod again to buyer with the following error-codes
$dontDisableCodes = array('10000', '10001', '10002');
if(in_array($code, $dontDisableCodes)) $this->enabled = true;
}
if (!$errormsgArray && $langConstantExist == false) $errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.$this->paymentMethod);
} else {
$errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_TEXT_ERROR_MESSAGE');
}
if (!$errormsgArray) $errormsgArray[] = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_'.$this->paymentMethod);
$errormsgArray = array_unique($errormsgArray);
$title = MODULE_PAYMENT_SOFORT_MULTIPAY_TEXT_ERROR_HEADING;
return array(
'title' => $title,
'error' => implode(', ', $errormsgArray)
);
}
/**
* Module is installed?
*/
function check() {
if (!isset($this->_check)) {
$constantName = 'MODULE_PAYMENT_SOFORT_'.$this->paymentMethod.'_STATUS';
$check_query = xtc_db_query("SELECT configuration_value FROM " . HelperFunctions::escapeSql(TABLE_CONFIGURATION) . " WHERE configuration_key = '".HelperFunctions::escapeSql($constantName)."'");
$this->_check = xtc_db_num_rows($check_query);
}
if ($this->_check) {
$this->_installSofortOrdersTable();
$this->_installSofortOrdersNotificationTable();
$this->_installSofortProductsTable();
}
return $this->_check;
}
/**
* install shared keys, that are used by all/most multipay-modules
* called by module with parent::install();
*/
function install() {
//following defined constants are global(!) - that means, they are set only once and are used by most/all payment-methods
if(!defined('MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY')) {
$sofortStatuses = $this->_insertAndReturnSofortStatus();
$tempStatus = (isset($sofortStatuses['temp'])&& !empty($sofortStatuses['temp']))? $sofortStatuses['temp'] : '';
$abortedStatus = (isset($sofortStatuses['aborted'])&& !empty($sofortStatuses['aborted']))? $sofortStatuses['aborted'] : '';
$unchangedStatus = (isset($sofortStatuses['unchanged'])&& !empty($sofortStatuses['unchanged']))? $sofortStatuses['unchanged'] : '';
//$checkStatus = (isset($sofortStatuses['check'])&& !empty($sofortStatuses['check']))? $sofortStatuses['check'] : '';
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY', '', '6', '2', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_AUTH', '".MODULE_PAYMENT_SOFORT_KEYTEST_DEFAULT."', '6', '3', 'xtc_cfg_select_option(array(),', now())"); //hide the input-field with an empty <select>
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_1', '-TRANSACTION-', '6', '8', 'xtc_cfg_select_option(array(\'Kd-Nr. {{customer_id}}\',\'-TRANSACTION-\'), ', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_2', '" . HelperFunctions::escapeSql(STORE_NAME) . "', '6', '9', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_IMAGE', 'Infographic', '6', '7', 'xtc_cfg_select_option(array(\'Infographic\',\'Logo & Text\'), ', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_PROF_SETTINGS', '', '6', '20', 'xtc_cfg_select_option(array(),', now())"); //hide the input-field with an empty <select>
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, use_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_TEMP_STATUS_ID', '".HelperFunctions::escapeSql($tempStatus)."', '6', '35', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, use_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_ABORTED_STATUS_ID', '".HelperFunctions::escapeSql($abortedStatus)."', '6', '35', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, set_function, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_LOG_ENABLED', 'False', '6', '28', 'xtc_cfg_select_option(array(\'True\', \'False\'), ', now())");
//only used while setting status - unchangeable and not shown in module-configuration
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_UNCHANGED_STATUS_ID', '".HelperFunctions::escapeSql($unchangedStatus)."', '6', '35', now())");
$moduleVersion = HelperFunctions::getSofortmodulVersion();
xtc_db_query("INSERT INTO ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." ( configuration_key, configuration_value, configuration_group_id, sort_order, date_added)
VALUES ('MODULE_PAYMENT_SOFORT_MULTIPAY_MODULE_VERSION', '".HelperFunctions::escapeSql($moduleVersion)."', '6', '2', now())");
$this->_installSofortOrdersTable();
$this->_installSofortOrdersNotificationTable();
$this->_installSofortProductsTable();
}
return true;
}
/**
* if this is the last removing of a multipay-paymentmethod --> we also remove all shared keys, that are used by all/most multipay-modules
* called by module with parent::remove()
*/
function remove() {
$check_query = xtc_db_query("SELECT * FROM ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." WHERE configuration_key like 'MODULE_PAYMENT_SOFORT_%_STATUS' AND configuration_key NOT LIKE '%_IDEAL_%'");
if (xtc_db_num_rows ($check_query) === 0 ) {
xtc_db_query("DELETE FROM ".HelperFunctions::escapeSql(TABLE_CONFIGURATION)." WHERE configuration_key LIKE 'MODULE_PAYMENT_SOFORT_%' AND configuration_key NOT LIKE '%_IDEAL_%'");
//We don't want to delete data, but we could in some cases...
//Notice: callback.php may throw warnings/errors, if they doesnt exist (in case of later notification)
//$this->_removeSofortOrdersTable();
//$this->_removeSofortOrdersNotificationTable();
//$this->_removeSofortProductsTable();
}
return true;
}
function keys() {
//unset, important for admin
if (isset($_SESSION['sofort']['apiKeyIsValid'])) unset($_SESSION['sofort']['apiKeyIsValid']);
}
function _getGenderFromAddressBook($firstname, $lastname, $company, $streetAddress, $postcode, $city, $countryId, $zoneId) {
$query = 'SELECT entry_gender
FROM '.HelperFunctions::escapeSql(TABLE_ADDRESS_BOOK).'
WHERE entry_firstname = "'.HelperFunctions::escapeSql($firstname).'"
AND entry_lastname = "'.HelperFunctions::escapeSql($lastname).'"
AND entry_company = "'.HelperFunctions::escapeSql($company).'"
AND entry_street_address = "'.HelperFunctions::escapeSql($streetAddress).'"
AND entry_postcode = "'.HelperFunctions::escapeSql($postcode).'"
AND entry_city = "'.HelperFunctions::escapeSql($city).'"
AND entry_country_id = "'.HelperFunctions::escapeSql($countryId).'"
AND entry_zone_id = "'.HelperFunctions::escapeSql($zoneId).'" LIMIT 1';
$sqlResult = xtc_db_query($query);
$result = xtc_db_fetch_array($sqlResult);
switch ($result['entry_gender']) {
case 'm': $salutation = 2; break;
case 'f': $salutation = 3; break;
default: $salutation = ''; break;
}
return $salutation;
}
/**
* check if order has temp-Status and buyer didnt finish the payment-process by "normal" way
* @return bool true (always)
*/
function _checkCancelOrder() {
if (!empty($_SESSION['sofort']['cart_pn_sofortueberweisung_id'])) {
$orderId = substr($_SESSION['sofort']['cart_pn_sofortueberweisung_id'], strpos($_SESSION['sofort']['cart_pn_sofortueberweisung_id'], '-') + 1);
$cartID = substr($_SESSION['sofort']['cart_pn_sofortueberweisung_id'], 0, strlen($_SESSION['cart']->cartID));
$checkQuery = xtc_db_query("SELECT orders_status FROM ".HelperFunctions::escapeSql(TABLE_ORDERS)." WHERE orders_id = '".(int) $orderId."' AND payment_method LIKE 'sofort_%'");
$result = xtc_db_fetch_array($checkQuery);
$tempStatus = MODULE_PAYMENT_SOFORT_MULTIPAY_TEMP_STATUS_ID;
if (HelperFunctions::statusIsUnchangedStatus($tempStatus)) {
if (is_object($this->sofort)) {
$this->sofort->logWarning("Warning: 'Temporary'-Status is set to 'Unchanged'-status. Don't use this status here and change in modulsettings! Check for 'abort'-status for this order could not be processed. Check order! Order-ID: $orderId");
} elseif (is_object($this->invoice)) {
$this->invoice->logWarning("Warning: 'Temporary'-Status is set to 'Unchanged'-status. Don't use this status here and change in modulsettings! Check for 'abort'-status for this order could not be processed. Check order! Order-ID: $orderId");
}
return true;
}
if ((($result['orders_status'] == $tempStatus) || $_SESSION['cart']->cartID != $cartID)) {
unset($_SESSION['sofort']['cart_pn_sofortueberweisung_id']);
if (isset($_SESSION['tmp_oID'])) unset($_SESSION['tmp_oID']);
$this->_cancelOrder( (int) $orderId, 'on');
}
}
return true;
}
/**
* Check, if needed sofort-lang-constants exists.
* If not, include the english-lang-file(s).
* @return always true
*/
function _checkExistingSofortConstants($paymentMethod) {
$paymentMethod = strtoupper($paymentMethod);
$allowedPaymentMethods = array('SU', 'SL', 'LS', 'SR', 'SV');
$coo_lang_file_master = MainFactory::create_object('LanguageTextManager', array(), true);
if(!in_array($paymentMethod, $allowedPaymentMethods)) return true;
//security check - constant exists if lang-file exists
if(defined('MODULE_PAYMENT_SOFORT_'.$paymentMethod.'_TEXT_TITLE')) return true;
$installedModulLangs = array();
$lngdir = DIR_FS_CATALOG.'lang/';
foreach (new DirectoryIterator($lngdir) as $file) {
if ($file->isDir() && file_exists($lngdir.$file->getFilename().'/modules/payment/sofort_general.php')) {
$installedModulLangs[] = $file->getFilename();
}
}
//currently installed in this module
if(!in_array($_SESSION['language'], $installedModulLangs)) {
switch ($paymentMethod) {
case 'SU': $coo_lang_file_master->init_from_lang_file('lang/english/modules/payment/sofort_sofortueberweisung.php'); break;
case 'SV': $coo_lang_file_master->init_from_lang_file('lang/english/modules/payment/sofort_sofortvorkasse.php'); break;
case 'SL': $coo_lang_file_master->init_from_lang_file('lang/english/modules/payment/sofort_sofortlastschrift.php'); break;
case 'LS': $coo_lang_file_master->init_from_lang_file('lang/english/modules/payment/sofort_lastschrift.php'); break;
case 'SR': $coo_lang_file_master->init_from_lang_file('lang/english/modules/payment/sofort_sofortrechnung.php'); break;
default:
}
}
return true;
}
/**
* Insert all SOFORT-Status into table orders_status and return them
* @return array with all status
*/
function _insertAndReturnSofortStatus() {
require_once('sofortInstall.php');
//SOFORT-langs in this module
$sofortLangs = array('GERMAN', 'ENGLISH', 'POLISH', 'DUTCH', 'FRENCH', 'ITALIAN');
//current installed langs
$installedLangs = array();
$orderQuery = xtc_db_query("SELECT languages_id, directory FROM " . HelperFunctions::escapeSql(TABLE_LANGUAGES));
while ($result = xtc_db_fetch_array($orderQuery)) $installedLangs[$result['languages_id']] = strtoupper($result['directory']);
//get the current highest orders_status_id
$orderQuery = xtc_db_query("SELECT MAX(orders_status_id) AS max_orders_status_id FROM orders_status");
$maxOrdersStatusIdTemp = xtc_db_fetch_array($orderQuery);
$ordersStatusIdTemp = $maxOrdersStatusIdTemp['max_orders_status_id'] + 1;
$ordersStatusIdConfirmed = $ordersStatusIdTemp + 1;
$ordersStatusIdCanceled = $ordersStatusIdConfirmed + 1;
$ordersStatusIdCheck = $ordersStatusIdCanceled + 1;
$ordersStatusIdUnconfirmed = $ordersStatusIdCheck + 1;
$ordersStatusIdInvoiceConfirmed = $ordersStatusIdUnconfirmed + 1;
$ordersStatusIdSvUnpaid = $ordersStatusIdInvoiceConfirmed + 1;
$ordersStatusIdAborted = $ordersStatusIdSvUnpaid + 1;
$ordersStatusIdReturnedDebit = $ordersStatusIdAborted + 1;
$ordersStatusIdRefunded = $ordersStatusIdReturnedDebit + 1;
$ordersStatusIdDirectDebit = $ordersStatusIdRefunded + 1;
$ordersStatusIdSvPaid = $ordersStatusIdDirectDebit + 1;
$ordersStatusIdTranslateConfirmed = $ordersStatusIdSvPaid + 1;
$ordersStatusIdUnchanged = $ordersStatusIdTranslateConfirmed + 1;
$sofortStatuses = array();
foreach($installedLangs as $installedLang) {
//insert english for shop-languages, which are not included in this module
if(in_array($installedLang, $sofortLangs)) {
$sofortLang = $installedLang;
$langId = array_search($sofortLang, $installedLangs);
} else {
$sofortLang = 'ENGLISH';
$langId = array_search($installedLang, $installedLangs);
}
//insert temp-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('temp', $sofortLang);
$sofortStatuses['temp'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['temp'] === false || $sofortStatuses['temp'] == '') $sofortStatuses['temp'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdTemp, $langId);
//insert sv-unpaid-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('sv_unpaid', $sofortLang);
$sofortStatuses['sv_unpaid'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['sv_unpaid'] === false || $sofortStatuses['sv_unpaid'] == '') $sofortStatuses['sv_unpaid'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdSvUnpaid, $langId);
//insert sv-paid-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('sv_paid', $sofortLang);
$sofortStatuses['sv_paid'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['sv_paid'] === false || $sofortStatuses['sv_paid'] == '') $sofortStatuses['sv_paid'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdSvPaid, $langId);
//insert confirmed-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('confirmed', $sofortLang);
$sofortStatuses['confirmed'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['confirmed'] === false || $sofortStatuses['confirmed'] == '') $sofortStatuses['confirmed'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdConfirmed, $langId);
//insert translate_confirmed-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('translate_confirmed', $sofortLang);
$sofortStatuses['translate_confirmed'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['translate_confirmed'] === false || $sofortStatuses['translate_confirmed'] == '') $sofortStatuses['translate_confirmed'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdTranslateConfirmed, $langId);
//insert canceled-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('canceled', $sofortLang);
$sofortStatuses['canceled'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['canceled'] === false || $sofortStatuses['canceled'] == '') $sofortStatuses['canceled'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdCanceled, $langId);
//insert aborted-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('aborted', $sofortLang);
$sofortStatuses['aborted'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['aborted'] === false || $sofortStatuses['aborted'] == '') $sofortStatuses['aborted'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdAborted, $langId);
//insert check-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('check', $sofortLang);
$sofortStatuses['check'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['check'] === false || $sofortStatuses['check'] == '') $sofortStatuses['check'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdCheck, $langId);
//insert unconfirmed-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('unconfirmed', $sofortLang);
$sofortStatuses['unconfirmed'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['unconfirmed'] === false || $sofortStatuses['unconfirmed'] == '') $sofortStatuses['unconfirmed'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdUnconfirmed, $langId);
//insert invoice-confirmed-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('invoice_confirmed', $sofortLang);
$sofortStatuses['invoice_confirmed'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['invoice_confirmed'] === false || $sofortStatuses['invoice_confirmed'] == '') $sofortStatuses['invoice_confirmed'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdInvoiceConfirmed, $langId);
//insert returned-debit-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('returned_debit', $sofortLang);
$sofortStatuses['returned_debit'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['returned_debit'] === false || $sofortStatuses['returned_debit'] == '') $sofortStatuses['returned_debit'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdReturnedDebit, $langId);
//insert refunded-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('refunded', $sofortLang);
$sofortStatuses['refunded'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['refunded'] === false || $sofortStatuses['refunded'] == '') $sofortStatuses['refunded'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdRefunded, $langId);
//insert direct-debit-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('direct_debit', $sofortLang);
$sofortStatuses['direct_debit'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['direct_debit'] === false || $sofortStatuses['direct_debit'] == '') $sofortStatuses['direct_debit'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdDirectDebit, $langId);
//insert unchanged-Status if not exists
$newOrdersStatusName = $this->_getNewOrdersStatusName('unchanged', $sofortLang);
$sofortStatuses['unchanged'] = $this->_getStatusIdIfExistInDb($newOrdersStatusName, $langId);
if($sofortStatuses['unchanged'] === false || $sofortStatuses['unchanged'] == '') $sofortStatuses['unchanged'] = $this->_insertStatusInDb($newOrdersStatusName, $ordersStatusIdUnchanged, $langId);
}
return $sofortStatuses;
}
function _getStatusIdIfExistInDb($newOrdersStatusName, $langId) {
if(!$newOrdersStatusName) return false;
$checkQuery = xtc_db_query('SELECT orders_status_id
FROM orders_status
WHERE language_id = "'.HelperFunctions::escapeSql($langId).'"
AND orders_status_name = "'.HelperFunctions::escapeSql($newOrdersStatusName).'"
LIMIT 1');
if (xtc_db_num_rows($checkQuery) < 1) {
return false;
} else {
$neededOrdersStatusId = xtc_db_fetch_array($checkQuery);
return $neededOrdersStatusId['orders_status_id'];
}
}
/**
* insert given statusstring into DB - empty strings will not be inserted
* @return $orders_status_id from DB OR false
*/
function _insertStatusInDb($newOrdersStatusName, $ordersStatusId, $langId) {
if (!$newOrdersStatusName) return false;
xtc_db_query("INSERT INTO orders_status (orders_status_id, language_id, orders_status_name)
values ('".HelperFunctions::escapeSql($ordersStatusId)."', '".HelperFunctions::escapeSql($langId)."', '".HelperFunctions::escapeSql($newOrdersStatusName)."')");
return $ordersStatusId;
}
/**
* returns the statusname for the given $status and $lang
* return max the first 32 chars! (because db-field = varchar(32) )
*/
function _getNewOrdersStatusName($status, $lang) {
switch ($status) {
case 'temp': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_TEMP_'.$lang); break;
case 'sv_unpaid': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_SV_UNPAID_'.$lang); break;
case 'sv_paid': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_SV_PAID_'.$lang); break;
case 'confirmed': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CONFIRMED_'.$lang); break;
case 'translate_confirmed': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CONFIRMED_2_'.$lang); break;
case 'invoice_confirmed': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_INVOICE_CONFIRMED_'.$lang); break;
case 'unconfirmed': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_UNCONFIRMED_'.$lang); break;
case 'canceled': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CANCELED_'.$lang); break;
case 'aborted': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_ABORTED_'.$lang); break;
case 'check': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_CHECK_'.$lang); break;
case 'returned_debit': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_RETURNED_DEBIT_'.$lang); break;
case 'refunded': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_REFUNDED_'.$lang); break;
case 'direct_debit': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_DIRECT_DEBIT_'.$lang); break;
case 'unchanged': $newOrdersStatusName = constant('MODULE_PAYMENT_SOFORT_MULTIPAY_STATE_UNCHANGED_'.$lang); break;
}
// if string is not cut to 32 chars, status will be reinserted with every installation
$newOrdersStatusName = substr($newOrdersStatusName, 0, 32);
return $newOrdersStatusName;
}
function _installSofortOrdersTable() {
$sql = '
CREATE TABLE IF NOT EXISTS `sofort_orders` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`orders_id` int(11) unsigned NOT NULL,
`transaction_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`payment_method` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`payment_secret` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
';
xtc_db_query($sql);
}
function _removeSofortOrdersTable() {
$sql = 'DROP TABLE `sofort_orders`';
xtc_db_query($sql);
}
function _installSofortOrdersNotificationTable() {
$sql = '
CREATE TABLE IF NOT EXISTS `sofort_orders_notification` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sofort_orders_id` int(11) unsigned NOT NULL,
`items` text COLLATE utf8_unicode_ci NOT NULL,
`amount` float NOT NULL,
`customer_comment` text COLLATE utf8_unicode_ci NOT NULL,
`seller_comment` text COLLATE utf8_unicode_ci NOT NULL,
`status_id` int(11) unsigned NOT NULL,
`status` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`status_reason` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`invoice_status` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`invoice_objection` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
';
xtc_db_query($sql);
}
function _removeSofortOrdersNotificationTable() {
$sql = 'DROP TABLE `sofort_orders_notification`';
xtc_db_query($sql);
}
function _installSofortProductsTable() {
$sql = '
CREATE TABLE IF NOT EXISTS `sofort_products` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`orders_id` int(11) unsigned NOT NULL,
`orders_products_id` int(11) unsigned NOT NULL,
`item_id` text COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
';
xtc_db_query($sql);
}
function _removeSofortProductsTable() {
$sql = 'DROP TABLE `sofort_products`';
xtc_db_query($sql);
}
/**
* get shop order total
* @return float $shopEndprice
*/
function _getShopTotal($orderTotals, $order) {
//Frequent sources of errors: shipping-tax, external modules, sort order of shown 'ot_'-modules
$ot_totalTotal = 0;
if (MODULE_ORDER_TOTAL_INSTALLED)
foreach ($orderTotals as $oneTotal)
if ($oneTotal['code'] == 'ot_total') $ot_totalTotal = $oneTotal['value'];
$orderObjectTotal = 0;
$orderObjectTotal = ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1) ? $order->info['total'] + $order->info['tax'] : $order->info['total'];
//use the higher one
$shopTotal = 0;
if ($ot_totalTotal >= $orderObjectTotal) {
$shopTotal = $ot_totalTotal;
} else if ($orderObjectTotal > $ot_totalTotal) {
$shopTotal = $orderObjectTotal;
}
$shopTotal = number_format($shopTotal, 2, '.','');
return $shopTotal;
}
/**
* transcribes or removes unallowed characters from a reason line
* @param string $reason original reason line
* @return string cleaned reason
*/
function _convertReason($reason)
{
$shopEncoding = 'UTF-8';
$targetLocale = 'de_DE.utf8';
$oldLocale = setlocale(LC_ALL, '0');
$convertedReason = '';
if (setlocale(LC_ALL, $targetLocale) !== false) {
$convertedReason = substr(iconv($shopEncoding, "ASCII//TRANSLIT", 'aaa'.$reason),3);
}
setlocale(LC_ALL, $oldLocale);
if (empty($convertedReason)) {
$convertedReason = $this->cleanReason($reason);
}
return $convertedReason;
}
function cleanReason($reason)
{
$replacements = [
'ä' => 'ae',
'Ä' => 'Ae',
'ö' => 'oe',
'Ö' => 'Oe',
'ü' => 'ue',
'Ü' => 'Ue',
'ß' => 'ss',
];
$reason = strtr($reason, $replacements);
$reason = preg_replace('/[^a-zA-Z0-9 +,-.]/', '', $reason);
return $reason;
}
/**
* get the reasons for the given payment method
* @return array with reason1 and reason2
*/
function _getReasons($paymentMethod, $customerId, $order, $orderId) {
if ($paymentMethod == 'SV') { //SV has only one reason
$reason_1 = str_replace('{{order_id}}', $orderId, MODULE_PAYMENT_SOFORT_SV_REASON_2);
$reason_1 = str_replace('{{customer_id}}', $customerId, $reason_1);
$reason_1 = str_replace('{{transaction_id}}', '-TRANSACTION-', $reason_1);
$reason_1 = $this->_convertReason($reason_1);
$reason_1 = substr($reason_1, 0, 27);
$reason_2 = ''; //SV has only one reason, the 2nd is set by SOFORT
} else {
$reason_1 = str_replace('{{order_id}}', $orderId, MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_1);
$reason_1 = str_replace('{{customer_id}}', $customerId, $reason_1);
$reason_1 = str_replace('{{transaction_id}}', '-TRANSACTION-', $reason_1);
$reason_1 = $this->_convertReason($reason_1);
$reason_1 = substr($reason_1, 0, 27);
$reason_2 = str_replace('{{order_id}}', $orderId, MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_2);
$reason_2 = str_replace('{{customer_id}}', $customerId, $reason_2);
$reason_2 = str_replace('{{order_date}}', strftime(DATE_FORMAT_SHORT), $reason_2);
$reason_2 = str_replace('{{customer_name}}', $order->customer['firstname'] . ' ' . $order->customer['lastname'], $reason_2);
$reason_2 = str_replace('{{customer_company}}', $order->customer['company'], $reason_2);
$reason_2 = str_replace('{{customer_email}}', $order->customer['email_address'], $reason_2);
$reason_2 = str_replace('{{transaction_id}}', '-TRANSACTION-', $reason_2);
$reason_2 = $this->_convertReason($reason_2);
$reason_2 = substr($reason_2, 0, 27);
}
$reasons = array();
$reasons[0] = $reason_1;
$reasons[1] = $reason_2;
return $reasons;
}
/**
* delete all data of this buying-proccess - currently only needed for SV;
* this function must be compatible with xtc3, modified-shop, comSeo and gam!
* @see /path/to/root/checkout_process.php -> code after: "$payment_module->after_process();"
* @return bool true (always)
*/
function _resetCartAndDeleteSessionData() {
global $order_total_modules, $insert_id;
$_SESSION['cart']->reset(true);
if (isset($_SESSION['sendto'])) unset ($_SESSION['sendto']);
if (isset($_SESSION['billto'])) unset ($_SESSION['billto']);
if (isset($_SESSION['shipping'])) unset ($_SESSION['shipping']);
if (isset($_SESSION['payment'])) unset ($_SESSION['payment']);
if (isset($_SESSION['comments'])) unset ($_SESSION['comments']);
if (isset($_SESSION['last_order'])) unset ($_SESSION['last_order']);
if (isset($_SESSION['tmp_oID'])) unset ($_SESSION['tmp_oID']);
if (isset($_SESSION['cc'])) unset ($_SESSION['cc']);
if (isset($_SESSION['cc_id'])) unset ($_SESSION['cc_id']);
if (isset ($_SESSION['credit_covers'])) unset ($_SESSION['credit_covers']);
$last_order = $insert_id; //maybe needed in file-includes or function-calls below
//GV Code Start
if (isset ($_SESSION['credit_covers']))
unset ($_SESSION['credit_covers']);
if (is_object($order_total_modules)) {
$order_total_modules->clear_posts(); //ICW ADDED FOR CREDIT CLASS SYSTEM
}
// GV Code End
//modified eCommerce Shopsoftware + Gambio Start
if(@isset($_SESSION['xtb0'])) {
define('XTB_CHECKOUT_PROCESS', __LINE__);
require_once (DIR_FS_CATALOG.'callback/xtbooster/xtbcallback.php');
}
//modified eCommerce Shopsoftware End
//Gambio Start
// BOF GM_MOD GX-Customizer:
if (file_exists(DIR_FS_CATALOG.'gm/modules/gm_gprint_checkout_process.php')) {
require(DIR_FS_CATALOG . 'gm/modules/gm_gprint_checkout_process.php');
}
//Gambio End
return true;
}
/**
* @see xtc_remove_order() in admin/includes/functions/general.php
* @param bool $restock - only allowed is: FALSE or 'on'
*/
function _cancelOrder($orderId, $restock = false) {
//only Gambio
if (HelperFunctions::isGambio()) {
$this->_gambio_remove_order($orderId, $restock, true, $restock);
//only xtc3, comSeo
} else {
if ($restock == 'on') {
//following code is (nearly 100%) copy&paste from function xtc_remove_order() - there is no other way for stock-update :-|
//compatible and checked with xtc3_sp2 and comseo_2.0 and comseo_2.1
$order_query = xtc_db_query("
SELECT orders_products_id, products_id, products_quantity
FROM ".TABLE_ORDERS_PRODUCTS."
WHERE orders_id = '".xtc_db_input($orderId)."'");
while ($order = xtc_db_fetch_array($order_query)) {
xtc_db_query("
UPDATE ".TABLE_PRODUCTS."
SET products_quantity = products_quantity + ".(int)$order['products_quantity'].", products_ordered = products_ordered - ".(int)$order['products_quantity']."
WHERE products_id = '".(int)$order['products_id']."'");
//only comSeo, not xtc3
if (function_exists('nc_get_products_attributes_id')) {
$result = mysqli_query($GLOBALS["___mysqli_ston"], '
SELECT *
FROM orders_products_attributes
WHERE orders_id = "'.(int)$orderId.'"
AND orders_products_id = "'.HelperFunctions::escapeSql($order['orders_products_id']).'"');
while(($row = mysqli_fetch_array($result) )) {
$attributes_id = nc_get_products_attributes_id($order['products_id'], $row['products_options'], $row['products_options_values']);
mysqli_query($GLOBALS["___mysqli_ston"], '
UPDATE products_attributes
SET attributes_stock = attributes_stock + '.(int)$order['products_quantity'].'
WHERE products_attributes_id = "'.(int)$attributes_id.'"');
//echo mysql_error(); //buyer ist not allowed to see this
}
}
}
}
}
//update status and customer-history
$time = date("d.m.Y, G:i:s");
xtc_db_query('UPDATE orders SET orders_status = "'.HelperFunctions::escapeSql(MODULE_PAYMENT_SOFORT_MULTIPAY_ABORTED_STATUS_ID).'", last_modified = now() WHERE orders_id = '.HelperFunctions::escapeSql($orderId));
HelperFunctions::insertHistoryEntry((int) $orderId, MODULE_PAYMENT_SOFORT_MULTIPAY_ABORTED_STATUS_ID, MODULE_PAYMENT_SOFORT_MULTIPAY_ORDER_CANCELED, '', $time);
}
/**
* copy of function xtc_remove_order() in /admin/includes/functions/general.php - Gambioversion: GX2.0.10g - no direct access possible/useful
* @param int $orderId
* @param $restock
* @param bool $canceled - set to FALSE (default) will delete orderinformation completly from the DB!
* @param $reshipp
* @see xtc_remove_order() in gambio-admin-folder
*/
function _gambio_remove_order($order_id, $restock = false, $canceled = false, $reshipp = false) {
//following code is NOT formatted for better comparison in case of future changes!
if ($restock == 'on' || $reshipp == 'on')
{
// BOF GM_MOD:
$order_query = xtc_db_query("
SELECT DISTINCT
op.orders_products_id,
op.products_id,
op.products_quantity,
opp.products_properties_combis_id,
o.date_purchased
FROM ".TABLE_ORDERS_PRODUCTS." op
LEFT JOIN ".TABLE_ORDERS." o ON op.orders_id = o.orders_id
LEFT JOIN orders_products_properties opp ON opp.orders_products_id = op.orders_products_id
WHERE
op.orders_id = '" . xtc_db_input($order_id) . "'
");
while ($order = xtc_db_fetch_array($order_query))
{
if($restock == 'on') {
/* BOF SPECIALS RESTOCK */
$t_query = xtc_db_query("
SELECT
specials_date_added
AS
date
FROM " .
TABLE_SPECIALS . "
WHERE
specials_date_added < '" . HelperFunctions::escapeSql($order['date_purchased']) . "'
AND
products_id = '" . HelperFunctions::escapeSql($order['products_id']) . "'
");
if((int)xtc_db_num_rows($t_query) > 0)
{
xtc_db_query("
UPDATE " .
TABLE_SPECIALS . "
SET
specials_quantity = specials_quantity + " . (int)$order['products_quantity'] . "
WHERE
products_id = '" . (int)$order['products_id'] . "'
");
}
/* EOF SPECIALS RESTOCK */
// check if combis exists
$t_combis_query = xtc_db_query("
SELECT
products_properties_combis_id
FROM
products_properties_combis
WHERE
products_id = '" . HelperFunctions::escapeSql($order['products_id']) . "'
");
$t_combis_array_length = xtc_db_num_rows($t_combis_query);
if($t_combis_array_length > 0){
$coo_combis_admin_control = MainFactory::create_object("PropertiesCombisAdminControl");
$t_use_combis_quantity = $coo_combis_admin_control->get_use_properties_combis_quantity($order['products_id']);
}else{
$t_use_combis_quantity = 0;
}
if($t_combis_array_length == 0 || ($t_combis_array_length > 0 && $t_use_combis_quantity == 1)){
xtc_db_query("
UPDATE " .
TABLE_PRODUCTS . "
SET
products_quantity = products_quantity + ".(int)$order['products_quantity']."
WHERE
products_id = '".(int)$order['products_id']."'
");
}
xtc_db_query("
UPDATE " .
TABLE_PRODUCTS . "
SET
products_ordered = products_ordered - ".(int)$order['products_quantity']."
WHERE
products_id = '".(int)$order['products_id']."'
");
if($t_combis_array_length > 0 && (($t_use_combis_quantity == 0 && STOCK_CHECK == 'true' && ATTRIBUTE_STOCK_CHECK == 'true') || $t_use_combis_quantity == 2)){
xtc_db_query("
UPDATE
products_properties_combis
SET
combi_quantity = combi_quantity + " . $order['products_quantity'] . "
WHERE
products_properties_combis_id = '" . $order['products_properties_combis_id'] . "' AND
products_id = '" . $order['products_id'] . "'
");
}
// BOF GM_MOD
if(ATTRIBUTE_STOCK_CHECK == 'true')
{
$gm_get_orders_attributes = xtc_db_query("
SELECT
products_options,
products_options_values
FROM
orders_products_attributes
WHERE
orders_id = '" . xtc_db_input($order_id) . "'
AND
orders_products_id = '" . HelperFunctions::escapeSql($order['orders_products_id']) . "'
");
while($gm_orders_attributes = xtc_db_fetch_array($gm_get_orders_attributes))
{
$gm_get_attributes_id = xtc_db_query("
SELECT
pa.products_attributes_id
FROM
products_options_values pov,
products_options po,
products_attributes pa
WHERE
po.products_options_name = '" . HelperFunctions::escapeSql($gm_orders_attributes['products_options']) . "'
AND po.products_options_id = pa.options_id
AND pov.products_options_values_id = pa.options_values_id
AND pov.products_options_values_name = '" . HelperFunctions::escapeSql($gm_orders_attributes['products_options_values']) . "'
AND pa.products_id = '" . HelperFunctions::escapeSql($order['products_id']) . "'
LIMIT 1
");
if(xtc_db_num_rows($gm_get_attributes_id) == 1)
{
$gm_attributes_id = xtc_db_fetch_array($gm_get_attributes_id);
xtc_db_query("
UPDATE
products_attributes
SET
attributes_stock = attributes_stock + ".$order['products_quantity']."
WHERE
products_attributes_id = '" . $gm_attributes_id['products_attributes_id'] . "'
");
}
}
}
// EOF GM_MOD
}
// BOF GM_MOD products_shippingtime:
if($reshipp == 'on') {
require_once(DIR_FS_CATALOG . 'gm/inc/set_shipping_status.php');
set_shipping_status($order['products_id'], $order['products_properties_combis_id']);
}
// BOF GM_MOD products_shippingtime:
}
}
}
/**
* check if order has status "paid" and insert "paid"-status into table_orders and sofort_orders and set comments to history
* (sets log-entries in all currious situations)
* @return bool TRUE (if errors occured: FALSE)
* @todo this function is too long and should be splittet - Notice: this function is the most complicated function of this file!!!
*/
function _insertPaidStatus() {
global $insert_id; //$insert_id equals $orderId!
//create transactionData-Object
$SofortLib_TransactionData = new SofortLib_TransactionData(MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY);
if (!is_object($SofortLib_TransactionData) || !($SofortLib_TransactionData instanceof SofortLib_TransactionData)) {
if (is_object($this->invoice)) {
$this->invoice->logError("TransactionData-Object corrupt. Maybe status could not be correct set! Order-ID: $insert_id. Check status of order!");
} else {
$this->sofort->logError("TransactionData-Object corrupt. Maybe status could not be correct set! Order-ID: $insert_id. Check status of order!");
}
return false;
}
//get transactionID from table orders
$transactionId = HelperFunctions::getTransactionIdFromShop($insert_id);
if (!$transactionId){
$SofortLib_TransactionData->logError("Transaction-ID not found for order-ID: $insert_id. Maybe status could not be correct set! Check status of order!");
return false;
}
//fetch all transactionData from SOFORT
$SofortLib_TransactionData->setTransaction($transactionId);
$SofortLib_TransactionData->sendRequest();
if ($SofortLib_TransactionData->isError()) {
$SofortLib_TransactionData->logError("Error in TransactionData: ".print_r($SofortLib_TransactionData->getError(), true)."Transaction-ID: $transactionId.
Order-ID: $insert_id. Maybe status could not be correct set! Check status of order!");
return false;
}
//check if SOFORT-paymentSecret is equal to shop-paymentSecret
$paymentSecret = $SofortLib_TransactionData->getUserVariable(3); //paymentSecret was sent to SOFORT in the 4th user variable
if (!HelperFunctions::checkPaymentSecret($paymentSecret, $transactionId)) {
$SofortLib_TransactionData->logError("Check of Payment-Secret failed for given Transaction-ID: $transactionId! Checked paymentSecret: $paymentSecret. Order-ID: $insert_id. Check order!");
return false;
}
//check if SOFORT-orderId is equal to shop-orderId
$orderId = HelperFunctions::getOrderId($transactionId);
if (!$orderId || $orderId != $insert_id) {
$SofortLib_TransactionData->logError("Order-ID not found or not equal with shop-order-ID ($insert_id) for Transaction-ID: $transactionId! Check order!");
return false;
}
$time = date('d.m.Y, G:i:s', strtotime($SofortLib_TransactionData->getTime()));
$statusReason = $SofortLib_TransactionData->getStatusReason();
$status = $SofortLib_TransactionData->getStatus();
$paymentMethod = $SofortLib_TransactionData->getPaymentMethod();
$PnagInvoice = '';
if ($paymentMethod == 'sr') {
$PnagInvoice = new PnagInvoice(MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY, $transactionId);
if ($PnagInvoice->isError()) {
$SofortLib_TransactionData->logError("Errors while creating invoice-object: ".print_r($PnagInvoice->getErrors(), true)." Transaction-ID: $transactionId, Order-ID: $insert_id. Check order!");
return false;
}
}
$dbEntries = array(
'amount' => $SofortLib_TransactionData->getAmount(),
'status' => $status,
'status_reason' => $statusReason,
);
if ($paymentMethod == 'sr') $dbEntries['status_id'] = $PnagInvoice->getState();
$statusShort = HelperFunctions::getShortStatus($paymentMethod, $status, $statusReason);
$newShopStatus = HelperFunctions::getNewShopStatusId($statusShort, $insert_id, $SofortLib_TransactionData);
$historyComments = HelperFunctions::getHistoryComments($statusShort, $insert_id, $SofortLib_TransactionData, $transactionId, false, $SofortLib_TransactionData);
//check if notification was faster than call of successURL
if (HelperFunctions::hasEntriesInTableSofortNotifications($transactionId)) {
$SofortLib_TransactionData->log("Status of first notification was already set by notification (not by success-URL) for order-ID: $insert_id. There is nothing to do here.");
return true; //everything was done by notification
}
//save all relevant data in table sofort_notification
//this DB-entry also prevents race-conditions between call of successUrl and notification
//@see hasEntriesInTableSofortNotifications() and statusAndReasonDidNotChange()
//must be set (preferably direct) after call of getHistoryComments() (because of a checks there inside)
HelperFunctions::insertSofortOrdersNotification($transactionId, $dbEntries, $SofortLib_TransactionData);
//special features for SR
if ($paymentMethod == 'sr') {
//if buyer has changed addresses at sofort-wizard -> set new addresses also in shopsystem
if ($statusShort == 'sr_pen_con_inv') HelperFunctions::updateShopAdresses($SofortLib_TransactionData->getInvoiceAddress(), $SofortLib_TransactionData->getShippingAddress(), $insert_id, $SofortLib_TransactionData);
//sync SOFORT-articles/orderTotals with the shop-articles/orderTotals
require_once(DIR_FS_CATALOG.'callback/sofort/ressources/scripts/sofortOrderSynchronisation.php');
$SofortOrderSynchronisation = new sofortOrderSynchronisation();
$SofortOrderSynchronisation->editArticlesShop($PnagInvoice, $insert_id);
}
//insert all data into orders-table and orders_status_history-table
if ($historyComments['buyer']) {
if (!$newShopStatus) {
$SofortLib_TransactionData->logError("Status for buyer-comment (".$historyComments['buyer'].") unknown. Comment will not be
inserted. Check order! Order-Id: $insert_id, Transaction-ID: $transactionId!");
return false;
}
HelperFunctions::insertHistoryEntry($insert_id, $newShopStatus, $historyComments['buyer'], '', $time);
}
if ($historyComments['seller']) HelperFunctions::insertHistoryEntry($insert_id, -1, $historyComments['seller'], '', $time);
//if $newShopStatus is set, set it into table orders
if ($newShopStatus) HelperFunctions::updateTableOrdersStatus($insert_id, $newShopStatus);
return true;
}
/**
* checks, if current payment-method is installed (installed != enabled)
*/
function _isInstalled() {
$installedPaymentMethods = explode(';', MODULE_PAYMENT_INSTALLED);
if (in_array($this->code.'.php', $installedPaymentMethods)) {
// xtc-Bugfix: if paymentmethod was just deinstalled --> paymentmethod is nevertheless in MODULE_PAYMENT_INSTALLED
$countResult = xtc_db_query("SELECT count(*) as anzahl FROM " . TABLE_CONFIGURATION . " WHERE configuration_key = 'MODULE_PAYMENT_".strtoupper($this->code)."_ALLOWED'");
$count = xtc_db_fetch_array($countResult);
if ($count['anzahl'] > 0) {
return true;
}
}
return false;
}
/**
* checks, if currently installed module-files work together with an older installation of this module
* @return bool - TRUE: everything ok - FALSE: module doesnt work with installed version -> deactivate this module until seller reinstalled ALL sofort-gateway-payments
*/
function _modulVersionCheck() {
//all versions without this constant are always to old
if (!defined('MODULE_PAYMENT_SOFORT_MULTIPAY_MODULE_VERSION')) return false;
$installedShopVersion = trim(MODULE_PAYMENT_SOFORT_MULTIPAY_MODULE_VERSION);
//$filesVersion = trim(HelperFunctions::getSofortmodulVersion()); //can be used, if needed
//all installed versions lower than 5.3.0 are to old and not compatible
if (version_compare($installedShopVersion, '5.3.0', '<')) return false;
//currently(!), all higher version are compatible with 5.3.0 an higher
if (version_compare($installedShopVersion, '5.3.0', '>=')) return true;
//extend here with later versions of this module...
//should never be reached
return false;
}
}