1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
handler.php
См. документацию.
1<?php
2
3namespace Sale\Handlers\PaySystem;
4
5use Bitrix\Main;
6use Bitrix\Main\Request;
7use Bitrix\Main\Type\DateTime;
8use Bitrix\Main\Localization\Loc;
9use Bitrix\Main\Web\HttpClient;
10use Bitrix\Sale\PaySystem;
11use Bitrix\Sale\Payment;
12use Bitrix\Main\Application;
13use Bitrix\Sale\PriceMaths;
14
15class QiwiHandler extends PaySystem\ServiceHandler implements PaySystem\ICheckable
16{
22 public function initiatePay(Payment $payment, Request $request = null)
23 {
24 if ($request === null)
25 {
26 $request = Main\Context::getCurrent()->getRequest();
27 }
28
29 $phone = $this->normalizePhone($this->getPhone($payment, $request));
30 if (!preg_match('/^\+7\d{10}$/', $phone))
31 {
32 $params = [
33 'PAYMENT_ID' => $payment->getId(),
34 'PAYSYSTEM_ID' => $this->service->getField('ID'),
35 'BUYER_PERSON_PHONE' => $phone,
36 'RETURN_URL' => $this->getSuccessUrl($payment),
37 ];
38 $this->setExtraParams($params);
39 return $this->showTemplate($payment, 'template_query');
40 }
41
42 $params = [
43 'URL' => $this->getUrl($payment, 'pay'),
44 'BUYER_PERSON_PHONE' => $phone,
45 'QIWI_SUCCESS_URL' => $this->getSuccessUrl($payment),
46 'QIWI_FAIL_URL' => $this->getFailUrl($payment),
47 ];
48 $this->setExtraParams($params);
49 return $this->showTemplate($payment, 'template');
50 }
51
57 private function getPhone(Payment $payment, Request $request): string
58 {
59 $newPhone = trim((string)$request->getPost('NEW_PHONE'));
60 if ($newPhone !== '')
61 {
62 return $newPhone;
63 }
64
65 return (string)$this->getBusinessValue($payment, 'BUYER_PERSON_PHONE');
66 }
67
72 private function normalizePhone($number)
73 {
74 $normalizedNumber = \NormalizePhone($number);
75 if ($normalizedNumber)
76 {
77 return '+'.$normalizedNumber;
78 }
79
80 return $number;
81 }
82
86 public static function getIndicativeFields()
87 {
88 return array('txn_id', 'to', 'from', 'summ');
89 }
90
95 public function getPaymentIdFromRequest(Request $request)
96 {
97 return $request->get('bill_id');
98 }
99
103 protected function getUrlList()
104 {
105 return array(
106 'pay' => array(
107 self::ACTIVE_URL => 'https://w.qiwi.com/order/external/create.action'
108 ),
109 'check' => array(
110 self::ACTIVE_URL => 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}'
111 )
112 );
113 }
114
120 public function processRequest(Payment $payment, Request $request)
121 {
122 return $this->processNoticeAction($payment, $request);
123 }
124
130 private function processNoticeAction(Payment $payment, Request $request)
131 {
132 $result = new PaySystem\ServiceResult();
133
134 $instance = \Bitrix\Main\Application::getInstance();
135 $context = $instance->getContext();
136 $server = $context->getServer();
137
138 if ($this->getBusinessValue($payment, 'QIWI_AUTHORIZATION') == 'OPEN')
139 {
140 $login = $this->getBusinessValue($payment, 'QIWI_SHOP_ID');
141 $password = $this->getBusinessValue($payment, 'QIWI_NOTICE_PASSWORD');
142
143 if (!$this->checkAuth($login, $password))
144 {
145 $result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
146 return $result;
147 }
148 }
149 else
150 {
151 if ($server->get('HTTP_X_API_SIGNATURE') !== null && $this->getBusinessValue($payment, 'QIWI_API_PASSWORD'))
152 {
153 $key = $this->getBusinessValue($payment, 'QIWI_API_PASSWORD');
154 $postParams = $_POST;
155 ksort($postParams);
156 $check = base64_encode(sha1($key, implode("|", array_values($postParams))));
157
158 if ($check != $server->get('HTTP_X_API_SIGNATURE'))
159 {
160 $result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
161 return $result;
162 }
163 }
164 else
165 {
166 $result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_AUTH'));
167 return $result;
168 }
169 }
170
171
172 $fields = array(
173 "PS_STATUS" => $request->get('status') == "paid" ? "Y" : "N",
174 "PS_STATUS_CODE" => mb_substr($request->get('status'), 0, 5),
175 "PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_STATUS_MESSAGE_".mb_strtoupper($_POST['status'])),
176 "PS_RESPONSE_DATE" => new DateTime(),
177 "PS_SUM" => (double)$request->get('amount'),
178 "PS_CURRENCY" => $request->get('ccy'),
179 "PS_STATUS_DESCRIPTION" => ""
180 );
181
182 if ((int)$request->get('error') > 0)
183 {
184 $paidInfo['PS_STATUS_DESCRIPTION'] = "Error: ".Loc::getMessage("SALE_HPS_QIWI_ERROR_CODE_".$request->get('error'));
185 $result->setPsData($fields);
186 $result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_OTHER'));
187
188 return $result;
189 }
190
191 foreach($_POST as $key => $value)
192 $fields['PS_STATUS_DESCRIPTION'] .= $key.':'.$value.', ';
193
194 $result->setPsData($fields);
195
196 $changeStatusPay = $this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY') == "Y";
197
198 if ($request->get('status') == "paid" && $changeStatusPay)
199 {
200 $result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
201 $result->setData(array('CODE' => 'QIWI_WALLET_ERROR_CODE_NONE'));
202 }
203
204 return $result;
205 }
206
211 protected function isTestMode(Payment $payment = null)
212 {
213 return false;
214 }
215
219 public function getCurrencyList()
220 {
221 return array('RUB', 'USD');
222 }
223
229 public function sendResponse(PaySystem\ServiceResult $result, Request $request)
230 {
231 global $APPLICATION;
232
233 $APPLICATION->RestartBuffer();
234
235 $data = $result->getData();
236
237 header("Content-Type: text/xml");
238 header("Pragma: no-cache");
239 $xml = '<?xml version="1.0" encoding="UTF-8"?><result><result_code>'.$this->getErrorCodeValue($data['CODE']).'</result_code></result>';
240
241 echo $xml;
242 die();
243 }
244
248 protected function getAuthHeader()
249 {
250 $instance = \Bitrix\Main\Application::getInstance();
251 $context = $instance->getContext();
252 $server = $context->getServer();
253
254 $incomingToken = false;
255 if ($server->get("REMOTE_USER") !== null)
256 {
257 $incomingToken = $server->get("REMOTE_USER");
258 }
259 elseif ($server->get("REDIRECT_REMOTE_USER") !== null)
260 {
261 $incomingToken = $server->get("REDIRECT_REMOTE_USER");
262 }
263 elseif ($server->get("HTTP_AUTHORIZATION") !== null)
264 {
265 $incomingToken = $server->get("HTTP_AUTHORIZATION");
266 }
267 elseif (function_exists("apache_request_headers"))
268 {
269 $headers = \apache_request_headers();
270
271 if(array_key_exists("Authorization", $headers))
272 $incomingToken = $headers["Authorization"];
273 }
274 return $incomingToken;
275 }
276
282 protected function checkAuth($login, $password)
283 {
284 if($password == '')
285 return false;
286
287 $header = $this->getAuthHeader();
288
289 if(!$header)
290 return false;
291
292 $check = 'Basic '.base64_encode($login.':'.$password);
293 return $header == $check;
294 }
295
300 protected function getErrorCodeValue($code)
301 {
302 $codes = array(
303 'QIWI_WALLET_ERROR_CODE_NONE' => 0,
304 'QIWI_WALLET_ERROR_CODE_BAD_REQUEST' => 5,
305 'QIWI_WALLET_ERROR_CODE_BUSY' => 13,
306 'QIWI_WALLET_ERROR_CODE_AUTH' => 150,
307 'QIWI_WALLET_ERROR_CODE_NOT_FOUND' => 210,
308 'QIWI_WALLET_ERROR_CODE_EXISTS' => 215,
309 'QIWI_WALLET_ERROR_CODE_TOO_LOW' => 241,
310 'QIWI_WALLET_ERROR_CODE_TOO_HIGH' => 242,
311 'QIWI_WALLET_ERROR_CODE_NO_PURSE' => 298,
312 'QIWI_WALLET_ERROR_CODE_OTHER' => 300
313 );
314
315 return $codes[$code];
316 }
317
322 public function check(Payment $payment)
323 {
324 $result = new PaySystem\ServiceResult();
325
326 $url = $this->getUrl($payment, 'check');
327
328 $request = new HttpClient();
329 $request->setAuthorization($this->getBusinessValue($payment, 'QIWI_API_LOGIN'), $this->getBusinessValue($payment, 'QIWI_API_PASSWORD'));
330 $request->setHeader("Accept", "text/json");
331 $request->setCharset("utf-8");
332
333 $response = $request->get(str_replace(
334 array("{prv_id}", "{bill_id}"),
335 array($this->getBusinessValue($payment, 'QIWI_SHOP_ID'), $this->getBusinessValue($payment, 'PAYMENT_ID')),
336 $url
337 ));
338
339 if($response === false)
340 {
341 $result->addErrors($request->getError());
342 return $result;
343 }
344
345 $response = (array)json_decode($response);
346 if(!$response || !isset($response['response']))
347 {
348 $result->addErrors($request->getError());
349 return $result;
350 }
351
352 $response = (array)$response['response'];
353 if ((int)$response['result_code'])
354 {
355 $psData = array(
356 "PS_STATUS" => 'N',
357 "PS_STATUS_CODE" => $response['result_code'],
358 "PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_ERROR_CODE_" . $response['result_code']),
359 "PS_STATUS_DESCRIPTION" => isset($response['description']) ? $response['description'] : "",
360 "PS_RESPONSE_DATE" => new DateTime()
361 );
362
363 $result->setPsData($psData);
364 }
365 elseif(isset($response['bill']))
366 {
367 $bill = (array)$response['bill'];
368
369 $psData = array(
370 "PS_STATUS" => $bill['status'] == "paid" ? "Y" : "N",
371 "PS_STATUS_CODE" => mb_substr($bill['status'], 0, 10),
372 "PS_STATUS_MESSAGE" => Loc::getMessage("SALE_QWH_STATUS_MESSAGE_".mb_strtoupper($bill['status'])),
373 "PS_RESPONSE_DATE" => new DateTime(),
374 "PS_SUM" => (double)$bill['amount'],
375 "PS_CURRENCY" => $bill['ccy'],
376 'PS_STATUS_DESCRIPTION' => ''
377 );
378
379 foreach($bill as $key => $value)
380 $psData['PS_STATUS_DESCRIPTION'] .= "{$key}:{$value}, ";
381
382 $billAmount = PriceMaths::roundPrecision($bill['amount']);
383 $paymentSum = PriceMaths::roundPrecision($payment->getSum());
384
385 if($bill['status'] == "paid" && $billAmount == $paymentSum && $this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY'))
386 $result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
387
388 $result->setPsData($psData);
389 }
390
391 return $result;
392 }
393
398 private function getSuccessUrl(Payment $payment)
399 {
400 return $this->getBusinessValue($payment, 'QIWI_SUCCESS_URL') ?: $this->service->getContext()->getUrl();
401 }
402
407 private function getFailUrl(Payment $payment)
408 {
409 return $this->getBusinessValue($payment, 'QIWI_FAIL_URL') ?: $this->service->getContext()->getUrl();
410 }
411}
global $APPLICATION
Определения include.php:80
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
$login
Определения change_password.php:8
getUrl(Payment $payment=null, $action)
Определения baseservicehandler.php:343
showTemplate(Payment $payment=null, $template='')
Определения baseservicehandler.php:59
getBusinessValue(Payment $payment=null, $code)
Определения baseservicehandler.php:184
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$postParams
Определения iblock_catalog_edit.php:50
$context
Определения csv_new_setup.php:223
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$value
Определения Param.php:39
$password
Определения mysql_to_pgsql.php:34
$payment
Определения payment.php:14
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$instance
Определения ps_b24_final.php:14
if(empty($signedUserToken)) $key
Определения quickway.php:257
die
Определения quickway.php:367
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$response
Определения result.php:21
$url
Определения iframe.php:7
$fields
Определения yandex_run.php:501