| 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/includes/modules/payment/ |
Upload File : |
<?php
/* --------------------------------------------------------------
paypal3.php 2018-03-20
Gambio GmbH
http://www.gambio.de
Copyright (c) 2018 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
defined('GM_HTTP_SERVER') or define('GM_HTTP_SERVER', HTTP_SERVER);
class paypal3_ORIGIN
{
public $code, $title, $description, $enabled;
public $tmpOrders = true;
public $tmpStatus = 0;
protected $text;
protected $configStorage;
protected $logger;
protected $selection_logo = '';
public $sort_order;
public $info;
public $order_status, $order_status_pending, $order_status_error;
public function __construct()
{
$this->logger = MainFactory::create('PayPalLogger');
$this->text = MainFactory::create('PayPalText');
$this->configStorage = MainFactory::create('PayPalConfigurationStorage');
$this->code = 'paypal3';
$this->enabled = (@constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_STATUS') === 'True');
$this->title = @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_TEXT_TITLE_ADMIN');
$config_button = '<br><br><a href="' . xtc_href_link('admin.php', 'do=PayPalConfiguration')
. '" class="button" style="margin: auto; background-color: #E30000;">'
. $this->text->get_text('configure') . '</a><br><br>';
$this->description = @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_TEXT_DESCRIPTION')
. ($this->check() ? $config_button : '');
$this->sort_order = @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_SORT_ORDER');
$this->info = @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_TEXT_INFO');
$this->order_status = $this->configStorage->get('orderstatus/completed');
$this->order_status_pending = $this->configStorage->get('orderstatus/pending');
$this->order_status_error = $this->configStorage->get('orderstatus/error');
if(is_object($GLOBALS['order']))
{
$this->update_status();
}
// transport abandonment of withdrawal rights across POST/GET change of checkout_confirmation
if($_SERVER['REQUEST_METHOD'] === 'POST')
{
$_SESSION['paypal_abandonment_download'] = isset($_POST['abandonment_download']) ? 'true' : 'false';
$_SESSION['paypal_abandonment_service'] = isset($_POST['abandonment_service']) ? 'true' : 'false';
}
else
{
if(isset($_SESSION['paypal_abandonment_download']))
{
$_SESSION['abandonment_download'] = $_SESSION['paypal_abandonment_download'];
if($_SESSION['paypal_abandonment_download'] === 'true')
{
$_POST['abandonment_download'] = 'true';
}
}
if(isset($_SESSION['paypal_abandonment_service']))
{
$_SESSION['abandonment_service'] = $_SESSION['paypal_abandonment_service'];
if($_SESSION['paypal_abandonment_service'] === 'true')
{
$_POST['abandonment_service'] = 'true';
}
}
}
}
protected function _initLanguageConstants()
{
$constant_names = [
'MODULE_PAYMENT_PAYPAL3_TEXT_DESCRIPTION',
'MODULE_PAYMENT_PAYPAL3_TEXT_TITLE',
'MODULE_PAYMENT_PAYPAL3_TEXT_TITLE_ADMIN',
'MODULE_PAYMENT_PAYPAL3_TEXT_INFO',
'MODULE_PAYMENT_PAYPAL3_STATUS_TITLE',
'MODULE_PAYMENT_PAYPAL3_STATUS_DESC',
'MODULE_PAYMENT_PAYPAL3_SORT_ORDER_TITLE',
'MODULE_PAYMENT_PAYPAL3_SORT_ORDER_DESC',
'MODULE_PAYMENT_PAYPAL3_ZONE_TITLE',
'MODULE_PAYMENT_PAYPAL3_ZONE_DESC',
'MODULE_PAYMENT_PAYPAL3_ALLOWED_TITLE',
'MODULE_PAYMENT_PAYPAL3_ALLOWED_DESC',
];
foreach($constant_names as $constant_name)
{
defined($constant_name) or define($constant_name, $this->text->get_text($constant_name));
}
}
public function update_status()
{
$order = $GLOBALS['order'];
if(!$this->_isConfigured())
{
$this->enabled = false;
}
if(isset($_SESSION['shipping'])
&& is_array($_SESSION['shipping'])
&& $_SESSION['shipping']['id'] === 'selfpickup_selfpickup'
&& (bool)$this->configStorage->get('allow_selfpickup') === false)
{
$this->enabled = false;
}
if(($this->enabled === true) && ((int)@constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_ZONE') > 0))
{
$check_flag = false;
$check_query = xtc_db_query("SELECT `zone_id` FROM " . TABLE_ZONES_TO_GEO_ZONES . " WHERE `geo_zone_id` = '"
. @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_ZONE')
. "' AND zone_country_id = '" . $order->billing['country']['id']
. "' ORDER BY zone_id");
while($check = xtc_db_fetch_array($check_query))
{
if($check['zone_id'] < 1)
{
$check_flag = true;
break;
}
elseif($check['zone_id'] === $order->billing['zone_id'])
{
$check_flag = true;
break;
}
}
if($check_flag === false)
{
$this->enabled = false;
}
}
}
protected function _isConfigured()
{
$isConfigured = false;
$mode = $this->configStorage->get('mode');
$client_id = $this->configStorage->get('restapi-credentials/' . $mode . '/client_id');
$secret = $this->configStorage->get('restapi-credentials/' . $mode . '/secret');
if(!empty($client_id) && !empty($secret))
{
$isConfigured = true;
}
return $isConfigured;
}
public function javascript_validation()
{
return false;
}
public function _selectionPayPalPlus()
{
try
{
$order = isset($GLOBALS['order']) ? $GLOBALS['order'] : new order();
if(isset($_SESSION['paypal_payment'])
&& $_SESSION['paypal_payment']['type'] === 'plus'
&& $_SESSION['paypal_payment']['state'] === 'created'
&& $_SESSION['paypal_payment']['cartID'] === $_SESSION['cart']->cartID
&& $_SESSION['paypal_payment']['billto'] === $_SESSION['billto']
)
{
$payPalPayment = MainFactory::create('PayPalPayment', $_SESSION['paypal_payment']['id']);
$this->logger->notice('re-using existing payment resource ' . $_SESSION['paypal_payment']['id']);
}
else
{
$payPalPaymentFactory = MainFactory::create_object('PayPalPaymentFactory');
$payPalPayment = $payPalPaymentFactory->createPaymentFromOrder($GLOBALS['order'], 'plus');
$_SESSION['paypal_payment'] = [
'id' => $payPalPayment->id,
'type' => 'plus',
'state' => 'created',
'cartID' => $_SESSION['cart']->cartID,
'billto' => $_SESSION['billto'],
];
}
$approvalUrl = $payPalPayment->getLink('approval_url');
$language = $this->getLocale();
$preselection = $this->_hasLowestPriority() ? 'paypal' : 'none';
$ppplusConfigJSON = '{
"approvalUrl": "' . (string)$approvalUrl->href . '",
"placeholder": "ppplus",
"mode": "' . $this->configStorage->get('mode') . '",
"country": "' . $order->billing['country']['iso_code_2'] . '",
"language": "' . $language . '",
"preselection": "' . $preselection . '",
"showPuiOnSandbox": "true",
"buttonLocation": "outside",
"disableContinue": function()
{
$("#ppplus_continue").css("opacity", "0.1");
$(\'div.payment_item input[value="paypal3"]\').get(0).checked = false;
},
"enableContinue": function()
{
$("div.payment_item input[value=paypal3]").trigger("click");
$("#ppplus_continue").css("opacity", "1.0");
},
"onContinue": function()
{
$("#ppplus_continue").closest("form").trigger("submit", ["trigger"]);
},
"styles":
{
"psp": {
"font-size": "14px",
"font-family": "Arial,Tahoma,Verdana",
"color": "#666",
}
},
"thirdPartyPaymentMethods": thirdPartyPayments,
}';
$this->logger->debug_notice("PayPal PLUS configuration generated:\n" . $ppplusConfigJSON);
$tmpPlaceholder = '<div style="text-align: center;"><img src="' . GM_HTTP_SERVER . DIR_WS_CATALOG
. 'images/ladebalken.gif"></div>';
$ppplusSnippet = '<div id="ppplus" style="width: 100%; min-height: 20px;">' . $tmpPlaceholder . '</div>';
if($preselection === 'none')
{
$preselectionSnippet = ' ppp.deselectPaymentMethod(); $("ul.paypal3-plus-checkout li:first").trigger("click"); ';
}
else
{
$preselectionSnippet = ' /* pp+ preselected */ ';
}
$ppplusSnippet .= sprintf('<script> var ppp; var initPPP = function(thirdPartyPayments) { ppp = PAYPAL.apps.PPP(%s); %s}; </script>',
$ppplusConfigJSON, $preselectionSnippet);
$description = $ppplusSnippet;
}
catch(Exception $e)
{
$errorMessage = 'Could not instantiate payment for PP+: ' . $e->getMessage();
$this->logger->notice($errorMessage);
$_SESSION['ppplus_disabled'] = true;
xtc_redirect(xtc_href_link('checkout_payment.php', '', 'SSL'));
return false;
}
$this->logger->notice('Created payment for PP+ payment wall: ' . $_SESSION['paypal_payment']['id']);
$selection = [
'id' => $this->code,
'module' => '',
'description' => $description,
'fields' => [],
];
return $selection;
}
protected function _hasLowestPriority()
{
$integratedModules = [];
if($this->configStorage->get('thirdparty_payments/invoice/mode') === 'paywall')
{
$integratedModules[] = '\'MODULE_PAYMENT_INVOICE_STATUS\'';
}
if($this->configStorage->get('thirdparty_payments/cod/mode') === 'paywall')
{
$integratedModules[] = '\'MODULE_PAYMENT_COD_STATUS\'';
}
if($this->configStorage->get('thirdparty_payments/moneyorder/mode') === 'paywall')
{
$integratedModules[] = '\'MODULE_PAYMENT_MONEYORDER_STATUS\'';
}
if($this->configStorage->get('thirdparty_payments/eustandardtransfer/mode') === 'paywall')
{
$integratedModules[] = '\'MODULE_PAYMENT_EUSTANDARDTRANSFER_STATUS\'';
}
if($this->configStorage->get('thirdparty_payments/cash/mode') === 'paywall')
{
$integratedModules[] = '\'MODULE_PAYMENT_CASH_STATUS\'';
}
$minSortOrderQuery = "SELECT
CAST(`conf`.`configuration_value` AS DECIMAL(20,5)) AS `decvalue`,
`conf`.`configuration_value`,
`conf`.`configuration_key`
FROM
`configuration` `conf`
WHERE
`configuration_key` IN (
SELECT
REPLACE(`configuration_key`, '_STATUS', '_SORT_ORDER') AS `module_code`
FROM
`configuration` `c`
WHERE
`configuration_key` LIKE 'module_payment_%_status' AND
`configuration_value` = 'True' AND
`configuration_key` NOT IN (:integrated_modules)
)
ORDER BY
`decvalue` ASC
LIMIT 1
";
$integratedModulesList = empty($integratedModules) ? '\'\'' : implode(', ', $integratedModules);
$minSortOrderQuery = strtr($minSortOrderQuery, [
':integrated_modules' => $integratedModulesList,
]);
$minSortOrderResult = xtc_db_query($minSortOrderQuery);
$minSortOrder = 0;
while($row = xtc_db_fetch_array($minSortOrderResult))
{
$minSortOrder = (double)$row['configuration_value'];
}
$hasLowestPriority = (double)constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_SORT_ORDER')
<= $minSortOrder;
return $hasLowestPriority;
}
protected function _getStateSelector()
{
$stateSelector = '';
$stateRequiredCountries = explode(',', 'AR,BR,CA,CN,ID,IN,JP,MX,TH,US');
$stateRequired = is_array($GLOBALS['order']->delivery['country'])
&& in_array($GLOBALS['order']->delivery['country']['iso_code_2'],
$stateRequiredCountries,
true)
&& empty($GLOBALS['order']->delivery['zone_id']);
if($stateRequired)
{
$countryService = StaticGXCoreLoader::getService('Country');
$deliveryCountry = $countryService->getCountryById(new IdType($GLOBALS['order']->delivery['country']['id']));
if($countryService->countryHasCountryZones($deliveryCountry))
{
$countryZones = $countryService->findCountryZonesByCountryId(new IdType($GLOBALS['order']->delivery['country']['id']));
$stateSelector .= '<br>' . $this->text->get_text('select_your_state') . ': ';
$stateSelector .= '<select name="paypal_zone">';
foreach($countryZones as $cZone)
{
if(in_array($GLOBALS['order']->delivery['state'],
[(string)$cZone->getName(), (string)$cZone->getCode()], true)
|| in_array($_SESSION['paypal_state'], [(string)$cZone->getName(), (string)$cZone->getCode()],
true))
{
$zoneSelected = ' selected="selected"';
}
else
{
$zoneSelected = '';
}
$stateSelector .= '<option ' . $zoneSelected . ' value="' . (string)$cZone->getId() . '">'
. (string)$cZone->getName() . '</option>';
}
$stateSelector .= '</select>';
}
}
return $stateSelector;
}
public function selection()
{
if(isset($_GET['paypal']) && $_GET['paypal'] === 'cancel')
{
unset($_SESSION['payment']);
}
// default values for ECM mode
$selection = [
'id' => $this->code,
'module' => @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_TEXT_TITLE'),
'description' => @constant('MODULE_PAYMENT_' . strtoupper($this->code) . '_TEXT_DESCRIPTION'),
'fields' => [],
];
$stateSelector = $this->_getStateSelector();
$selection['description'] .= $stateSelector;
$calledFromCheckoutPayment = is_object($GLOBALS['order']) && strpos($_SERVER['PHP_SELF'], 'checkout_payment') !== false;
$isShortcutPayment = isset($_SESSION['paypal_payment']) && $_SESSION['paypal_payment']['type'] === 'ecs';
if($isShortcutPayment === true)
{
if(!isset($_SESSION['paypal_payment']['is_guest'])
&& $_SESSION['paypal_payment']['cartID'] !== $_SESSION['cart']->cartID)
{
unset($_SESSION['paypal_payment']);
$isShortcutPayment = false;
}
else
{
$selection['description'] .= ' <!-- (ECS) -->';
}
}
if(isset($_SESSION['ppplus_disabled']) === false
&& $calledFromCheckoutPayment === true
&& $isShortcutPayment === false
&& empty($stateSelector) === true)
{
if((bool)$this->configStorage->get('use_paypal_plus') === true)
{
$plus_selection = $this->_selectionPayPalPlus();
$selection = $plus_selection !== false ? $plus_selection : $selection;
}
else
{
unset($_SESSION['paypal_payment']);
}
}
return $selection;
}
public function pre_confirmation_check()
{
$confirmation_ok = false;
if(isset($_POST['paypal_zone']))
{
$countryService = StaticGXCoreLoader::getService('Country');
$paypalZone = $countryService->getCountryZoneById(new IdType((int)$_POST['paypal_zone']));
$_SESSION['paypal_state'] = (string)$paypalZone->getCode();
}
if(!isset($_GET['paymentId']))
{
if((int)gm_get_conf('GM_CHECK_CONDITIONS') !== 1)
{
$_SESSION['conditions'] = 'true/not_reqd';
}
if((int)gm_get_conf('GM_CHECK_WITHDRAWAL') !== 1)
{
$_SESSION['withdrawal'] = 'true/not_reqd';
}
if(!empty($_SESSION['paypal_payment']['payer_id'])
&& in_array($_SESSION['paypal_payment']['type'], ['ecs', 'ecm'], true))
{
$confirmation_ok = true;
}
elseif($_SESSION['paypal_payment']['type'] === 'plus')
{
// perform last-second updates
try
{
if($_SESSION['cart']->get_content_type() !== 'virtual')
{
$this->logger->notice('Updating PLUS payment with shipping/billing address: '
. $_SESSION['paypal_payment']['id']);
$paymentFactory = MainFactory::create('PayPalPaymentFactory');
$paymentFactory->updatePaymentFromOrder($_SESSION['paypal_payment']['id'], $GLOBALS['order']);
}
$this->logger->notice('Redirecting to PayPal for Plus payment');
echo '<!DOCTYPE html><html><head><script src="https://www.paypalobjects.com/webstatic/ppplus/ppplus.min.js" type="text/javascript"></script></head>';
echo '<body><script>PAYPAL.apps.PPP.doCheckout();</script><p>'
. $this->text->get_text('redirecting_to_paypal') . '</p></body>';
xtc_db_close();
exit;
}
catch(Exception $e)
{
$errorMessage = $this->text->get_text('error_updating_payment');
$_SESSION['paypal3_error'] = $errorMessage;
$this->logger->error($errorMessage . ' (' . $e->getMessage() . ')');
unset($_SESSION['payment'], $_SESSION['paypal_payment']);
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
}
else // type == 'ecm'
{
$this->logger->notice('Instantiating Payment for ECM mode');
try
{
$order_total = new order_total();
$order_total_array = $order_total->process();
$paypalState = isset($_SESSION['paypal_state']) ? $_SESSION['paypal_state'] : null;
$payPalPaymentFactory = MainFactory::create_object('PayPalPaymentFactory');
$payPalPayment = $payPalPaymentFactory->createPaymentFromOrder($GLOBALS['order'],
'ecm', $paypalState);
$approvalLinkEntry = $payPalPayment->getLink('approval_url');
$approvalUrl = $approvalLinkEntry->href;
$approvalUrl .= '&LocaleCode=' . $this->getLocale();
$_SESSION['paypal_payment'] = [
'id' => $payPalPayment->id,
'type' => 'ecm',
'state' => 'created',
'cartID' => $_SESSION['cart']->cartID,
'billto' => $_SESSION['billto'],
];
# die("<br>\nApproval URL: ".$approvalUrl);
$this->logger->notice('ECM payment created with id ' . $payPalPayment->id
. ', redirecting customer to ' . $approvalUrl);
xtc_redirect($approvalUrl);
}
catch(Exception $e)
{
$errorMessage = $this->text->get_text('error_creating_ecm_payment');
$this->logger->notice($errorMessage . ': ' . $e->getMessage());
$_SESSION['paypal3_error'] = $this->text->get_text('paypal_unavailable');
unset($_SESSION['payment']);
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
}
}
if(!empty($_GET['paymentId']) && $_GET['paymentId'] === $_SESSION['paypal_payment']['id']
&& (!empty($_GET['PayerID']) || !empty($_SESSION['paypal_payment']['payer_id'])))
{
$this->logger->notice('Payment approved by customer: ' . $_SESSION['paypal_payment']['id'] . ', PayerID: '
. $_GET['PayerID']);
$confirmation_ok = true;
$_SESSION['paypal_payment']['state'] = 'approved';
$_SESSION['paypal_payment']['payer_id'] = $_GET['PayerID'];
}
try
{
MainFactory::create('PayPalPayment', $_SESSION['paypal_payment']['id']);
}
catch(Exception $e)
{
$errorMessage = $this->text->get_text('error_retrieving_payment');
unset($_SESSION['paypal_payment']);
$this->logger->notice($errorMessage . ': ' . $e->getMessage());
$_SESSION['paypal3_error'] = $errorMessage;
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
if($confirmation_ok !== true)
{
$this->logger->notice("pre_confirmation_check failed, GET:\n" . print_r($_GET, true));
$_SESSION['paypal3_error'] = $this->text->get_text('paypal_unavailable');
unset($_SESSION['payment'], $_SESSION['paypal_payment']);
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
return $confirmation_ok;
}
/** determines LocaleCode from session data */
protected function getLocale()
{
$language = strtolower($_SESSION['language_code']);
$shop_country_data = $this->_findCountryByID(STORE_COUNTRY);
$shop_country = $shop_country_data['country_iso_2'];
$addressBookService = StaticGXCoreLoader::getService('AddressBook');
$billtoAddress = $addressBookService->findAddressById(new IdType($_SESSION['billto']));
$billtoCountry = (string)$billtoAddress->getCountry()->getIso2();
$ppLocaleFactory = MainFactory::create('PayPalLocaleFactory');
$locale = $ppLocaleFactory->getLocaleByLanguageAndCountry($language, $billtoCountry);
if(empty($locale))
{
$locale = $language . '_' . $shop_country;
}
return $locale;
}
protected function _findCountryByID($country_id)
{
$query = "SELECT * FROM `countries` WHERE `countries_id` = ':countries_id'";
$query = strtr($query, [':countries_id' => (int)$country_id]);
$result = xtc_db_query($query);
$country_data = false;
while($row = xtc_db_fetch_array($result))
{
$country_data = $row;
}
return $country_data;
}
public function confirmation()
{
unset($_SESSION['paypal_payment_instruction_href']);
$confirmation = [
'title' => $this->text->get_text('checkout_confirmation_info'),
];
return $confirmation;
}
public function refresh()
{
}
public function process_button()
{
$order = $GLOBALS['order'];
$pb = '';
return $pb;
}
public function after_process()
{
// $GLOBALS['order'], $_SESSION['tmp_oID'], $GLOBALS['order_totals']
if(!empty($_SESSION['paypal_final_order_status']))
{
// set orders_status again, in case something has changed it
$insert_id = (int)$_SESSION['tmp_oID'];
$this->logger->notice(sprintf('Re-setting order status for %d to %d', $insert_id,
$_SESSION['paypal_final_order_status']));
xtc_db_query("UPDATE " . TABLE_ORDERS . " SET orders_status='" . $_SESSION['paypal_final_order_status']
. "' WHERE orders_id='" . $insert_id . "'");
unset($_SESSION['paypal_final_order_status']);
}
}
public function before_process()
{
return false;
}
public function payment_action()
{
$insert_id = $GLOBALS['insert_id'];
$order = new order($insert_id);
$this->logger->notice('Executing payment ' . $_SESSION['paypal_payment']['id'] . ' for orders_id '
. $insert_id);
try
{
$paypalPayment = MainFactory::create('PayPalPayment', $_SESSION['paypal_payment']['id']);
}
catch(Exception $e)
{
$errorMessage = $this->text->get_text('error_retrieving_payment');
unset($_SESSION['paypal_payment']);
xtc_db_query("UPDATE " . TABLE_ORDERS . " SET orders_status='" . $this->order_status_error
. "' WHERE orders_id='" . $insert_id . "'");
$this->_addOrdersStatusHistoryEntry($insert_id, $this->order_status_error,
$errorMessage . "\n" . $e->getMessage());
$this->logger->notice($errorMessage . ': ' . $e->getMessage());
$_SESSION['paypal3_error'] = $errorMessage;
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
try
{
$paymentFactory = MainFactory::create('PayPalPaymentFactory');
if($_SESSION['cart']->get_content_type() !== 'virtual')
{
$this->logger->notice('Updating payment with final shipping/billing address: '
. $_SESSION['paypal_payment']['id']);
$paymentFactory->updatePaymentFromOrder($_SESSION['paypal_payment']['id'], $GLOBALS['order']);
}
$this->logger->notice(sprintf('adding invoice_number to payment %s: %s', $_SESSION['paypal_payment']['id'],
$order->info['orders_id']));
$paymentFactory->addInvoiceNumber($_SESSION['paypal_payment']['id'], $order);
// execute payment
$isPlus = $_SESSION['paypal_payment']['type'] === 'plus';
$state = isset($_SESSION['paypal_state']) ? $_SESSION['paypal_state'] : null;
$this->_addPaymentToOrder($insert_id, $paypalPayment->id, $this->configStorage->get('mode'));
try
{
$paypalPayment->execute($_SESSION['paypal_payment']['payer_id'], $order, $isPlus, $state);
}
catch (RestTimeoutException $rte)
{
$this->logger->notice('Timeout when executing payment, reloading payment: ' . $paypalPayment->id);
sleep(5);
$paypalPayment = MainFactory::create('PayPalPayment', $paypalPayment->id);
if(!empty($paypalPayment->transactions[0]))
{
$resourceZero = (array)$paypalPayment->transactions[0]->related_resources[0];
$transaction = array_pop($resourceZero);
$this->logger->notice('Transaction state after timed-out execute: ' . (string)$transaction->state);
if((string)$transaction->state !== 'completed')
{
throw new Exception('Payment not completed after timeout in execute call');
}
}
}
try {
$this->logger->notice('Reloading payment to find payment instruction: ' . $paypalPayment->id);
$paypalPayment = MainFactory::create('PayPalPayment', $paypalPayment->id);
}
catch (Exception $e)
{
$this->logger->notice('Error reloading payment: ' . $e->getMessage());
}
$paymentInstruction = $paypalPayment->payment_instruction;
if($paymentInstruction !== null)
{
$this->logger->notice(sprintf('storing payment instruction for order %d in database',
$order->info['orders_id']));
$this->_storePaymentInstruction($paymentInstruction, $order->info['orders_id']);
}
$resourceZero = (array)$paypalPayment->transactions[0]->related_resources[0];
$transaction = array_pop($resourceZero);
$this->logger->notice('Transaction state after execute: ' . (string)$transaction->state);
$final_order_status = $this->order_status;
if($transaction->state === 'pending' && $this->order_status_pending)
{
$final_order_status = $this->order_status_pending;
}
$_SESSION['paypal_final_order_status'] = $final_order_status;
xtc_db_query("UPDATE " . TABLE_ORDERS . " SET orders_status='" . $final_order_status . "' WHERE orders_id='"
. $insert_id . "'");
$status_comments = '';
$status_comments .= $this->text->get_text('checkout_mode') . ': '
. strtoupper($_SESSION['paypal_payment']['type']);
if(isset($_SESSION['paypal_payment']['is_guest']) && $_SESSION['paypal_payment']['is_guest'] == true)
{
$this->logger->notice('Payment ' . $_SESSION['paypal_payment']['id'] . ' was initiated by ECS');
$status_comments .= "\n" . $this->text->get_text('guest_customer_created_from_ecs_data');
// void session for ECS guests unless cart contains download products
$isDownload = false;
/** @var array $products */
$products = $_SESSION['cart']->get_products();
foreach($products as $product)
{
$isDownload = $product['product_type'] === '2';
}
if($isDownload === false)
{
$_SESSION['paypal_ecs_logout_required'] = true;
}
}
$this->_addOrdersStatusHistoryEntry($insert_id, $final_order_status, $status_comments);
$this->logger->notice('Payment ' . $_SESSION['paypal_payment']['id'] . ' executed.');
$GLOBALS['tmp'] = false;
}
catch(Exception $e)
{
$errorMessage = $this->text->get_text('error_executing_payment');
unset($_SESSION['paypal_payment']);
xtc_db_query("UPDATE " . TABLE_ORDERS . " SET orders_status='" . $this->order_status_error
. "' WHERE orders_id='" . $insert_id . "'");
$this->_addOrdersStatusHistoryEntry($insert_id, $this->order_status_error,
$errorMessage . "\n" . $e->getMessage());
$this->logger->notice('ERROR executing payment ' . $paypalPayment->id . ' - ' . $e->getMessage());
$_SESSION['paypal3_error'] = $errorMessage;
xtc_redirect(xtc_href_link('checkout_payment.php', 'payment_error=' . $this->code, 'SSL'));
}
unset($_SESSION['paypal_payment'], $_SESSION['paypal_state'], $_SESSION['paypal_abandonment_service'], $_SESSION['paypal_abandonment_download']);
}
/**
* stores payment instruction (for payment upon invoice)
*/
protected function _storePaymentInstruction(stdClass $paymentInstruction, $orders_id)
{
$orders_id = (int)$orders_id;
if($orders_id <= 0)
{
throw new Exception('invalid value for orders_id');
}
if(isset($paymentInstruction->payment_due_date))
{
$dueDate = xtc_db_input($paymentInstruction->payment_due_date);
}
else
{
$dueDate = '1000-01-01';
}
$insert_query = "INSERT
INTO `orders_payment_instruction`
SET
`orders_id` = ':orders_id',
`reference` = ':reference',
`bank_name` = ':bank_name',
`account_holder` = ':account_holder',
`iban` = ':iban',
`bic` = ':bic',
`value` = ':value',
`currency` = ':currency',
`due_date` = ':due_date'";
$insert_query = strtr($insert_query, [
':orders_id' => $orders_id,
':reference' => xtc_db_input($paymentInstruction->reference_number),
':bank_name' => xtc_db_input($paymentInstruction->recipient_banking_instruction->bank_name),
':account_holder' => xtc_db_input($paymentInstruction->recipient_banking_instruction->account_holder_name),
':iban' => xtc_db_input($paymentInstruction->recipient_banking_instruction->international_bank_account_number),
':bic' => xtc_db_input($paymentInstruction->recipient_banking_instruction->bank_identifier_code),
':value' => sprintf('%.2f', (double)$paymentInstruction->amount->value),
':currency' => xtc_db_input($paymentInstruction->amount->currency),
':due_date' => $dueDate,
]);
xtc_db_query($insert_query);
}
protected function _addOrdersStatusHistoryEntry($orders_id, $orders_status_id, $comments)
{
$insert_query = 'INSERT INTO
`orders_status_history`
SET
`orders_id` = \':orders_id\',
`orders_status_id` = \':orders_status_id\',
`date_added` = NOW(),
`customer_notified` = 0,
`comments` = \':comments\'';
$insert_query = strtr($insert_query, [
':orders_id' => (int)$orders_id,
':orders_status_id' => (int)$orders_status_id,
':comments' => xtc_db_input($comments),
]);
xtc_db_query($insert_query);
}
protected function _addPaymentToOrder($orders_id, $payment_id, $mode)
{
$query = 'REPLACE
INTO `orders_paypal_payments`
SET
`orders_id` = \':orders_id\',
`payment_id` = \':payment_id\',
`mode` = \':mode\'
';
$query = strtr($query, [
':orders_id' => (int)$orders_id,
':payment_id' => xtc_db_input($payment_id),
':mode' => xtc_db_input($mode),
]);
xtc_db_query($query);
}
public function get_error()
{
$error = false;
if(isset($_SESSION['paypal3_error']))
{
$error = ['error' => $_SESSION['paypal3_error']];
unset($_SESSION['paypal3_error']);
}
return $error;
}
public function check()
{
if(!isset($this->_check))
{
$check_query = xtc_db_query("SELECT `configuration_value` FROM " . TABLE_CONFIGURATION
. " WHERE `configuration_key` = 'MODULE_PAYMENT_" . strtoupper($this->code)
. "_STATUS'");
$this->_check = xtc_db_num_rows($check_query);
}
return $this->_check;
}
public function install()
{
$config = $this->_configuration();
$sort_order = 0;
foreach($config as $key => $data)
{
$install_query = "INSERT INTO " . TABLE_CONFIGURATION
. " ( `configuration_key`, `configuration_value`, `configuration_group_id`, `sort_order`, `set_function`, `use_function`, `date_added`) "
. "VALUES ('MODULE_PAYMENT_" . strtoupper($this->code) . "_" . $key . "', '"
. $data['configuration_value'] . "', '6', '" . $sort_order . "', '"
. addslashes($data['set_function']) . "', '" . addslashes($data['use_function'])
. "', now())";
xtc_db_query($install_query);
$sort_order++;
}
}
public function remove()
{
xtc_db_query("DELETE FROM " . TABLE_CONFIGURATION . " WHERE `configuration_key` IN ('" . implode("', '",
$this->keys())
. "')");
}
/**
* Determines the module's configuration keys
*
* @return array
*/
public function keys()
{
$ckeys = array_keys($this->_configuration());
$keys = [];
foreach($ckeys as $k)
{
$keys[] = 'MODULE_PAYMENT_' . strtoupper($this->code) . '_' . $k;
}
return $keys;
}
public function isInstalled()
{
$isInstalled = true;
foreach($this->keys() as $key)
{
if(!defined($key))
{
$isInstalled = false;
}
}
return $isInstalled;
}
public function _configuration()
{
$config = [
'STATUS' => [
'configuration_value' => 'True',
'set_function' => 'gm_cfg_select_option(array(\'True\', \'False\'), ',
],
'SORT_ORDER' => [
'configuration_value' => '-9999',
],
'ALLOWED' => [
'configuration_value' => '',
],
'ZONE' => [
'configuration_value' => '0',
'use_function' => 'xtc_get_zone_class_title',
'set_function' => 'xtc_cfg_pull_down_zone_classes(',
],
];
return $config;
}
}
MainFactory::load_origin_class('paypal3');