20 private $serviceResult;
52 public function run(array $fields): ?array
54 $this->params = $fields;
59 $this->validateInputParams();
60 $this->initPaymentService();
61 $this->initRegistry();
62 $this->initPaymentEntities();
63 $this->checkPaymentAllowed();
71 return $this->formatResponse();
77 private function validateInputParams(): void
79 $paymentId = (int)$this->params[
'PAYMENT_ID'];
80 $paySystemId = (int)$this->params[
'PAY_SYSTEM_ID'];
85 'paymentId must be specified',
90 if ($paySystemId <= 0)
92 throw new InitiatePayException(
93 'paySystemId must be specified',
98 if (empty($this->params[
'ACCESS_CODE']))
100 throw new InitiatePayException(
101 'accessCode must be specified',
110 private function initPaymentService(): void
112 $this->service = Sale\PaySystem\Manager::getObjectById((
int)$this->params[
'PAY_SYSTEM_ID']);
116 throw new InitiatePayException(
117 'payment service not found',
122 if (!empty($this->params[
'RETURN_URL']))
124 $this->service->getContext()->setUrl($this->params[
'RETURN_URL']);
131 private function initRegistry(): void
133 $this->registry = Sale\Registry::getInstance($this->service->getField(
'ENTITY_REGISTRY_TYPE'));
134 if (!$this->registry)
136 throw new InitiatePayException(
146 private function initPaymentEntities(): void
148 $paymentRow = Sale\Payment::getList([
149 'filter' => [
'ID' => (
int)$this->params[
'PAYMENT_ID']],
150 'select' => [
'ORDER_ID',
'ID'],
153 if (!$paymentData = $paymentRow->fetch())
155 throw new InitiatePayException(
161 $paymentId = (int)$paymentData[
'ID'];
162 $orderId = (int)$paymentData[
'ORDER_ID'];
164 if (!$this->order = $this->findOrder($orderId))
166 throw new InitiatePayException(
172 if (!$this->payment = $this->order->getPaymentCollection()->getItemById($paymentId))
174 throw new InitiatePayException(
181 private function findOrder(
int $orderId): ?
Sale\Order
188 $orderClassName = $this->registry->getOrderClassName();
190 $order = $orderClassName::load($orderId);
197 private function checkPaymentAllowed(): void
201 throw new InitiatePayException(
202 'order in unpayable status',
207 if ($this->order->getHash() !== $this->params[
'ACCESS_CODE'])
209 throw new InitiatePayException(
219 private function initiatePay(): void
221 $this->updatePaymentMetadata();
224 if (!empty($this->params[
'template']))
226 $request = \Bitrix\Main\Context::getCurrent()->getRequest();
227 $request->set([
'template' => $this->params[
'template']]);
230 $this->serviceResult = $this->service->initiatePay(
236 if (!$this->serviceResult->isSuccess())
239 'payment service error',
243 $this->
addErrors($this->serviceResult->getErrors());
245 foreach ($this->serviceResult->getBuyerErrors() as $buyerError)
247 $customData = $buyerError->getCustomData();
248 $errorContext = is_array($customData) ? $customData : [];
249 $errorContext[
'is_buyer'] =
true;
252 $buyerError->getMessage(),
253 $buyerError->getCode(),
260 private function updatePaymentMetadata(): void
262 Sale\DiscountCouponsManagerBase::freezeCouponStorage();
264 $result = $this->payment->setFields([
265 'PAY_SYSTEM_ID' => $this->service->getField(
'ID'),
266 'PAY_SYSTEM_NAME' => $this->service->getField(
'NAME')
269 $result = $result->isSuccess() ? $this->order->save() : $result;
271 Sale\DiscountCouponsManagerBase::unFreezeCouponStorage();
273 if (!$result->isSuccess())
275 throw new InitiatePayException(
276 'cannot update payment',
284 return $this->payment;
289 return $this->serviceResult;
292 private function formatResponse(): ?array
294 if ($this->errorCollection->isEmpty())
297 'html' => $this->serviceResult->getTemplate(),
298 'url' => $this->serviceResult->getPaymentUrl(),
299 'qr' => $this->serviceResult->getQr(),