Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
initiatepayaction.php
1<?php
2
4
8
10{
15 private $params = [];
16
20 private $serviceResult;
21
25 private $service;
26
30 private $registry;
31
35 private $order;
36
40 private $payment;
41
52 public function run(array $fields): ?array
53 {
54 $this->params = $fields;
55 $this->serviceResult = new Sale\PaySystem\ServiceResult();
56
57 try
58 {
59 $this->validateInputParams();
60 $this->initPaymentService();
61 $this->initRegistry();
62 $this->initPaymentEntities();
63 $this->checkPaymentAllowed();
64 $this->initiatePay();
65 }
66 catch (InitiatePayException $e)
67 {
68 $this->addError(new Error($e->getMessage(), $e->getCode()));
69 }
70
71 return $this->formatResponse();
72 }
73
77 private function validateInputParams(): void
78 {
79 $paymentId = (int)$this->params['PAYMENT_ID'];
80 $paySystemId = (int)$this->params['PAY_SYSTEM_ID'];
81
82 if ($paymentId <= 0)
83 {
84 throw new InitiatePayException(
85 'paymentId must be specified',
87 );
88 }
89
90 if ($paySystemId <= 0)
91 {
92 throw new InitiatePayException(
93 'paySystemId must be specified',
95 );
96 }
97
98 if (empty($this->params['ACCESS_CODE']))
99 {
100 throw new InitiatePayException(
101 'accessCode must be specified',
103 );
104 }
105 }
106
110 private function initPaymentService(): void
111 {
112 $this->service = Sale\PaySystem\Manager::getObjectById((int)$this->params['PAY_SYSTEM_ID']);
113
114 if (!$this->service)
115 {
116 throw new InitiatePayException(
117 'payment service not found',
119 );
120 }
121
122 if (!empty($this->params['RETURN_URL']))
123 {
124 $this->service->getContext()->setUrl($this->params['RETURN_URL']);
125 }
126 }
127
131 private function initRegistry(): void
132 {
133 $this->registry = Sale\Registry::getInstance($this->service->getField('ENTITY_REGISTRY_TYPE'));
134 if (!$this->registry)
135 {
136 throw new InitiatePayException(
137 'internal error',
139 );
140 }
141 }
142
146 private function initPaymentEntities(): void
147 {
148 $paymentRow = Sale\Payment::getList([
149 'filter' => ['ID' => (int)$this->params['PAYMENT_ID']],
150 'select' => ['ORDER_ID', 'ID'],
151 'limit' => 1
152 ]);
153 if (!$paymentData = $paymentRow->fetch())
154 {
155 throw new InitiatePayException(
156 'payment not found',
158 );
159 }
160
161 $paymentId = (int)$paymentData['ID'];
162 $orderId = (int)$paymentData['ORDER_ID'];
163
164 if (!$this->order = $this->findOrder($orderId))
165 {
166 throw new InitiatePayException(
167 'order not found',
169 );
170 }
171
172 if (!$this->payment = $this->order->getPaymentCollection()->getItemById($paymentId))
173 {
174 throw new InitiatePayException(
175 'payment not found',
177 );
178 }
179 }
180
181 private function findOrder(int $orderId): ?Sale\Order
182 {
183 if ($orderId <= 0)
184 {
185 return null;
186 }
187
188 $orderClassName = $this->registry->getOrderClassName();
190 $order = $orderClassName::load($orderId);
191 return $order;
192 }
193
197 private function checkPaymentAllowed(): void
198 {
199 if (!Sale\OrderStatus::isAllowPay($this->order->getField('STATUS_ID')))
200 {
201 throw new InitiatePayException(
202 'order in unpayable status',
204 );
205 }
206
207 if ($this->order->getHash() !== $this->params['ACCESS_CODE'])
208 {
209 throw new InitiatePayException(
210 'access error',
212 );
213 }
214 }
215
219 private function initiatePay(): void
220 {
221 $this->updatePaymentMetadata();
222
223 $request = null;
224 if (!empty($this->params['template']))
225 {
226 $request = \Bitrix\Main\Context::getCurrent()->getRequest();
227 $request->set(['template' => $this->params['template']]);
228 }
229
230 $this->serviceResult = $this->service->initiatePay(
231 $this->payment,
232 $request,
234 );
235
236 if (!$this->serviceResult->isSuccess())
237 {
238 $this->addError(new Error(
239 'payment service error',
241 ));
242
243 $this->addErrors($this->serviceResult->getErrors());
244
245 foreach ($this->serviceResult->getBuyerErrors() as $buyerError)
246 {
247 $customData = $buyerError->getCustomData();
248 $errorContext = is_array($customData) ? $customData : [];
249 $errorContext['is_buyer'] = true;
250
251 $this->addError(new Error(
252 $buyerError->getMessage(),
253 $buyerError->getCode(),
254 $errorContext
255 ));
256 }
257 }
258 }
259
260 private function updatePaymentMetadata(): void
261 {
262 Sale\DiscountCouponsManagerBase::freezeCouponStorage();
263
264 $result = $this->payment->setFields([
265 'PAY_SYSTEM_ID' => $this->service->getField('ID'),
266 'PAY_SYSTEM_NAME' => $this->service->getField('NAME')
267 ]);
268
269 $result = $result->isSuccess() ? $this->order->save() : $result;
270
271 Sale\DiscountCouponsManagerBase::unFreezeCouponStorage();
272
273 if (!$result->isSuccess())
274 {
275 throw new InitiatePayException(
276 'cannot update payment',
278 );
279 }
280 }
281
282 public function getPayment(): ?Sale\Payment
283 {
284 return $this->payment;
285 }
286
287 public function getServiceResult(): ?Sale\PaySystem\ServiceResult
288 {
289 return $this->serviceResult;
290 }
291
292 private function formatResponse(): ?array
293 {
294 if ($this->errorCollection->isEmpty())
295 {
296 return [
297 'html' => $this->serviceResult->getTemplate(),
298 'url' => $this->serviceResult->getPaymentUrl(),
299 'qr' => $this->serviceResult->getQr(),
300 ];
301 }
302
303 return null;
304 }
305}
addError(Error $error)
Definition action.php:200
addErrors(array $errors)
Definition action.php:213
static isAllowPay($statusId)