%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/sale/handlers/paysystem/qiwi/ |
| Current File : /home/bitrix/www/bitrix/modules/sale/handlers/paysystem/qiwi/handler.php |
<?php
namespace Sale\Handlers\PaySystem;
use Bitrix\Main\Entity\EntityError;
use Bitrix\Main\Error;
use Bitrix\Main\Request;
use Bitrix\Main\Type\DateTime;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Sale\PaySystem;
use Bitrix\Sale\Payment;
use Bitrix\Main\Application;
use Bitrix\Sale\PriceMaths;
use Bitrix\Sale\Result;
class QiwiHandler extends PaySystem\ServiceHandler implements PaySystem\ICheckable
{
/**
* @param Payment $payment
* @param Request|null $request
* @return PaySystem\ServiceResult
*/
public function initiatePay(Payment $payment, Request $request = null)
{
$params = array('URL' => $this->getUrl($payment, 'pay'));
$this->setExtraParams($params);
return $this->showTemplate($payment, "template");
}
/**
* @return array
*/
public static function getIndicativeFields()
{
return array('txn_id', 'to', 'from', 'summ');
}
/**
* @param Request $request
* @return mixed
*/
public function getPaymentIdFromRequest(Request $request)
{
return $request->get('bill_id');
}
/**
* @return mixed
*/
protected function getUrlList()
{
return array(
'pay' => array(
self::ACTIVE_URL => 'https://w.qiwi.com/order/external/create.action'
),
'check' => array(
self::ACTIVE_URL => 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}'
)
);
}
/**
* @param Payment $payment
* @param Request $request
* @return PaySystem\ServiceResult
*/
public function processRequest(Payment $payment, Request $request)
{
return $this->processNoticeAction($payment, $request);
}
/**
* @param Payment $payment
* @param Request $request
* @return PaySystem\ServiceResult
*/
private function processNoticeAction(Payment $payment, Request $request)
{
$result = new PaySystem\ServiceResult();
$instance = \Bitrix\Main\Application::getInstance();
$context = $instance->getContext();
$server = $context->getServer();
if ($this->getBusinessValue($payment, 'QIWI_AUTHORIZATION') == 'OPEN')
{
$login = $this->getBusinessValue($payment, 'QIWI_SHOP_ID');
$password = $this->getBusinessValue($payment, 'QIWI_NOTICE_PASSWORD');
if (!$this->checkAuth($login, $password))
{
$result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
return $result;
}
}
else
{
if ($server->get('HTTP_X_API_SIGNATURE') !== null && $this->getBusinessValue($payment, 'QIWI_API_PASSWORD'))
{
$key = $this->getBusinessValue($payment, 'QIWI_API_PASSWORD');
$postParams = $_POST;
ksort($postParams);
$check = base64_encode(sha1($key, implode("|", array_values($postParams))));
if ($check != $server->get('HTTP_X_API_SIGNATURE'))
{
$result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
return $result;
}
}
else
{
$result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
return $result;
}
}
$fields = array(
"PS_STATUS" => $request->get('status') == "paid" ? "Y" : "N",
"PS_STATUS_CODE" => substr($request->get('status'), 0, 5),
"PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_STATUS_MESSAGE_" . strtoupper($_POST['status'])),
"PS_RESPONSE_DATE" => new DateTime(),
"PS_SUM" => (double)$request->get('amount'),
"PS_CURRENCY" => $request->get('ccy'),
"PS_STATUS_DESCRIPTION" => ""
);
if ((int)$request->get('error') > 0)
{
$paidInfo['PS_STATUS_DESCRIPTION'] = "Error: ".Loc::getMessage("SALE_HPS_QIWI_ERROR_CODE_".$request->get('error'));
$result->setPsData($fields);
$result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_OTHER'));
return $result;
}
foreach($_POST as $key => $value)
$fields['PS_STATUS_DESCRIPTION'] .= $key.':'.$value.', ';
$result->setPsData($fields);
$changeStatusPay = $this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY') == "Y";
if ($request->get('status') == "paid" && $changeStatusPay)
{
$result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
$result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_NONE'));
}
return $result;
}
/**
* @param Payment $payment
* @return bool
*/
protected function isTestMode(Payment $payment = null)
{
return false;
}
/**
* @return array
*/
public function getCurrencyList()
{
return array('RUB', 'USD');
}
/**
* @param PaySystem\ServiceResult $result
* @param Request $request
* @return mixed
*/
public function sendResponse(PaySystem\ServiceResult $result, Request $request)
{
global $APPLICATION;
$APPLICATION->RestartBuffer();
$data = $result->getData();
header("Content-Type: text/xml");
header("Pragma: no-cache");
$xml = '<?xml version="1.0" encoding="UTF-8"?><result><result_code>'.$this->getErrorCodeValue($data['CODE']).'</result_code></result>';
$charsetConverter = \CharsetConverter::getInstance();
$instance = Application::getInstance();
$context = $instance->getContext();
$culture = $context->getCulture();
$siteCharset = $culture->getCharset();
echo $charsetConverter->ConvertCharset($xml, $siteCharset, "utf-8");
die();
}
/**
* @return bool|null|string
*/
protected function getAuthHeader()
{
$instance = \Bitrix\Main\Application::getInstance();
$context = $instance->getContext();
$server = $context->getServer();
$incomingToken = false;
if ($server->get("REMOTE_USER") !== null)
{
$incomingToken = $server->get("REMOTE_USER");
}
elseif ($server->get("REDIRECT_REMOTE_USER") !== null)
{
$incomingToken = $server->get("REDIRECT_REMOTE_USER");
}
elseif ($server->get("HTTP_AUTHORIZATION") !== null)
{
$incomingToken = $server->get("HTTP_AUTHORIZATION");
}
elseif (function_exists("apache_request_headers"))
{
$headers = \apache_request_headers();
if(array_key_exists("Authorization", $headers))
$incomingToken = $headers["Authorization"];
}
return $incomingToken;
}
/**
* @param $login
* @param $password
* @return bool
*/
protected function checkAuth($login, $password)
{
if(strlen($password) == 0)
return false;
$header = $this->getAuthHeader();
if(!$header)
return false;
$check = 'Basic '.base64_encode($login.':'.$password);
return $header == $check;
}
/**
* @param $code
* @return mixed
*/
protected function getErrorCodeValue($code)
{
$codes = array(
'QIWI_WALLET_ERROR_CODE_NONE' => 0,
'QIWI_WALLET_ERROR_CODE_BAD_REQUEST' => 5,
'QIWI_WALLET_ERROR_CODE_BUSY' => 13,
'QIWI_WALLET_ERROR_CODE_AUTH' => 150,
'QIWI_WALLET_ERROR_CODE_NOT_FOUND' => 210,
'QIWI_WALLET_ERROR_CODE_EXISTS' => 215,
'QIWI_WALLET_ERROR_CODE_TOO_LOW' => 241,
'QIWI_WALLET_ERROR_CODE_TOO_HIGH' => 242,
'QIWI_WALLET_ERROR_CODE_NO_PURSE' => 298,
'QIWI_WALLET_ERROR_CODE_OTHER' => 300
);
return $codes[$code];
}
/**
* @param Payment $payment
* @return PaySystem\ServiceResult
*/
public function check(Payment $payment)
{
$result = new PaySystem\ServiceResult();
$url = $this->getUrl($payment, 'check');
$request = new HttpClient();
$request->setAuthorization($this->getBusinessValue($payment, 'QIWI_API_LOGIN'), $this->getBusinessValue($payment, 'QIWI_API_PASSWORD'));
$request->setHeader("Accept", "text/json");
$request->setCharset("utf-8");
$response = $request->get(str_replace(
array("{prv_id}", "{bill_id}"),
array($this->getBusinessValue($payment, 'QIWI_SHOP_ID'), $this->getBusinessValue($payment, 'PAYMENT_ID')),
$url
));
if($response === false)
{
$result->addErrors($request->getError());
return $result;
}
$response = (array)json_decode($response);
if(!$response || !isset($response['response']))
{
$result->addErrors($request->getError());
return $result;
}
$response = (array)$response['response'];
if ((int)$response['result_code'])
{
$psData = array(
"PS_STATUS" => 'N',
"PS_STATUS_CODE" => $response['result_code'],
"PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_ERROR_CODE_" . $response['result_code']),
"PS_STATUS_DESCRIPTION" => isset($response['description']) ? $response['description'] : "",
"PS_RESPONSE_DATE" => new DateTime()
);
$result->setPsData($psData);
}
elseif(isset($response['bill']))
{
$bill = (array)$response['bill'];
$psData = array(
"PS_STATUS" => $bill['status'] == "paid" ? "Y" : "N",
"PS_STATUS_CODE" => substr($bill['status'], 0, 10),
"PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_STATUS_MESSAGE_" . strtoupper($bill['status'])),
"PS_RESPONSE_DATE" => new DateTime(),
"PS_SUM" => (double)$bill['amount'],
"PS_CURRENCY" => $bill['ccy'],
'PS_STATUS_DESCRIPTION' => ''
);
foreach($bill as $key => $value)
$psData['PS_STATUS_DESCRIPTION'] .= "{$key}:{$value}, ";
$billAmount = PriceMaths::roundPrecision($bill['amount']);
$paymentSum = PriceMaths::roundPrecision($payment->getSum());
if($bill['status'] == "paid" && $billAmount == $paymentSum && $this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY'))
$result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
$result->setPsData($psData);
}
return $result;
}
}