Как сменить статус заказа при успешной оплате для minishop2?

После оплаты, идёт перенаправление на страницу, в параметрах странице уже есть такие параметры как
action,msorder,mscode
все они имеют значение что и должны, 1 это после успешной оплаты получит «success» 2й, это номер заказа, 3й это хеш заказа.

Так вот как после завершение удачной оплаты, как дать знать минишопу что заказ оплачен и можно менять статус на «Оплачено» допустим?

Модуль оплаты сделан вручную, существующих для нужной мне системы нет.
В моём модуле есть 2 метода что были переопределены, это метод «Send» и метод «getPaymentLink», мне нужно добавить ещё что-то? или что нужно сделать?

Так же самой системой оплаты на мою ссылку успешной оплаты, приходит ответ, и в ответе есть ключ с типом code
Viktor
12 января 2023, 08:25
modx.pro
154
0

Комментарии: 13

Viktor
12 января 2023, 08:37
0
Мне нужно наверно сделать как в пейпале, добавить php, в ассет платежей минишопа, и ловить это сообщение, а потом что сделать? вручную менять статус? или есть у минишопа метод для этого после успешной оплаты?
    Viktor
    12 января 2023, 08:43
    0
    У сервиса оплаты минишопа есть такой метод как «receive», как я понял из сущ пейпала, что это метод при котором отправляется запрос на проверку успешной оплаты, как его за тригерить? или он сам тригерится после возвращение на страницу оформления заказа с параметрами, успеха, номера заказа и хэша заказа?
      Николай Савин
      12 января 2023, 08:56
      0
      receive это метод, который реагирует запрос из вне. Обычно банк после оплаты дергает файл
      /assets/components/minishop2/payment/имя_платежки/имя_платежки.php
      В этом файле «по вкусу» происходит валидация входящего от банка запроса и затем вызывается метод receive, основная задача которого — поменять статус заказа на оплачено. Запрос на проверку успешной оплаты производится также «по вкусу». Многие платежки просто слепо доверяют входящим данным.

      Для фронта, в случае этого метода ничего не происходит, так как он является служебным API методом.

      Как его тригерить — посмотрите в том же Paypal или например Робокасса
        Viktor
        12 января 2023, 09:02
        0
        Да, спасибо смотрел, буду так и делать
          Viktor
          12 января 2023, 12:35
          0
          А можете пожалуйста подсказать, как отправить это в другой поток, то есть после оплаты не важно какой идёт редирект, а там происходит проверка и смена статуса, так как мне добавить проверку и смену статуса, чтобы оно не мешало пользователю и страница не грузилась там несколько секунд. А сразу редиректила на отдельную страницу.

          Потому что от банка вроде должно приходить что якоба оплата прошла именно на сайт, а как бы есть то нет, а так же там только есть номер счёта. Конечно можно добавить поле в заказ и указать айди счёт на оплату и по нему искать так, но слишком много костылей, плюс это всё может приходить то не приходить, то может приходить спустя время, а с помощью редиректа я все данные получаю быстро.

          Хостинг обычный виртуальный, php 7.4+ modx 2.7.3
            Николай Савин
            12 января 2023, 12:40
            0
            Кажется мы друг друга не очень понимаем.

            Еще раз. Метод receive не используется клиентом, администратором и т.п.
            Он нужен для того чтобы Банк в фоновом режиме сообщил сайту о совершенной оплате. Никаких редиректов там нет и быть не может.

            Смену статуса оплаты по URL в данном случае использовать нельзя, потому что зная нужную комбинацию — мошенник может подтвердить оплату, не производя ее.
            Опирайтесь ТОЛЬКО на автоматическую служебную информацию от банка.
              Viktor
              12 января 2023, 12:45
              0
              Сделал по аналогу как в пейпале код ниже. Я поставил чтобы редирект был на этот файл, чтобы получить поля «action» и так далее. Проверяется оплата, проверяется хэш, потом идёт редирект, и получается что всё это время у пользователя грузится страница, секунды 4.

              <?php
              
              const MODX_API_MODE = true;
              /** @noinspection PhpIncludeInspection */
              require dirname(__FILE__, 5) . '/index.php';
              
              /** @var modX $modx */
              $modx->getService('error', 'error.modError');
              $modx->setLogLevel(modX::LOG_LEVEL_ERROR);
              $modx->setLogTarget('FILE');
              
              
              function goNext(){
                  global $modx;
                  $redirect = $_GET['action'] == 'success'
                      ? $modx->makeUrl((int) $modx->getOption('epay_post_success_page_id'), '', '', 'full')
                      : $modx->makeUrl((int) $modx->getOption('epay_post_error_page_id'), '', '', 'full');
                  return $modx->sendRedirect($redirect);
              }
              
              
              if (isset($_GET['action']) && !empty($_GET['action']) && !empty($_GET['msorder']) && !empty($_GET['mscode']) && !empty($_GET['invoice_id'])) {
              
                  /** @var miniShop2 $miniShop2 */
                  $miniShop2 = $modx->getService('miniShop2');
                  $miniShop2->loadCustomClasses('payment');
              
              
              
                  if (!class_exists('EpayHalykBank')) {
                      $_GET['action'] = 'cancel';
                      goNext();
                  }
              
              
                  /** @var msOrder $order */
                  $order = $modx->newObject('msOrder');    
                  $handler = new EpayHalykBank($order);
              
              
                  if ($order = $modx->getObject('msOrder', (int)$_GET['msorder'])) {
                      /** @var msPaymentInterface|EpayHalykBank $handler */
              
               
                      $verifyingOrderPaymentStatus = $handler->getOrderPaymentStatus($order, array(
                          'action' => $_GET['action'],
                          'msorder' => $_GET['msorder'],
                          'mscode' => $_GET['mscode'],
                          'invoice_id' => $_GET['invoice_id']
                      ));
              
                      // $modx->log(
                      //     modX::LOG_LEVEL_ERROR,
                      //     'Верификация 
              '.var_dump($verifyingOrderPaymentStatus['status'])
                      // );
              
                      if($verifyingOrderPaymentStatus && !empty($verifyingOrderPaymentStatus['status'])){
                          $updatingOrder = $handler->receive($order, array(
                              'verifyedResponse' => $verifyingOrderPaymentStatus,
                              'requestParams' => array(
                                  'action' => $_GET['action'],
                                  'msorder' => $_GET['msorder'],
                                  'mscode' => $_GET['mscode'],
                                  'invoice_id' => $_GET['invoice_id']
                              )
                          ));
                          if($updatingOrder){
                              $_GET['action'] = 'success';
                          } else {
                              $_GET['action'] = 'cancel';
                          }
                          goNext();
                      }        
                  } else {
                      $_GET['action'] = 'cancel';
                      goNext();
                  }
              
              
              }
              
              goNext();
              Ниже функции проверки и смены статуса
              /**
              * @param msOrder $order
              * @param array params
              *
              * @return array|string
              */
              public function getOrderPaymentStatus(msOrder $order, $params = array()){
              
                  if($params['action'] == 'continue'){
                      $createdOrderHash = $this->getOrderHashOld($order);
                      if($params['mscode'] == $createdOrderHash){
                          $authResponse = $this->paymentAuth($order);
              
                          if($authResponse['access_token']){
                              $getPaymentStatus = $this->jwt_request(
                                  $this->config['transactionCheckStatusUrl'].$params['invoice_id'],
                                  $authResponse['access_token']
                              );
              
                              return array(
                                  'status' => 'verified',
                                  'response' => $getPaymentStatus
                              );
              
                          } else {
                              return array(
                                  'status' => 'error'
                              );
                          }
              
              
                      }
                  }
              
              }
              
              
              
              
              /**
              * @param msOrder $order
              * @param array $params
              *
              * @return bool
              */
              public function receive(msOrder $order, $params = array())
              {
                  if ($params['requestParams']['action'] == 'continue' && $params['verifyedResponse']['status'] == 'verified') {
              
                      if(!empty($params['verifyedResponse']) && !empty($params['verifyedResponse']['response'])  && !empty($params['verifyedResponse']['response']['resultCode'])){
                          
                          if ($params['verifyedResponse']['response']['resultCode'] == '100') {
                              $this->ms2->changeOrderStatus($order->get('id'), 2); // Set status "paid"
                          } else {
                              $this->ms2->changeOrderStatus($order->get('id'), 1002); // Set status "Payment error"
              
                              $msOrder->set('payment_response_status', $result);
                              $msOrder->save();
                              return false;
                          }
              
                      }
              
                  } else {
                      return false;
                  }
              
                  return true;
              }
                Viktor
                12 января 2023, 12:57
                0
                По урл у меня ничего не обновляется, у меня идёт редирект после оплаты на страницу, сразу с гет запросами стандартными, action, mscode, msorder, а так же добавил свой invoice_id, всё, потом идёт проверки, правильный ли хэш заказа с номером заказа, потом берётся номер счёта на оплату, и спрашивает у банка код этой транзакции, если код транзакции говорит ок, то только тогда я меняю статус.

                Так же сейчас добавлю поле для заказа, и буду записывать туда номер счёта на оплату, и так же добавлю новую проверку
                  Viktor
                  12 января 2023, 13:53
                  0
                  По моему опираясь только на банк(в моём случае) и ждать пока он отправит тоже не то, максимально что я получу от банка, это номер счёта, и максимальная защита это origin запроса.

                  Сейчас же, в гет запрос должен попасть номер заказа, а так же хэш заказа, а потом ещё и номер заказа, получается защиты будет по больше, ему нужно будет подобрать 2 параметра.

                  К тому же, по урл ничего не меняется, происходят проверки, и потом лишь только запрашивается у банка код транзакции на стороне сайта, и лишь потом на стороне сайта меняется статус заказа. В том же пейпале точно так же как и у меня, у меня даже по больше защиты будет, разве нет?
                    Николай Савин
                    12 января 2023, 14:02
                    0
                    Я вам выше дал ссылку на исходный код платежки от Робокассы.
                    Посмотрите как устроена она. Это самый свежий компонент.
                      Viktor
                      12 января 2023, 14:14
                      0
                      Тоже самое почти что и пейпал. Со мной расходства есть, я в методе сенд получаю ответ авторизации, и потом отправляю его на фронт (ПОТОМУ ЧТО без этого никак, без их js библиотеки это попросту не работает, писал в тех поддержку спрашивал(да такое бывает, мне самому плохо и меня откачивали).
                      Затем идёт редирект с фронта на оплату, и потом я сделал редирект после успешной оплаты, идёт редирект, в редиректе есть обычные гет запросы, с номером заказа, хэш заказа, а так же номер счёта на оплату, и потом точно так же как в робокасе и пейпале, я всё отправляю в метод оплаты, и внутри на сайте, потом сверяю все предоставленные данные, и только потом я отправляю отдельный запрос в банк чтобы он дал мне статус оплаты по данному счёту на оплату, и там же внутри самого сайта я меняю статус в зависимости от ответа от банка.

                      У меня от банка приходит лишь номер счёта на оплату, и всё, нет ни подписи, не номера заказа, не хэш этого заказа, по этому я сделал через редирект, сейчас сделаю как вы посоветовали.
                        Николай Савин
                        12 января 2023, 14:21
                        0
                        У меня два вопроса.
                        Первый — Зачем вообще после возвращения со страницы оплаты что то делать? Это может быть актуально разве что для цифровых товаров, которые после оплаты должны быть доступны для скачивания.

                        Второй вопрос — я потерял нить разговора. У вас вопрос какой бы изначально? В чем затык?
                          Viktor
                          12 января 2023, 14:31
                          0
                          1) Чтобы обновить статус заказа на оплачен, либо поставить статус что ошибка оплаты и так далее. Почему именно так, потому что в ответе от банка, в пост запросе я получу только номер счёта на оплату, а так же эти данные приходят не сразу, а если будет хэш заказа, то уже будет сложнее подобрать, плюс у меня нет никакой проверки что этот запрос был от банка, у меня от банка просто приходит номер счёта на оплату из важных.

                          2) Всё что было решил, просто по моему решение мне нужно была помощь чтобы он выполнялся в фоне.

                          3) Переделаю как вы посоветовали, будет так же как в робокасе и пейпале, только из проверки будет только на ориджин. И само собой будут проверки на стороне сайта, то есть сначала спрошу заново о статусе, лишь потом буду что-то менять в заказе.
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            13