1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
handler.php
См. документацию.
1<?php
2namespace Sale\Handlers\PaySystem;
3
4use Bitrix\Main\Error;
5use Bitrix\Main\Request;
6use Bitrix\Main\Context;
7use Bitrix\Main\Type\DateTime;
8use Bitrix\Main\Localization\Loc;
9use Bitrix\Main\Web;
10use Bitrix\Sale\PaySystem;
11use Bitrix\Sale\Payment;
12use Bitrix\Sale\PriceMaths;
13use Bitrix\Sale\Cashbox;
14
15Loc::loadMessages(__FILE__);
16
21class RoboxchangeHandler
24{
25 use PaySystem\Cashbox\CheckTrait;
26
27 public const TEMPLATE_TYPE_CHECKOUT = 'checkout';
28 public const TEMPLATE_TYPE_IFRAME = 'iframe';
29
30 protected const DEFAULT_TEMPLATE_NAME = 'template';
31
32 private const ANALYTICS_LABEL_RU_VALUE = 'api_1c-bitrix';
33 private const ANALYTICS_LABEL_KZ_VALUE = 'api_1c-bitrix_kz';
34
41 public function initiatePay(Payment $payment, Request $request = null)
42 {
43 if ($request === null)
44 {
45 $request = Context::getCurrent()->getRequest();
46 }
47
48 $receipt = null;
49 if ($this->service->canPrintCheckSelf($payment))
50 {
51 $receiptResult = $this->getReceipt($payment);
52 if (!$receiptResult->isSuccess())
53 {
54 $result = new PaySystem\ServiceResult();
55 $result->addErrors($receiptResult->getErrors());
56 return $result;
57 }
58
59 $receipt = self::encode($receiptResult->getData());
60
61 PaySystem\Logger::addDebugInfo(__CLASS__.": receipt = {$receipt}");
62 }
63
64 $additionalUserFields = $this->getAdditionalUserFields($payment, $request);
65
66 $params = [
67 'ROBOXCHANGE_SHOPLOGIN' => $this->getBusinessValue($payment, 'ROBOXCHANGE_SHOPLOGIN'),
68 'URL' => $this->getUrl($payment, 'pay'),
69 'PS_MODE' => self::getHandlerModeAlias($this->service->getField('PS_MODE')),
70 'SIGNATURE_VALUE' => $this->getSignatureValue($payment, $receipt, $additionalUserFields),
71 'ROBOXCHANGE_ORDERDESCR' => $this->getOrderDescription($payment),
72 'PAYMENT_ID' => $payment->getId(),
73 'SUM' => PriceMaths::roundPrecision($payment->getSum()),
74 'CURRENCY' => $payment->getField('CURRENCY'),
75 'OUT_SUM_CURRENCY' => $this->getOutSumCurrency($payment),
76 'ADDITIONAL_USER_FIELDS' => $additionalUserFields,
77 'RECEIPT' => $receipt,
78 ];
79 $this->setExtraParams($params);
80
81 return $this->showTemplate($payment, $this->getTemplateName($payment));
82 }
83
88 private function getAdditionalUserFields(Payment $payment, Request $request): array
89 {
90 $countryCode = $this->getCountryCode($payment);
91
92 $additionalUserFields = [
93 'SHP_BX_PAYMENT_CODE' => $payment->getField('XML_ID'),
94 'SHP_BX_PAYSYSTEM_CODE' => $this->service->getField('ID'),
95 'SHP_HANDLER' => 'ROBOXCHANGE',
96 'SHP_PARTNER' => $countryCode === 'RU' ? self::ANALYTICS_LABEL_RU_VALUE : self::ANALYTICS_LABEL_KZ_VALUE,
97 'SHP_BX_REDIRECT_URL' => $request->get('SHP_BX_REDIRECT_URL') ?: $this->getReturnUrl(),
98 ];
99 ksort($additionalUserFields);
100
101 return $additionalUserFields;
102 }
103
110 private function getSignatureValue(Payment $payment, string $receipt = null, array $additionalUserFields = []): string
111 {
112 $passwordCode = 'ROBOXCHANGE_SHOPPASSWORD';
113 if ($this->isTestMode($payment))
114 {
115 $passwordCode .= '_TEST';
116 }
117
118 $shopPassword1 = (string)$this->getBusinessValue($payment, $passwordCode);
119
120 $signaturePartList = [
121 $this->getBusinessValue($payment, 'ROBOXCHANGE_SHOPLOGIN'),
122 $payment->getSum(),
123 $payment->getId(),
124 ];
125
126 if ($outSumCurrency = $this->getOutSumCurrency($payment))
127 {
128 $signaturePartList[] = $outSumCurrency;
129 }
130
131 if ($receipt)
132 {
133 $signaturePartList[] = $receipt;
134 }
135
136 $signaturePartList[] = $shopPassword1;
137
138 if ($additionalUserFields)
139 {
140 foreach ($additionalUserFields as $fieldName => $fieldValue)
141 {
142 $signaturePartList[] = implode('=', [$fieldName, $fieldValue]);
143 }
144 }
145
146 return md5(implode(':', $signaturePartList));
147 }
148
153 private function getOrderDescription(Payment $payment)
154 {
155 return mb_substr($this->getBusinessValue($payment, 'ROBOXCHANGE_ORDERDESCR'), 0, 100);
156 }
157
162 private function getTemplateName(Payment $payment): string
163 {
164 $templateType = (string)$this->getBusinessValue($payment, 'ROBOXCHANGE_TEMPLATE_TYPE');
165 if (empty($templateType) || $templateType === self::TEMPLATE_TYPE_CHECKOUT)
166 {
167 return static::DEFAULT_TEMPLATE_NAME;
168 }
169
170 return $templateType;
171 }
172
176 public static function getIndicativeFields()
177 {
178 return ['SHP_HANDLER' => 'ROBOXCHANGE'];
179 }
180
186 protected static function isMyResponseExtended(Request $request, $paySystemId)
187 {
188 $id = (int)$request->get('SHP_BX_PAYSYSTEM_CODE');
189 return $id === (int)$paySystemId;
190 }
191
197 private function isCorrectHash(Payment $payment, Request $request): bool
198 {
199 $passwordCode2 = 'ROBOXCHANGE_SHOPPASSWORD2';
200 if ($this->isTestMode($payment))
201 {
202 $passwordCode2 .= '_TEST';
203 }
204
205 $shopPassword2 = (string)$this->getBusinessValue($payment, $passwordCode2);
206
207 $signaturePartList = [
208 $request->get('OutSum'),
209 $request->get('InvId'),
210 $shopPassword2,
211 ];
212
213 foreach ($this->getAdditionalUserFields($payment, $request) as $fieldName => $fieldValue)
214 {
215 $signaturePartList[] = implode('=', [$fieldName, $fieldValue]);
216 }
217
218 $hash = md5(implode(':', $signaturePartList));
219
220 return mb_strtoupper($hash) === mb_strtoupper($request->get('SignatureValue'));
221 }
222
227 public function getPaymentIdFromRequest(Request $request)
228 {
229 return $request->get('InvId');
230 }
231
232 protected function getUrl(Payment $payment = null, $action): string
233 {
234 $url = parent::getUrl($payment, $action);
235
236 if ($payment !== null)
237 {
238 $url = str_replace('#domain#', $this->getDomain($payment), $url);
239 }
240
241 return $url;
242 }
243
247 protected function getUrlList()
248 {
249 return [
250 'pay' => [
251 self::ACTIVE_URL => 'https://auth.robokassa.#domain#/Merchant/Index.aspx',
252 ],
253 ];
254 }
255
256 private function getDomain(Payment $payment): string
257 {
258 $countryCode = $this->getCountryCode($payment);
259 return mb_strtolower($countryCode);
260 }
261
271 public function processRequest(Payment $payment, Request $request)
272 {
273 $result = new PaySystem\ServiceResult();
274
275 if ($this->isCorrectHash($payment, $request))
276 {
277 return $this->processNoticeAction($payment, $request);
278 }
279
280 $result->addError(new Error(Loc::getMessage('SALE_HPS_ROBOXCHANGE_INCORRECT_HASH')));
281
282 return $result;
283 }
284
294 private function processNoticeAction(Payment $payment, Request $request): PaySystem\ServiceResult
295 {
296 $result = new PaySystem\ServiceResult();
297
298 $psStatusDescription = Loc::getMessage('SALE_HPS_ROBOXCHANGE_RES_NUMBER').": ".$request->get('InvId');
299 $psStatusDescription .= "; ".Loc::getMessage('SALE_HPS_ROBOXCHANGE_RES_DATEPAY').": ".date("d.m.Y H:i:s");
300
301 if ($request->get("IncCurrLabel") !== null)
302 {
303 $psStatusDescription .= "; ".Loc::getMessage('SALE_HPS_ROBOXCHANGE_RES_PAY_TYPE').": ".$request->get("IncCurrLabel");
304 }
305
306 $result->setPsData([
307 "PS_STATUS" => "Y",
308 "PS_STATUS_CODE" => "-",
309 "PS_STATUS_DESCRIPTION" => $psStatusDescription,
310 "PS_STATUS_MESSAGE" => Loc::getMessage('SALE_HPS_ROBOXCHANGE_RES_PAYED'),
311 "PS_SUM" => $payment->getSum(),
312 "PS_CURRENCY" => $payment->getField('CURRENCY'),
313 "PS_RESPONSE_DATE" => new DateTime(),
314 ]);
315
316 PaySystem\Logger::addDebugInfo(
317 __CLASS__.': PS_CHANGE_STATUS_PAY='.$this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY')
318 );
319
320 if ($this->getBusinessValue($payment, 'PS_CHANGE_STATUS_PAY') === 'Y')
321 {
322 $result->setOperationType(PaySystem\ServiceResult::MONEY_COMING);
323 }
324
325 return $result;
326 }
327
332 protected function isTestMode(Payment $payment = null)
333 {
334 return $this->getBusinessValue($payment, 'PS_IS_TEST') === 'Y';
335 }
336
340 public function getCurrencyList()
341 {
342 return ['RUB', 'KZT', 'USD', 'EUR'];
343 }
344
349 private function getOutSumCurrency(Payment $payment): string
350 {
351 $countryCode = $this->getCountryCode($payment);
352
353 $currency = (string)$payment->getField('CURRENCY');
354 $currency = ($currency === 'RUB') ? 'RUR' : $currency;
355
356 if (
357 ($countryCode === 'RU' && $currency === 'RUR')
358 || ($countryCode === 'KZ' && $currency === 'KZT')
359 )
360 {
361 $currency = '';
362 }
363
364 return $currency;
365 }
366
371 private function getCountryCode(Payment $payment): string
372 {
373 $countryCode = (string)$this->getBusinessValue($payment, 'ROBOXCHANGE_COUNTRY_CODE');
374 return $countryCode ?: 'RU';
375 }
376
382 public function sendResponse(PaySystem\ServiceResult $result, Request $request)
383 {
384 global $APPLICATION;
385 if ($result->isResultApplied())
386 {
387 $APPLICATION->RestartBuffer();
388 echo 'OK'.$request->get('InvId');
389 }
390 }
391
395 public static function getHandlerModeList()
396 {
397 return PaySystem\Manager::getHandlerDescription('roboxchange')['HANDLER_MODE_LIST'];
398 }
399
400 private static function getHandlerModeAlias(string $psMode): string
401 {
402 $defaultAlias = 'BankCard';
403
404 $aliases = [
405 'bank_card' => 'BankCard',
406 'widget' => '',
407 'sbp' => 'SBP',
408 'apple_pay' => 'ApplePay',
409 'google_pay' => 'GooglePay',
410 'samsung_pay' => 'SamsungPay',
411 ];
412
413 return $aliases[$psMode] ?? $defaultAlias;
414 }
415
416 private function getReceipt(Payment $payment): PaySystem\ServiceResult
417 {
418 $result = new PaySystem\ServiceResult();
419
420 $checkQueryResult = $this->buildCheckQuery($payment);
421 if ($checkQueryResult->isSuccess())
422 {
423 $receiptData = $checkQueryResult->getData();
424 if (!empty($receiptData['items']) && !empty($receiptData['sno']))
425 {
426 $result->setData([
427 'sno' => $receiptData['sno'],
428 'items' => $receiptData['items'],
429 ]);
430 }
431 else
432 {
433 $result->addError(PaySystem\Error::create(Loc::getMessage('SALE_HPS_ROBOXCHANGE_ERROR_EMPTY_RECEIPT')));
434 }
435 }
436 else
437 {
438 $result->addErrors($checkQueryResult->getErrors());
439 }
440
441 return $result;
442 }
443
449 private static function encode(array $data)
450 {
451 return Web\Json::encode($data, JSON_UNESCAPED_UNICODE);
452 }
453
454 public static function getCashboxClass(): string
455 {
456 return '\\'.Cashbox\CashboxRobokassa::class;
457 }
458
459 private function getReturnUrl(): string
460 {
461 return $this->service->getContext()->getUrl();
462 }
463}
$hash
Определения ajax_redirector.php:8
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
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
trait Error
Определения error.php:11
$payment
Определения payment.php:14
$currency
Определения template.php:266
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$action
Определения file_dialog.php:21
$url
Определения iframe.php:7