403Webshell
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 :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/moncbefd/www.moneta.at/includes/modules/payment//paypal3.php
<?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');

Youez - 2016 - github.com/yon3zu
LinuXploit