%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/sale/handlers/paysystem/assist/ |
| 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;
}
}