%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/sale/handlers/paysystem/assist/
Upload File :
Create Path :
Current File : //home/bitrix/www/bitrix/modules/sale/handlers/paysystem/assist/handler.php

<?php

namespace Sale\Handlers\PaySystem;

use Bitrix\Main\Entity\EntityError;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Request;
use Bitrix\Main\Error;
use Bitrix\Main\Type\DateTime;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Sale\PaySystem;
use Bitrix\Sale\Payment;
use Bitrix\Sale\PriceMaths;

Loc::loadMessages(__FILE__);

class AssistHandler extends PaySystem\ServiceHandler implements PaySystem\IRefund, PaySystem\ICheckable
{
	/**
	 * @param Payment $payment
	 * @param Request|null $request
	 * @return PaySystem\ServiceResult
	 */
	public function initiatePay(Payment $payment, Request $request = null)
	{
		$extraParams = array(
			'URL' => $this->getUrl($payment, 'pay')
		);
		$this->setExtraParams($extraParams);

		return $this->showTemplate($payment, "template");
	}

	/**
	 * @return array
	 */
	public static function getIndicativeFields()
	{
		return array('ordernumber', 'billnumber', 'orderamount', 'amount', 'meantypename', 'meantype_id', 'approvalcode', 'operationtype');
	}

	/**
	 * @param Payment $payment
	 * @param int $refundableSum
	 * @return PaySystem\ServiceResult
	 */
	public function refund(Payment $payment, $refundableSum)
	{
		$result = new PaySystem\ServiceResult();

		$params = $this->getParamsBusValue($payment);
		$refundUrl = $this->getUrl($payment, 'return');

		$data = array(
			'Billnumber' => $payment->getField('PS_INVOICE_ID'),
			'Merchant_ID' => $params['ASSIST_SHOP_IDP'],
			'Login' => $params['ASSIST_SHOP_LOGIN'],
			'Password' => $params['ASSIST_SHOP_PASSWORD'],
			'Amount' => $refundableSum,
			'Currency' => $params['PAYMENT_CURRENCY'],
			'Format' => 3
		);

		$clientHttp = new HttpClient();
		$response = $clientHttp->post($refundUrl, $data);

		if ($response)
		{
			$xml = new \CDataXML();
			$xml->LoadString($response);
			$data = $xml->GetArray();
			if ($data && $data['result']['@']['firstcode'] == '0' && $data['result']['@']['secondcode'] == '0')
			{
				$result->setOperationType(PaySystem\ServiceResult::MONEY_LEAVING);
			}
			else
			{
				$error = 'assist error refund: firstcode='.$data['result']['@']['firstcode'].' secondcode='.$data['result']['@']['secondcode'];
				PaySystem\Logger::addError('Assist: return: '.$error);
				$result->addError(new EntityError(Loc::getMessage('SALE_PS_MESSAGE_ERROR_CONNECT_PAY_SYS')));
			}
		}
		else
		{
			$message = 'Incorrect server response';
			$result->addError(new Error($message));

			PaySystem\Logger::addError('Assist: return: '.$message);
		}

		return $result;
	}

	/**
	 * @param Payment $payment
	 * @param $request
	 * @return bool
	 */
	private function isCorrectHash(Payment $payment, Request $request)
	{
		$hash = md5(
			ToUpper(
				md5($this->getBusinessValue($payment, 'ASSIST_SHOP_SECRET_WORLD')).md5(
					$this->getBusinessValue($payment, 'ASSIST_SHOP_IDP').$request->get('ordernumber').$request->get('amount').$this->getBusinessValue($payment, 'PAYMENT_CURRENCY').$request->get('orderstate')
				)
			)
		);

		return (ToUpper($hash) == ToUpper($request->get('checkvalue')));
	}

	/**
	 * @param Payment $payment
	 * @param Request $request
	 * @return bool
	 */
	private function isCorrectSum(Payment $payment, Request $request)
	{
		$sum = $request->get('orderamount');
		$paymentSum = $this->getBusinessValue($payment, 'PAYMENT_SHOULD_PAY');

		return PriceMaths::roundPrecision($paymentSum) === PriceMaths::roundPrecision($sum);
	}

	/**
	 * @param PaySystem\ServiceResult $result
	 * @param Request $request
	 * @return mixed
	 */
	public function sendResponse(PaySystem\ServiceResult $result, Request $request)
	{
		global $APPLICATION;
		$APPLICATION->RestartBuffer();

		header('Content-Type: text/xml');
		header('Pragma: no-cache');
		$text = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n';

		if ($result->isResultApplied())
		{
			$text .= '<pushpaymentresult firstcode=\'0\' secondcode=\'0\'>';
			$text .= '<order>';
			$text .= '<billnumber>'.$request->get('billnumber').'</billnumber>';
			$text .= '<packetdate>'.$request->get('packetdate').'</packetdate>';
			$text .= '</order>';
		}
		else
		{
			$text .= '<pushpaymentresult firstcode=\'9\' secondcode=\'7\'>';
		}

		$text .= '</pushpaymentresult>';

		echo $text;
		die();
	}

	/**
	 * @param Request $request
	 * @return mixed
	 */
	public function getPaymentIdFromRequest(Request $request)
	{
		return $request->get('ordernumber');
	}

	/**
	 * @param Payment $payment
	 * @param Request $request
	 * @return PaySystem\ServiceResult
	 */
	public function processRequest(Payment $payment, Request $request)
	{
		$result = new PaySystem\ServiceResult();

		if ($this->isCorrectHash($payment, $request))
		{
			$status = str_replace(' ', '', $request->get('orderstate'));
			$psStatus = ($status == "Approved") ? "Y" : "N";

			$result->setPSData(
				array(
					"PS_STATUS" => $psStatus,
					"PS_STATUS_CODE" => substr($status, 0, 5),
					"PS_STATUS_DESCRIPTION" => Loc::getMessage('SALE_PS_DESCRIPTION_'.ToUpper($status)),
					"PS_STATUS_MESSAGE" => Loc::getMessage('SALE_PS_MESSAGE_'.ToUpper($status)),
					"PS_SUM" => $request->get('orderamount'),
					"PS_CURRENCY" => $request->get('ordercurrency'),
					"PS_INVOICE_ID" => $request->get('billnumber'),
					"PS_RESPONSE_DATE" => new DateTime()
				)
			);

			if ($this->isCorrectSum($payment, $request) &&
				$this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY') == 'Y' &&
				$psStatus == 'Y' &&
				!$payment->isPaid()
			)
			{
				$result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
			}
			else
			{
				$result->addError(new Error('Incorrect sum or payment flag'));
			}
		}
		else
		{
			$result->addError(new Error('Incorrect hash sum'));
		}

		if (!$result->isSuccess())
		{
			PaySystem\Logger::addError('Assist: '.$request->get('orderstate').': '.join('\n', $result->getErrorMessages()));
		}

		return $result;
	}

	/**
	 * @param Payment $payment
	 * @return bool
	 */
	protected function isTestMode(Payment $payment = null)
	{
		return ($this->getBusinessValue($payment, 'PS_IS_TEST') == 'Y');
	}

	/**
	 * @return array
	 */
	protected function getUrlList()
	{
		return array(
			'confirm' => 'https://#SERVER_NAME#/charge/charge.cfm',
			'return' => 'https://#SERVER_NAME#/cancel/wscancel.cfm',
			'pay' => 'https://#SERVER_NAME#/pay/order.cfm',
			'check' => 'https://#SERVER_NAME#/orderstate/orderstate.cfm',
		);
	}

	/**
	 * @param Payment $payment
	 * @param string $action
	 * @return string
	 */
	protected function getUrl(Payment $payment = null, $action)
	{
		$url = parent::getUrl($payment, $action);
		if ($this->isTestMode($payment))
			$domain = 'payments.demo.paysecure.ru';
		else
			$domain = $this->getBusinessValue($payment, 'ASSIST_SERVER_URL');

		return str_replace('#SERVER_NAME#', $domain, $url);
	}

	/**
	 * @return array
	 */
	public function getCurrencyList()
	{
		return array('RUB', 'USD', 'EUR');
	}

	/**
	 * @param Payment $payment
	 * @return PaySystem\ServiceResult
	 */
	public function check(Payment $payment)
	{
		$serviceResult = new PaySystem\ServiceResult();

		$dtm = AddToTimeStamp(array("MM" => -1), false);

		$postData = array(
			'Ordernumber' => $this->getBusinessValue($payment, 'PAYMENT_ID'),
			'Merchant_ID' => $this->getBusinessValue($payment, 'ASSIST_SHOP_IDP'),
			'login' => $this->getBusinessValue($payment, 'ASSIST_SHOP_LOGIN'),
			'password' => $this->getBusinessValue($payment, 'ASSIST_SHOP_PASSWORD'),
			'FORMAT' => 3,
			'StartYear' => date('Y', $dtm),
			'StartMonth' => date('n', $dtm),
			'StartYDay' => date('j', $dtm)
		);

		$httpClient = new HttpClient();
		$queryRes = $httpClient->query('POST', $this->getUrl($payment, 'check'), $postData);

		if ($queryRes)
		{
			$httpResult = $httpClient->getResult();

			$objXML = new \CDataXML();
			$objXML->LoadString($httpResult);
			$data = $objXML->GetArray();

			if ($data && $data['result']['@']['firstcode'] == '0')
			{
				$orderData = $data['result']['#']['order'][0]['#'];
				if ((int)$orderData['ordernumber'][0]['#'] == $this->getBusinessValue($payment, 'PAYMENT_ID'))
				{
					$check = ToUpper(md5(ToUpper(md5($this->getBusinessValue($payment, 'ASSIST_SHOP_SECRET_WORLD')).md5($this->getBusinessValue($payment, 'ASSIST_SHOP_IDP').$orderData['ordernumber'][0]['#'].$orderData['orderamount'][0]['#'].$orderData['ordercurrency'][0]['#'].$orderData['orderstate'][0]['#']))));

					if (ToUpper($orderData['checkvalue'][0]['#']) == $check)
					{
						$status = str_replace(' ', '', $orderData['orderstate'][0]['#']);

						$psData = array(
							'PS_STATUS' => ($orderData['orderstate'][0]['#'] == 'Approved' ? 'Y' : 'N'),
							'PS_STATUS_CODE' => substr($orderData['orderstate'][0]['#'], 0, 5),
							'PS_STATUS_DESCRIPTION' => Loc::getMessage('SALE_PS_DESCRIPTION_'.ToUpper($status)),
							'PS_STATUS_MESSAGE' => Loc::getMessage('SALE_PS_MESSAGE_'.ToUpper($status)),
							'PS_SUM' => DoubleVal($orderData['orderamount'][0]['#']),
							'PS_CURRENCY' => $orderData['ordercurrency'][0]['#'],
							'PS_RESPONSE_DATE' => new DateTime(),
						);
						$serviceResult->setPsData($psData);

						if (
							!$payment->isPaid() &&
							$this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY') == 'Y' &&
							$psData["PS_STATUS"] == "Y" &&
							$payment->getSum() == floatval($psData["PS_SUM"])
						)
						{
							$serviceResult->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
						}
					}
				}
			}
			else
			{
				$serviceResult->addError(new EntityError(Loc::getMessage('SALE_PS_MESSAGE_ERROR_CONNECT_PAY_SYS')));
			}
		}

		return $serviceResult;
	}
}

Zerion Mini Shell 1.0