1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
handler.php
См. документацию.
1<?php
2namespace Sale\Handlers\PaySystem;
3
4use Bitrix\Crm;
5use Bitrix\Crm\EntityPreset;
6use Bitrix\Crm\EntityRequisite;
7use Bitrix\Main;
8use Bitrix\Main\Loader;
9use Bitrix\Main\Localization\Loc;
10use Bitrix\Main\PhoneNumber;
11use Bitrix\Main\Request;
12use Bitrix\Main\Web;
13use Bitrix\Sale\BasketItem;
14use Bitrix\Sale\Order;
15use Bitrix\Sale\PayableBasketItem;
16use Bitrix\Sale\Payment;
17use Bitrix\Sale\PaymentCollection;
18use Bitrix\Sale\PaySystem;
19use Bitrix\Sale\PriceMaths;
20use Bitrix\Sale\Services\Base\RestrictionInfoCollection;
21use Bitrix\Sale\Services\PaySystem\Restrictions\RestrictableServiceHandler;
22use Bitrix\Sale\Services\PaySystem\Restrictions\RestrictionCurrencyTrait;
23use Bitrix\Sale\Services\PaySystem\Restrictions\RestrictionPersonTypeTrait;
24
25class TBankBusinessHandler extends PaySystem\BaseServiceHandler implements RestrictableServiceHandler
26{
28
29 protected const SANDBOX_URL = 'https://business.tbank.ru/openapi/sandbox/';
30 protected const PRODUCTION_URL = 'https://business.tbank.ru/openapi/';
31
32 public const ERROR_CODE_SYSTEM_FAILURE = -1;
33 public const ERROR_CODE_RESPONSE_FAILURE = -2;
34 public const ERROR_CODE_BAD_INVOICE_SUM = -3;
35 public const ERROR_CODE_BAD_INVOICE_PARAMS = -4;
36
37 protected const ERROR_STATUS_BAD_JSON = -1;
38
39 protected const PAYMENT_STATUS_DRAFT = 'DRAFT';
40 protected const PAYMENT_STATUS_SUBMITTED = 'SUBMITTED';
41 protected const PAYMENT_STATUS_EXECUTED = 'EXECUTED';
42
43 protected const PAYMENT_CURRENCY_RUB = 'RUB';
44
45 protected const RESPONSE_STATUS_200 = 200;
46 protected const RESPONSE_STATUS_400 = 400;
47 protected const RESPONSE_STATUS_401 = 401;
48 protected const RESPONSE_STATUS_403 = 403;
49 protected const RESPONSE_STATUS_422 = 422;
50 protected const RESPONSE_STATUS_429 = 429;
51 protected const RESPONSE_STATUS_500 = 500;
52
53 protected const RESPONSE_ERROR_INVOICE_NOT_FOUND = 'INVOICE_NOT_FOUND';
54
55 protected const TEMPLATE_INVOICE_INFO = 'template';
56 protected const TEMPLATE_INVOICE_STATUS = 'template_status';
57 protected const TEMPLATE_INVOICE_EXPIRED = 'template_expired';
58
59 public function initiatePay(Payment $payment, ?Request $request = null): PaySystem\ServiceResult
60 {
61 $result = new PaySystem\ServiceResult();
62
63 if (!Loader::includeModule('crm'))
64 {
65 $result->addError(new Main\Error(Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_MODULE_CRM_ABSENT')));
66
67 return $result;
68 }
69
70 $invoiceState = [];
71 if ($payment->getField('PS_INVOICE_ID'))
72 {
73 $checkInvoiceResult = $this->checkInvoiceState($payment);
74 if ($this->isInvalidCheckInvoiceResult($checkInvoiceResult))
75 {
76 return $checkInvoiceResult;
77 }
78 $invoiceState = $checkInvoiceResult->getData();
79 unset($checkInvoiceResult);
80 }
81
82 if ($this->needCreateInvoice($invoiceState))
83 {
84 $createInvoiceResult = $this->createInvoice($payment);
85 if (!$createInvoiceResult->isSuccess())
86 {
87 return $createInvoiceResult;
88 }
89
90 $invoiceState = $createInvoiceResult->getData();
91
92 if (isset($invoiceState['response']['invoiceId']))
93 {
94 $result->setPsData(['PS_INVOICE_ID' => $invoiceState['response']['invoiceId']]);
95 }
96 }
97
98 $template = $this->getTemplateName($payment, $invoiceState);
99
100 $this->setExtraParams(
101 $this->getTemplateParams($payment, $template, $invoiceState)
102 );
103
104 $result->setTemplate($this->showTemplate($payment, $template)->getTemplate());
105
106 return $result;
107 }
108
112 public function getCurrencyList(): array
113 {
114 return [
115 self::PAYMENT_CURRENCY_RUB,
116 ];
117 }
118
125 public function getRestrictionList(): RestrictionInfoCollection
126 {
127 $collection = new RestrictionInfoCollection();
128
129 $this->getRestrictionCurrency($collection);
130
131 return $collection;
132 }
133
139 protected function isTestMode(?Payment $payment = null): bool
140 {
141 return ($this->getBusinessValue($payment, 'TBB_TEST_MODE') === 'Y');
142 }
143
147 public function getClientType($psMode): string
148 {
149 return PaySystem\ClientType::B2B;
150 }
151
155 protected function getUrlList(): array
156 {
157 return [
158 'invoice' => [
159 self::TEST_URL => self::SANDBOX_URL . 'api/v1/invoice/send',
160 self::ACTIVE_URL => self::PRODUCTION_URL.'api/v1/invoice/send',
161 ],
162 'invoiceCheck' => [
163 self::TEST_URL => self::SANDBOX_URL . 'api/v1/openapi/invoice/{invoiceId}/info',
164 self::ACTIVE_URL => self::PRODUCTION_URL . 'api/v1/openapi/invoice/{invoiceId}/info',
165 ],
166 ];
167 }
168
174 protected function getTBankAuthToken(): ?string
175 {
176 if (!Main\Loader::includeModule('seo'))
177 {
178 return null;
179 }
180
181 \Bitrix\Seo\Service::clearClientsCache();
182 $authAdapter = \Bitrix\Seo\Checkout\Service::getAuthAdapter(\Bitrix\Seo\Checkout\Service::TYPE_TBANK_BUSINESS);
183
184 return $authAdapter->getToken();
185 }
186
192 protected function getTBankTestToken(): string
193 {
194 return 'TinkoffOpenApiSandboxSecretToken';
195 }
196
203 protected function getHeaders(Payment $payment): array
204 {
205 $token =
206 $this->isTestMode($payment)
207 ? $this->getTBankTestToken()
208 : $this->getTBankAuthToken()
209 ;
210
211 return [
212 'Content-Type' => 'application/json',
213 'Accept' => 'application/json',
214 'Authorization' => 'Bearer ' . $token,
215 ];
216 }
217
223 protected function getTemplateName(Payment $payment, array $invoiceStatus = []): string
224 {
225 $template = null;
226
227 if (
228 $this->isExistDatePayBefore($payment)
229 && !$this->isValidDatePayBefore($payment)
230 )
231 {
232 $template = self::TEMPLATE_INVOICE_EXPIRED;
233 }
234 else
235 {
236 $currentStatus = ($invoiceStatus['response']['status'] ?? '');
237 if ($this->isValidPaymentStatus($currentStatus))
238 {
239 $template = self::TEMPLATE_INVOICE_STATUS;
240 }
241 }
242
243 return $template ?? self::TEMPLATE_INVOICE_INFO;
244 }
245
246 protected function getTemplateParams(Payment $payment, $template, $invoiceState = []) : array
247 {
248 $result = [];
249 switch ($template)
250 {
251 case self::TEMPLATE_INVOICE_INFO:
252 $result = $this->getInvoiceSumTemplateParams($payment);
253
254 if (isset($invoiceState['response']['pdfUrl']))
255 {
256 $result['INVOICE_PDF_URL'] = $invoiceState['response']['pdfUrl'];
257 }
258 if (isset($invoiceState['response']['incomingInvoiceUrl']))
259 {
260 $result['INVOICE_PERSONAL_ACCOUNT_URL'] = $invoiceState['response']['incomingInvoiceUrl'];
261 }
262
263 if (isset($invoiceState['params']['dueDate']))
264 {
265 $dueDate = new Main\Type\Date(
266 $invoiceState['params']['dueDate'],
267 'Y-m-d'
268 );
269 $result['INVOICE_DUE_DATE'] = $dueDate->toString();
270 }
271 break;
272 case self::TEMPLATE_INVOICE_STATUS:
273 $result = $this->getInvoiceSumTemplateParams($payment);
274
275 $result['INVOICE_STATUS'] = $this->getInvoiceStatusTitle(
276 $invoiceState['response']['status'] ?? ''
277 );
278 break;
279 }
280
281 return $result;
282 }
283
290 protected function getInvoiceSumTemplateParams(Payment $payment): array
291 {
292 Loader::includeModule('currency');
293
294 $result = [];
295
296 $invoiceSum = $this->getInvoiceSum($payment);
297 if ($invoiceSum !== null)
298 {
299 $result['INVOICE_SUM'] = $invoiceSum;
300 $result['INVOICE_SUM_FORMATTED'] = \CCurrencyLang::CurrencyFormat(
302 self::PAYMENT_CURRENCY_RUB
303 );
304 }
305
306 return $result;
307 }
308
313 private static function encode(array $data): bool|string
314 {
315 try
316 {
317 return Web\Json::encode($data, JSON_UNESCAPED_UNICODE);
318 }
319 catch (Main\ArgumentException)
320 {
321 return false;
322 }
323 }
324
329 private static function decode(string $data): mixed
330 {
331 try
332 {
333 return Web\Json::decode($data);
334 }
335 catch (Main\ArgumentException)
336 {
337 return false;
338 }
339 }
340
341 protected function checkInvoiceState(Payment $payment): PaySystem\ServiceResult
342 {
343 $url = str_replace(
344 '{invoiceId}',
345 $payment->getField('PS_INVOICE_ID'),
346 $this->getUrl($payment, 'invoiceCheck')
347 );
348
349 return $this->send(
350 Web\Http\Method::GET,
351 $url,
352 $this->getHeaders($payment)
353 );
354 }
355
356 protected function isInvalidCheckInvoiceResult(PaySystem\ServiceResult $result): bool
357 {
358 if ($result->isSuccess())
359 {
360 return false;
361 }
362
363 if ($this->isInvoiceNotFound($result->getData()))
364 {
365 return false;
366 }
367
368 return true;
369 }
370
371 protected function isInvoiceNotFound(array $invoiceState): bool
372 {
373 $status = (int)($invoiceState['status'] ?? 0);
374 $errorCode = $invoiceState['response']['errorCode'] ?? '';
375
376 return
377 $status === self::RESPONSE_STATUS_422
378 && $errorCode === self::RESPONSE_ERROR_INVOICE_NOT_FOUND
379 ;
380 }
381
382 protected function needCreateInvoice(array $invoiceState = []): bool
383 {
384 if (empty($invoiceState))
385 {
386 return true;
387 }
388 $currentStatus = ($invoiceState['response']['status'] ?? '');
389 if ($this->isValidPaymentStatus($currentStatus))
390 {
391 return false;
392 }
393
394 if ($this->isInvoiceNotFound($invoiceState))
395 {
396 return true;
397 }
398
399 return false;
400 }
401
406 protected function createInvoice(Payment $payment): PaySystem\ServiceResult
407 {
408 if (!$this->isInvoiceSumCorrect($payment))
409 {
410 $result = new PaySystem\ServiceResult();
411 $result->addError(new Main\Error(
412 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_BAD_INVOICE_SUM'),
413 self::ERROR_CODE_BAD_INVOICE_SUM
414 ));
415
416 return $result;
417 }
418
419 $invoiceQueryParams = $this->getInvoiceQueryParams($payment);
420 $result = $this->checkInvoiceQueryParams($invoiceQueryParams);
421 if (!$result->isSuccess())
422 {
423 $this->addDebugInfo(
424 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_INVALID_INVOICE_PARAMS'),
425 $invoiceQueryParams
426 );
427
428 return $result;
429 }
430
431 return $this->send(
432 Web\Http\Method::POST,
433 $this->getUrl($payment, 'invoice'),
434 $this->getHeaders($payment),
435 $invoiceQueryParams
436 );
437 }
438
439 protected function getInvoiceQueryParams(Payment $payment): array
440 {
441 $result = [
442 'invoiceNumber' => (string)$payment->getId(), // digital identifier
443 'items' => $this->getProductsForInvoice($payment),
444 'contactPhone' => $this->getContactPhone($payment),
445 ];
446
447 $email = $this->getEmail($payment);
448 if ($email)
449 {
450 $result['contacts'] = [
451 [
452 'email' => $email,
453 ]
454 ];
455 }
456
457 $comment = $this->getInvoiceComment($payment);
458 if ($comment !== '')
459 {
460 $result['comment'] = $comment;
461 }
462
463 $dueDate = $this->getDueDate($payment);
464 if (!empty($dueDate))
465 {
466 $result['dueDate'] = $dueDate;
467 }
468
469 $payer = $this->getPayerData($payment);
470 if (!empty($payer))
471 {
472 $result['payer'] = $payer;
473 }
474
475 return $result;
476 }
477
478 protected function checkInvoiceQueryParams(array $invoiceQueryParams): PaySystem\ServiceResult
479 {
480 $result = new PaySystem\ServiceResult();
481
482
483 if (empty($invoiceQueryParams['payer']))
484 {
485 $result->addError(new Main\Error(
486 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_INVALID_PAYER_DATA'),
487 self::ERROR_CODE_BAD_INVOICE_PARAMS
488 ));
489 }
490
491 if (empty($invoiceQueryParams['items']))
492 {
493 $result->addError(new Main\Error(
494 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_INVALID_INVOICE_ITEMS'),
495 self::ERROR_CODE_BAD_INVOICE_PARAMS
496 ));
497 }
498
499 return $result;
500 }
501
502 protected function getDueDate(Payment $payment): string
503 {
504 if (!$this->isValidDatePayBefore($payment))
505 {
506 return '';
507 }
509 $datePayBefore = $payment->getField('DATE_PAY_BEFORE');
510
511 return $datePayBefore->format('Y-m-d');
512 }
513
514 protected function getPayerData(Payment $payment): ?array
515 {
516 $payerData = $this->getCompanyPayerData($payment);
517
518 if (empty($payerData))
519 {
520 $payerData = $this->getContactPayerData($payment);
521 }
522
523 return !empty($payerData) ? $payerData : null;
524 }
525
526 protected function getContactPayerData(Payment $payment): ?array
527 {
528 $result = [];
529
530 $contactFullName = $this->getContactFullName($payment);
531
532 if (!empty($contactFullName))
533 {
534 $result['name'] = $contactFullName;
535 }
536
537 return !empty($result) ? $result : null;
538 }
539
540 protected function getCompanyPayerData(Payment $payment): ?array
541 {
543 $collection = $payment->getCollection();
544 $order = $collection->getOrder();
545
546 $clientCollection = $this->getClientCollection($order);
547 if ($clientCollection === null)
548 {
549 return null;
550 }
551
552 $company = $clientCollection->getPrimaryCompany();
553 if ($company === null)
554 {
555 return null;
556 }
557
558 $requisite =
559 (
560 new Crm\Requisite\DefaultRequisite(
561 new Crm\ItemIdentifier(
562 \CCrmOwnerType::Company,
563 (int)$company->getField('ENTITY_ID')
564 )
565 )
566 )
567 ->setCheckPermissions(false)
568 ;
569 $requisiteValues = $requisite->get();
570
571 $title = trim((string)$company->getCustomerName());
572 $inn = trim((string)($requisiteValues['RQ_INN'] ?? ''));
573 $kpp = trim((string)($requisiteValues['RQ_KPP'] ?? ''));
574
575 if ($title === '' || $inn === '')
576 {
577 return null;
578 }
579
580 if ($kpp === '')
581 {
582 if (!isset($requisiteValues['PRESET_ID']))
583 {
584 return null;
585 }
586
587 $companyPreset = EntityPreset::getSingleInstance()->getById($requisiteValues['PRESET_ID']);
588
589 if (
590 is_array($companyPreset)
591 && isset($companyPreset['XML_ID'])
592 && (string)$companyPreset['XML_ID'] === EntityRequisite::XML_ID_DEFAULT_PRESET_RU_COMPANY
593 )
594 {
595 return null;
596 }
597
598 $kpp = '0';
599 }
600
601 return [
602 'name' => $title,
603 'inn' => $inn,
604 'kpp' => $kpp,
605 ];
606 }
607
608 protected function getProductsForInvoice(Payment $payment): array
609 {
610 $catalogIncluded = Loader::includeModule('catalog');
612 $paymentCollection = $payment->getCollection();
613
614 $order = $paymentCollection->getOrder();
615 $basket = $order->getBasket();
616
617 $defaultMeasure = '';
618 if ($catalogIncluded)
619 {
620 $measureDescription = \CCatalogMeasure::getDefaultMeasure(true, false);
621 $defaultMeasure = $measureDescription['SYMBOL_RUS'];
622 unset($measureDescription);
623 }
624
625 $result = [];
626 // /** @var BasketItem $basketItem */
627 /*
628 foreach ($basket->getBasketItems() as $basketItem)
629 {
630 $row = [
631 'name' => $basketItem->getField('NAME'),
632 'amount' => $basketItem->getQuantity(),
633 'price' => $basketItem->getPriceWithVat(),
634 ];
635
636 $vat = $basketItem->getVatRate();
637 if ($vat === null)
638 {
639 $vat = 'None';
640 }
641 else
642 {
643 $vat = (string)((int)((float)$vat * 100));
644 }
645 $row['vat'] = $vat;
646 $row['unit'] = (string)$basketItem->getField('MEASURE_NAME') ?: $defaultMeasure;
647
648 $result[] = $row;
649 }
650 */
652 foreach ($payment->getPayableItemCollection()->getBasketItems() as $payableBasketItem)
653 {
655 $basketItem = $basket->getItemById($payableBasketItem->getField('ENTITY_ID'));
656 if ($basketItem)
657 {
658 $row = [
659 'name' => $basketItem->getField('NAME'),
660 'amount' => $basketItem->getQuantity(),
661 'price' => $basketItem->getPriceWithVat(),
662 ];
663
664 $vat = $basketItem->getVatRate();
665 if ($vat === null)
666 {
667 $vat = 'None';
668 }
669 else
670 {
671 $vat = (string)((int)((float)$vat * 100));
672 }
673 $row['vat'] = $vat;
674 $row['unit'] = (string)$basketItem->getField('MEASURE_NAME') ?: $defaultMeasure;
675
676 $result[] = $row;
677 }
678 }
679
680 return $result;
681 }
682
689 protected function getContactPhone(Payment $payment): string
690 {
692 $collection = $payment->getCollection();
693 $phoneNumber = $this->getClientPhoneNumber($collection->getOrder());
694
695 return
696 $phoneNumber
697 ? $this->normalizePhoneNumber($phoneNumber)
698 : ''
699 ;
700 }
701
702 protected function getContactFullName(Payment $payment): ?string
703 {
705 $collection = $payment->getCollection();
706 $order = $collection->getOrder();
707
708 $clientCollection = $this->getClientCollection($order);
709 if (!$clientCollection)
710 {
711 return null;
712 }
713
714 $clientFullName = null;
715
716 $clientId = $this->getPrimaryContactId($clientCollection);
717
718 $factory = Crm\Service\Container::getInstance()->getFactory(\CCrmOwnerType::Contact);
719 if ($factory)
720 {
721 $contactItem = $factory->getItem($clientId, ['FULL_NAME']);
722 $clientFullName = $contactItem->getFullName();
723 }
724
725 return $clientFullName;
726 }
727
734 protected function getClientPhoneNumber(Order $order): ?string
735 {
736 $clientCollection = $this->getClientCollection($order);
737 if (!$clientCollection)
738 {
739 return null;
740 }
741
742 $phoneNumber = null;
743
744 $clientId = $this->getPrimaryContactId($clientCollection);
745 $entityId = \CCrmOwnerType::ContactName;
746
747 if ($clientId === null)
748 {
749 $clientId = $this->getPrimaryCompanyId($clientCollection);
750 $entityId = \CCrmOwnerType::CompanyName;
751 }
752
753 if ($clientId)
754 {
755 $crmFieldMultiResult = \CCrmFieldMulti::GetList(
756 [
757 'ID' => 'desc',
758 ],
759 [
760 'ENTITY_ID' => $entityId,
761 'ELEMENT_ID' => $clientId,
762 'TYPE_ID' => 'PHONE',
763 ]
764 );
765 while ($crmFieldMultiData = $crmFieldMultiResult->Fetch())
766 {
767 $phoneNumber = $crmFieldMultiData['VALUE'];
768 if ($phoneNumber)
769 {
770 break;
771 }
772 }
773 unset(
774 $crmFieldMultiData,
775 $crmFieldMultiResult,
776 );
777 }
778
779 return $phoneNumber;
780 }
781
788 protected function normalizePhoneNumber(string $phoneNumber): string
789 {
790 $phoneNumber = trim($phoneNumber);
791 if ($phoneNumber === '')
792 {
793 return '';
794 }
795
796 $parser = PhoneNumber\Parser::getInstance();
797 $number = $parser->parse($phoneNumber);
798
799 return (string)$number->format(PhoneNumber\Format::E164);
800 }
801
802 protected function getEmail(Payment $payment): ?string
803 {
805 $collection = $payment->getCollection();
806 $order = $collection->getOrder();
807 $userEmail = $order->getPropertyCollection()->getUserEmail();
808
809 return $userEmail?->getValue();
810 }
811
812 protected function getInvoiceComment(Payment $payment): string
813 {
815 $collection = $payment->getCollection();
816 $order = $collection->getOrder();
817
818 $description = str_replace(
819 [
820 '#PAYMENT_NUMBER#',
821 '#ORDER_NUMBER#',
822 '#PAYMENT_ID#',
823 '#ORDER_ID#',
824 '#USER_EMAIL#',
825 ],
826 [
827 $payment->getField('ACCOUNT_NUMBER'),
828 $order->getField('ACCOUNT_NUMBER'),
829 $payment->getId(),
830 $order->getId(),
831 (string)$this->getEmail($payment),
832 ],
833 $this->getBusinessValue($payment, 'TBB_COMMENT_TEMPLATE') ?? ''
834 );
835
836 return mb_substr(trim($description), 0, 1000);
837 }
838
839 protected function getInvoiceSum(Payment $payment): ?float
840 {
842 $paymentCollection = $payment->getCollection();
843
844 $order = $paymentCollection->getOrder();
845 $basket = $order->getBasket();
846
847 $found = false;
848 $price = 0.0;
849 // /** @var BasketItem $basketItem */
850 /*
851 foreach ($basket->getBasketItems() as $basketItem)
852 {
853 $found = true;
854 $price += $basketItem->getFinalPrice();
855 }
856 */
858 foreach ($payment->getPayableItemCollection()->getBasketItems() as $payableBasketItem)
859 {
861 $basketItem = $basket->getItemById($payableBasketItem->getField('ENTITY_ID'));
862 if ($basketItem)
863 {
864 $found = true;
865 $price += $basketItem->getFinalPrice();
866 }
867 }
868
869 return
870 $found
871 ? $price
872 : null
873 ;
874 }
875
882 protected function isInvoiceSumCorrect(Payment $payment): bool
883 {
884 $paymentSum = PriceMaths::roundPrecision($payment->getSum());
885 $invoiceSum = $this->getInvoiceSum($payment);
886
887 $this->addDebugInfo(
888 'invoiceSum',
889 [
890 'invoiceSum' => $invoiceSum,
891 'paymentSum' => $paymentSum,
892 ]
893 );
894
895 return $paymentSum === $invoiceSum;
896 }
897
898 protected function send(string $method, string $url, array $headers, array $params = []): PaySystem\ServiceResult
899 {
900 $result = new PaySystem\ServiceResult();
901
902 $httpClient = new Web\HttpClient();
903 $httpClient->setHeaders($headers);
904
905 switch ($method)
906 {
907 case Web\Http\Method::GET:
908 $response = $httpClient->get($url);
909 break;
910 case Web\Http\Method::POST:
911 $postData = null;
912 if ($params)
913 {
914 $postData = static::encode($params);
915 }
916 $this->addDebugInfo('request data', $postData);
917 $response = $httpClient->post($url, $postData);
918 break;
919 default:
920 $response = null;
921 break;
922 }
923
924 if ($response === null)
925 {
926 $result->addError(new Main\Error(
927 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_UNSUPPORTED_PROTOCOL'),
928 self::ERROR_CODE_SYSTEM_FAILURE
929 ));
930
931 return $result;
932 }
933
934 $this->addDebugInfo('response data', $response);
935
936 $status = $httpClient->getStatus();
937 $response = static::decode($response);
938 if (!is_array($response))
939 {
940 $status = self::ERROR_STATUS_BAD_JSON;
941 }
942
943 switch ($status)
944 {
945 case self::ERROR_STATUS_BAD_JSON:
946 $result->setData([
947 'params' => $params,
948 'status' => $status,
949 ]);
950 $result->addError(new Main\Error(
951 Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_UNKNOWN_ANSWER'),
952 self::ERROR_CODE_SYSTEM_FAILURE
953 ));
954 break;
955 case self::RESPONSE_STATUS_200:
956 $result->setData([
957 'params' => $params,
958 'response' => $response,
959 'status' => $status,
960 ]);
961 break;
962 case self::RESPONSE_STATUS_400:
963 case self::RESPONSE_STATUS_401:
964 case self::RESPONSE_STATUS_403:
965 case self::RESPONSE_STATUS_422:
966 case self::RESPONSE_STATUS_429:
967 case self::RESPONSE_STATUS_500:
968 default:
969 $result->setData([
970 'params' => $params,
971 'response' => $response,
972 'status' => $status,
973 ]);
974 $result->addError($this->getResponseError($status, $response));
975 $this->addDebugInfo('invalid request', $response);
976 break;
977 }
978
979 return $result;
980 }
981
982 protected function addDebugInfo(string $message, mixed $data): void
983 {
984 if ($message === '')
985 {
986 return;
987 }
988 if (is_array($data) || is_bool($data))
989 {
990 $data = mydump($data);
991 }
992 elseif (is_object($data))
993 {
994 if (method_exists($data, '__toString'))
995 {
996 $data = (string)$data;
997 }
998 else
999 {
1000 $data = mydump($data);
1001 }
1002 }
1003 PaySystem\Logger::addDebugInfo(__CLASS__ . ': ' . $message . ': ' . $data);
1004 }
1005
1006 protected function getResponseError(int $status, mixed $response): Main\Error
1007 {
1008 $error = match ($status)
1009 {
1010 self::RESPONSE_STATUS_400 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_400_INVALID_REQUEST'),
1011 self::RESPONSE_STATUS_401 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_401_BAD_AUTHENTICATION'),
1012 self::RESPONSE_STATUS_403 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_403_BAD_AUTHORIZATION'),
1013 self::RESPONSE_STATUS_422 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_422_BAD_DATA'),
1014 self::RESPONSE_STATUS_429 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_429_TOO_MANY_REQUESTS'),
1015 self::RESPONSE_STATUS_500 => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_ERROR_500_SERVER'),
1016 default => Loc::getMessage(
1017 'SALE_HPS_TBANK_BUSINESS_ERROR_UNKNOWN_STATUS',
1018 [
1019 '#STATUS#' => $status,
1020 ]
1021 ),
1022 };
1023
1024 $message = '';
1025 if (isset($response['errorMessage']))
1026 {
1027 $message = $response['errorMessage'];
1028 if (isset($response['errorDetails']) && is_array($response['errorDetails']))
1029 {
1030 $message .= '. ' . implode(', ', $response['errorDetails']);
1031 }
1032 }
1033
1034 return new Main\Error(
1035 $message ?: $error,
1036 $response['errorCode'] ?? self::ERROR_CODE_RESPONSE_FAILURE
1037 );
1038 }
1039
1040 protected function getInvoiceStatusTitle(string $status): string
1041 {
1042 return (string)match ($status)
1043 {
1044 self::PAYMENT_STATUS_DRAFT => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_INVOICE_STATUS_DRAFT'),
1045 self::PAYMENT_STATUS_SUBMITTED => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_INVOICE_STATUS_SUBMITTED'),
1046 self::PAYMENT_STATUS_EXECUTED => Loc::getMessage('SALE_HPS_TBANK_BUSINESS_INVOICE_STATUS_EXECUTED'),
1047 default => '',
1048 };
1049 }
1050
1051 protected function isValidPaymentStatus(string $status): bool
1052 {
1053 return
1054 $status === self::PAYMENT_STATUS_DRAFT
1055 || $status === self::PAYMENT_STATUS_SUBMITTED
1056 || $status === self::PAYMENT_STATUS_EXECUTED
1057 ;
1058 }
1059
1060 protected function isValidDatePayBefore(Payment $payment): bool
1061 {
1062 $datePayBefore = $payment->getField('DATE_PAY_BEFORE');
1063 if ($datePayBefore instanceof Main\Type\Date)
1064 {
1065 $currentDate = new Main\Type\Date();
1066 if ($datePayBefore->getTimestamp() >= $currentDate->getTimestamp())
1067 {
1068 return true;
1069 }
1070 }
1071
1072 return false;
1073 }
1074
1075 protected function isExistDatePayBefore(Payment $payment): bool
1076 {
1077 return $payment->getField('DATE_PAY_BEFORE') instanceof Main\Type\Date;
1078 }
1079
1080 protected function getClientCollection(Order $order): ?Crm\Order\ContactCompanyCollection
1081 {
1082 if ($order instanceof Crm\Order\Order)
1083 {
1084 return $order->getContactCompanyCollection();
1085 }
1086
1087 return null;
1088 }
1089
1090 protected function getPrimaryCompanyId(Crm\Order\ContactCompanyCollection $collection): ?int
1091 {
1092 $company = $collection->getPrimaryCompany();
1093 if ($company !== null)
1094 {
1095 $companyId = $company->getField('ENTITY_ID');
1096
1097 return $companyId === null ? null : (int)$companyId;
1098 }
1099
1100 return null;
1101 }
1102
1103 protected function getPrimaryContactId(Crm\Order\ContactCompanyCollection $collection): ?int
1104 {
1105 $contact = $collection->getPrimaryContact();
1106 if ($contact !== null)
1107 {
1108 $contactId = $contact->getField('ENTITY_ID');
1109
1110 return $contactId === null ? null : (int)$contactId;
1111 }
1112
1113 return null;
1114 }
1115}
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
const E164
Определения format.php:7
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
$template
Определения file_edit.php:49
</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
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
$status
Определения session.php:10
mydump($thing, $maxdepth=-1, $depth=0)
Определения tools.php:3859
Order
Определения order.php:6
getRestrictionCurrency(RestrictionInfoCollection $collection)
Определения restrictioncurrencytrait.php:12
trait Error
Определения error.php:11
$payment
Определения payment.php:14
$order
Определения payment.php:8
$paymentCollection
Определения payment.php:11
$entityId
Определения payment.php:4
$email
Определения payment.php:49
$message
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$comment
Определения template.php:15
$vat
Определения template.php:273
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$dueDate
Определения template.php:10
$invoiceSum
Определения template.php:7
$title
Определения pdf.php:123
$response
Определения result.php:21
$method
Определения index.php:27
$postData
Определения index.php:29
$clientId
Определения seo_client.php:18
$error
Определения subscription_card_product.php:20
$invoiceStatus
Определения template_status.php:8
$url
Определения iframe.php:7