Как создать новый метод оплаты для minishop2?

Можете поделиться статьями как добавить свой метод оплаты, суть в оплате такая, получаем объект авторизации передав нужные поля, а так же номер заказа и сумму, и потом передать весь ответ от запроса на фронт, где с помощью js, будет создан объект оплаты, а так же уникальная ссылка, и перенаправит тоже через js. Сам метод оплаты вот epayment.kz/ru/docs/platezhnaya-stranica

Как можно это интегрировать с минишопом?

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

<?php
define('MODX_API_MODE', true);
require $_SERVER['DOCUMENT_ROOT'].'/index.php';

$params = [
    'grant_type' => 'client_credentials',
    'scope' => 'webapi usermanagement email_send verification statement statistics payment',
    'client_id' => $modx->getOption('epay_client_id'),
    'client_secret' => $modx->getOption('epay_client_secret'),
    'invoiceID' => $_POST['invoiceId'],
    'amount' => $_POST['amount'],
    'currency' => 'KZT',
    'terminal' => $modx->getOption('epay_terminal_id'),
    'postLink' => 'https://'.$_SERVER['HTTP_HOST'].'/core/components/epay/succsess.php',
    'failurePostLink' => 'https://'.$_SERVER['HTTP_HOST'].'/core/components/epay/error.php'
];


$debug = $modx->getOption('epay_debug');

$myCurl = curl_init();
curl_setopt_array($myCurl, array(
    CURLOPT_URL => $debug == 1 ? 'https://testoauth.homebank.kz/epay2/oauth2/token' : 'https://epay-oauth.homebank.kz/oauth2/token',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($params)
));
$response = curl_exec($myCurl);
curl_close($myCurl);

header('Content-type: application/json');
echo $response;
Как вариант этот код запихнуть в плагин и поставить обработчик и проверку, но это ведь тоже не правильно. Что лучше сделать в данной ситуации?
Viktor
09 января 2023, 15:14
modx.pro
64
0

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

Viktor
09 января 2023, 15:16
0
Сам обработчик пытался сделать, и пытался регистрировать как показано в доках минишопа, но он даже не появляется.
<?php

if (!class_exists('msPaymentInterface')) {
    require_once dirname(__FILE__, 3) . '/minishop2/mspaymenthandler.class.php';
}

class mspEpayHalykBank extends msPaymentHandler implements msPaymentInterface
{

    /**
    * mspEpayHalykBank constructor.
    *
    * @param xPDOObject $object
    * @param array $config
    */
    function __construct(xPDOObject $object, $config = array())
    {
        parent::__construct($object, $config);

        $siteUrl = $this->modx->getOption('site_url');
        $assetsUrl = $this->modx->getOption('assets_url') . 'components/minishop2/';
        $paymentUrl = $siteUrl . substr($assetsUrl, 1) . 'custom/payment/mspepayhalykbank.php';

        $this->config = array_merge(array(
            'grant_type' => 'client_credentials',
            'debug' => $modx->getOption('epay_debug'),
            'paymentEpayUrl' => $this->config['debug'] == 1 ? 'https://testoauth.homebank.kz/epay2/oauth2/token' : 'https://epay-oauth.homebank.kz/oauth2/token',
            'scope' => 'webapi usermanagement email_send verification statement statistics payment',
            'client_id' => $modx->getOption('epay_client_id'),
            'client_secret' => $modx->getOption('epay_client_secret'),
            'currency' => 'KZT',
            'terminal' => $modx->getOption('epay_terminal_id'),
            'postLink' => $siteUrl.'/core/components/epay/succsess.php',
            'failurePostLink' => $siteUrl.'/core/components/epay/error.php'
        ), $config);
    }


    /**
    * @param msOrder $order
    *
    * @return array|string
    */
    public function send(msOrder $order)
    {
        if ($order->get('status') > 1) {
            return $this->error('ms2_err_status_wrong');
        }
        $params = array_merge(
            $this->config,
            array(
                'invoiceID' => $_POST['invoiceId'],
                'amount' => $_POST['amount'],                
            )
        );


        $response = $this->request($params, $this->getPaymentLink($order));
        if (is_array($response) && !empty($response['access_token'])) {

            return $this->success('', array('redirect' => $this->config['checkoutUrl'] . urlencode($token)));
        } else {
            $this->modx->log(
                modX::LOG_LEVEL_ERROR,
                '[miniShop2] Payment error while request. Request: ' . print_r(
                    $params,
                    1
                ) . ', response: ' . print_r(
                    $response,
                    1
                )
            );

            return $this->success('', array('msorder' => $order->get('id')));
        }
    }



    /**
    * Building query
    *
    * @param array $params Query params
    *
    * @return array/boolean
    */
    public function request($params = array(), $paymentEpayUrlFull)
    {
        $myCurl = curl_init();
        curl_setopt_array($myCurl, array(
            CURLOPT_URL => $paymentEpayUrlFull,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($params)
        ));


        $response = curl_exec($myCurl);
        if (curl_errno($myCurl)) {
            $result = curl_error($myCurl);
        }


        header('Content-type: application/json');

        curl_close($myCurl);

        return $response;
    }


    /**
    * Returns a direct link for continue payment process of existing order
    *
    * @param msOrder $order
    *
    * @return string
    */
    public function getPaymentLink(msOrder $order)
    {
        return $this->config['paymentEpayUrl'] . '?' .
        http_build_query(array(
            'action' => 'continue',
            'msorder' => $order->get('id'),
            'mscode' => $this->getOrderHash($order),
        ));
    }
}
    Артур Шевченко
    09 января 2023, 15:23
    0
    В minishop2 предусмотрена возможность добавлять собственные сервисы. Вот пример. В документации к вашему платёжному сервису есть раздел Платёж по API думаю вам стоит использовать именно этот способ проведения платежа, а не JS.
      Viktor
      09 января 2023, 15:26
      0
      Нужно чтобы именно был редирект на страницу оплаты, а не чтобы заполнение данных происходило через сайт.
        Артур Шевченко
        09 января 2023, 15:31
        0
        В minishop2 оплата на сайте не происходит. Во всяком случае не знаю ни одного модуля, который бы позволял произвести оплату не покидая сайт. В методе оплаты же есть метод getPaymentLink и именно он должен возвращать ссылку на страницу оплаты вашего мерчанта, после чего в обработчике заказа будет выполнен редирект.
          Viktor
          10 января 2023, 09:17
          0
          Вот сделал новый метод.
          <?php
          
          if (!class_exists('msPaymentInterface')) {
              require_once dirname(__FILE__, 3) . '/handlers/mspaymenthandler.class.php';
          }
          
          class EpayHalykBank extends msPaymentHandler implements msPaymentInterface
          {
          
              /**
              * EpayHalykBank constructor.
              *
              * @param xPDOObject $object
              * @param array $config
              */
              function __construct(xPDOObject $object, $config = array())
              {
                  parent::__construct($object, $config);
          
                  $siteUrl = $this->modx->getOption('site_url');
                  $assetsUrl = $this->modx->getOption('assets_url') . 'components/minishop2/';
                  $paymentUrl = $siteUrl . substr($assetsUrl, 1) . 'payment/mspepayhalykbank.php';
          
                  $this->config = array_merge(array(
                      'grant_type' => 'client_credentials',
                      'debug' => $modx->getOption('epay_debug'),
                      'epayTokenAuthUrl' => $this->config['debug'] == 1 ? $modx->getOption('epay_test_auth_url') : $modx->getOption('epay_prod_auth_url'),
                      'payPageUrl' => $this->config['debug'] == 1 ? $modx->getOption('epay_test_pay_page_url') : $modx->getOption('epay_pay_page_url'),
                      'scope' => 'webapi usermanagement email_send verification statement statistics payment',
                      'client_id' => $modx->getOption('epay_client_id'),
                      'client_secret' => $modx->getOption('epay_client_secret'),
                      'currency' => $modx->getOption('epay_payment_currency'),
                      'terminal_id' => $modx->getOption('epay_terminal_id'),
                      'postLink' => $modx->makeUrl($modx->getOption('epay_post_success_page_id')),
                      'failurePostLink' => $modx->makeUrl($modx->getOption('epay_post_error_page_id'))
                  ), $config);
              }
          
          
          
              /**
              * Create Auth Token
              *
              * @param 
              *
              * @return string
              */
              public function paymentAuth(msOrder $order)
              {
                  $authUrl = $this->config['epayTokenAuthUrl'];
          
                  $params = array(
                      'grant_type' => $this->config['grant_type'],
                      'scope' => $this->config['scope'],
                      'client_id' => $this->config['client_id'],
                      'client_secret' => $this->config['client_secret'],
                      'invoiceID' => $this->getOrderHash($order),
                      'amount' => $order->get('cost'),
                      'currency' => $this->config['currency'],
                      'terminal' => $this->config['terminal_id'],
                      'postLink' => $this->config['postLink'],
                      'failurePostLink' => $this->config['failurePostLink']
                  );
          
                  $myCurl = curl_init();
                  curl_setopt_array($myCurl, array(
                      CURLOPT_URL => $authUrl,
                      CURLOPT_RETURNTRANSFER => true,
                      CURLOPT_POST => true,
                      CURLOPT_POSTFIELDS => http_build_query($params)
                  ));
          
                  $response = curl_exec($myCurl);
                  curl_close($myCurl);
          
                  return json_decode($response, true);
          
              }
          
          
              /**
              * Returns a direct link for continue payment process of existing order
              *
              * @param msOrder $order
              *
              * @return string
              */
              public function getPaymentLink(msOrder $order)
              {
          
                  $authResponse = $this->paymentAuth($order);
          
                  $msAddress = $order->getOne('Address');
                  $orderPhone = $msAddress->get('phone');
                  $orderEmail = $msAddress->get('email');
                  $orderReceiver = $msAddress->get('receiver');
                  $orderComment = $msAddress->get('comment');
          
                  if(substr($orderPhone, 0, 1) == '7'){
                      $orderPhone = '+' . $orderPhone;
                  }
                  // if($authResponse['access_token'])
                  // 'data' => "{\"statement\":{\"name\":\"Arman      Ali\",\"invoiceID\":\"80000016\"}}",
          
                  return $this->config['payPageUrl'] . '?' .
                  http_build_query(array(
                      'action' => 'continue',
                      'msorder' => $order->get('id'),
                      'mscode' => $this->getOrderHash($order),
                      'invoiceId' => $this->getOrderHash($order),
                      'backLink' => $this->config['postLink'].'?action=success',
                      'failureBackLink' => $this->config['failurePostLink'].'?action=error',
                      'postLink' => $this->$siteUrl,
                      'failurePostLink' => $this->config['failurePostLink'].'?action=error',
                      'language' => 'rus',
                      'description' => 'Оплата в интернет магазине',
                      'accountId' => $this->config['client_id'],
                      'terminal' => $this->config['terminal_id'],
                      'amount' => $order->get('cost'),
                      'data' => array(
                          'name' => $orderReceiver,
                          'orderId' => $order->get('id'),
                          'invoiceId' => $this->getOrderHash($order),
                          'phone' => $orderPhone,
                          'email' => $orderEmail,                
                          'comment' => $orderComment
                      ),
                      'currency' => $this->config['currency'],
                      'phone' => $orderPhone,
                      'email' => $orderEmail,
                      'cardSave' => true,
                      'auth' => $authResponse
          
                  ));
              }
          }
          Пытаюсь зарегестрировать, так как в доках, через консоль
          if ($miniShop2 = $modx->getService('miniShop2')) {
              $miniShop2->addService('payment', 'EpayHalykBank',
                  '{core_path}components/minishop2/custom/payment/epayhalykbank.class.php'
              );
          }
          Где EpayHalykBank это имя класса оплаты. Но когда хочу добавить этот обработчик, он просто не появляется. Пути проверял, имя файла тоже проверил, он содержит class

          Можете пожалуйста подсказать, как исправить?
            Viktor
            10 января 2023, 11:07
            0
            Проблема регистрации была в том что я использовал
            $modx
            а тут нужно было
            $this->modx
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      6