Артур Шевченко · 22 мая 2024, 22:24 Нужно переписать метод submit в обработчике заказа, так как из коробки он возвращает ответ сразу на фронт. А когда получишь ответ, там в параметре redirect будет ссылка на оплату. Тут вместо echo нужно сделать return и убрать die(). И тогда если сделать так $response = $miniShop2->order->submit(); $modx->sendRedirect($response['data']['redirect']);то пользователя перекинет на оплату. Вопросы / [miniShop2 + mspTinkoff] Можно ли вызвать оплату заказа через API ? 3 +1 1
Наумов Алексей · 19 апреля 2024, 11:49 Самое лучшее решение в данной ситуации — это сделать отдельный файл для работы с этим API, например: /assets/components/mycomponent/api.phpну или просто попроще /api.phpвнутри этого файла инициализируем MODX в API режиме, читаем, например: modx.pro/development/3163 А далее просто получаем данные, как нам нужно и выводим в json: $query = $modx->newQuery('modResource'); $query->where([ 'parent' => 2, ]); $resources = $modx->getIterator('modResource', $query); $data = []; foreach($resources as $resource) { $data[] = [ 'pagetitle' => $resource->get('pagetitle'); ]; } header("Content-Type: application/json"); echo json_encode($data); exit();да, если нужны TV поля, то запрос будет сложнее. Но эта информация тоже есть на форуме. Если уж совсем лень писать запрос — то можно внутри скрипта вызвать сниппет pdoresources: $data = $modx->runSnippet('pdoResources', [ПАРАМЕТРЫ]); Вопросы / [JSON] Как вывести страницу в формате JSON? 2 0 1
Артур Шевченко · 10 апреля 2024, 21:07 switch ($modx->event->name){ case 'msOnCreateOrder': $cart = $order->ms2->cart->get(); foreach($cart as $item){ $modx->log(1, print_r($item['options']['modification'],1)); } break; } Вопросы / [msOnCreateOrder] Получение модификаций товаров при оформлении заказа MiniShop2 1 +2 2
Артур Шевченко · 29 декабря 2023, 11:37 Если при смене контекста менять cultureKey и создать записи словаря для этого cultureKey, то будет другая запись. Вопросы / [Login] Как поменять стандартное сообщение об ошибке входа? 5 +1 1
Наумов Алексей · 06 декабря 2023, 11:02 Почитайте теперь здесь: docs.modx.pro/components/minishop2/development/events Вот реально там в первом же примере написано, что нужно сделать. Вопросы / [miniShop2] Проверка корзины при добавлении товара 6 +1 1
Артур Шевченко · 05 декабря 2023, 21:36 А почему именно в классе-обработчике, почему не в плагине? Вопросы / [miniShop2] Проверка корзины при добавлении товара 6 +1 1
Наумов Алексей · 05 декабря 2023, 20:35 Отсюда наверное стоит начать чтение: docs.modx.pro/components/minishop2/development/services/cart Вопросы / [miniShop2] Проверка корзины при добавлении товара 6 +1 1
Володя · 05 декабря 2023, 11:47 можно попробовать как при убывающей сортировке &sortby=`{"COALESCE(NULLIF(price,0),0)":"DESC"}`или при возрастающей &sortby=`{"COALESCE(NULLIF(price,0),9999999)":"ASC"}` Вопросы / [mFilter2] Сортировка по цене в каталоге 3 +1 1
Vladimir · 21 июня 2023, 11:35 Так же по этому пути должен быть ещё файл /assets/components/minishop2/payment/epayhalykbank.php/ <?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'); $isJsonRequest = (json_decode(file_get_contents('php://input')) != NULL) ? true : false; if ($_SERVER['REQUEST_METHOD'] === 'POST' && $isJsonRequest) { // $modx->log(modX::LOG_LEVEL_ERROR,'ЗАШЛИ '); $requestData = json_decode(file_get_contents('php://input'), true); $get_array = array(); parse_str($requestData['data'], $get_array); $requestData['data'] = $get_array; if(isset($requestData['invoiceId']) && !empty($requestData['invoiceId']) && isset($requestData['data']) && !empty($requestData['data']) && isset($requestData['data']['orderId']) && !empty($requestData['data']['orderId']) && isset($requestData['data']['orderHash']) && !empty($requestData['data']['orderHash'])){ /** @var miniShop2 $miniShop2 */ $miniShop2 = $modx->getService('miniShop2'); $miniShop2->loadCustomClasses('payment'); if (!class_exists('EpayHalykBank')) { exit('Error payment not exist'); } /** @var msOrder $order */ $order = $modx->newObject('msOrder'); $handler = new EpayHalykBank($order); $orderId = $requestData['data']['orderId']; $orderHash = $requestData['data']['orderHash']; $paymentInvocieId = $requestData['invoiceId']; if ($order = $modx->getObject('msOrder', array('id' => $orderId, 'order_hash' => $orderHash))) { /** @var msPaymentInterface|EpayHalykBank $handler */ $verifyingOrderPayment = $handler->handlePaymentVerification($order, array( 'invoiceID' => $paymentInvocieId, 'orderID' => $orderId, 'orderHash' => $orderId, )); if(!$verifyingOrderPayment){ die('Error when continuing order'); } die('True'); } else { exit('Error when continuing order, cannot get order'); } } } exit('Access Denied');А файл что в коре такой, самое последне изменёный <?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/'; $this->$paymentUrl = $siteUrl . substr($assetsUrl, 1) . 'payment/epayhalykbank.php'; $this->debugPayment = $this->modx->getOption('epay_debug'); $this->config = array_merge(array( 'grant_type' => 'client_credentials', 'epayTokenAuthUrl' => $this->debugPayment == 1 ? $this->modx->getOption('epay_test_auth_url') : $this->modx->getOption('epay_prod_auth_url'), 'payPageUrl' => $this->debugPayment == 1 ? $this->modx->getOption('epay_test_pay_page_url') : $this->modx->getOption('epay_pay_page_url'), 'scope' => 'webapi usermanagement email_send verification statement statistics payment', 'client_id' => $this->modx->getOption('epay_client_id'), 'client_secret' => $this->modx->getOption('epay_client_secret'), 'currency' => $this->modx->getOption('epay_payment_currency'), 'terminal_id' => $this->modx->getOption('epay_terminal_id'), 'transactionCheckStatusUrl' => $this->debugPayment == 1 ? $this->modx->getOption('transaction_chech_test_url') : $this->modx->getOption('transaction_chech_prod_url'), 'postLink' => $this->modx->makeUrl((int) $this->modx->getOption('epay_post_success_page_id'), '', '', 'full'), 'failurePostLink' => $this->modx->makeUrl((int) $this->modx->getOption('epay_post_error_page_id'), '', '', 'full') ), $config); } public function getOrderHashOld(msOrder $order) { return md5( $order->get('id') . $order->get('num') . $order->get('createdon') . $order->get('cart_cost') . $order->get('delivery_cost') ); } public function getOrderHash(msOrder $order) { return substr(preg_replace('/[^0-9]/', '', md5( $order->get('id') . $order->get('num') . $order->get('createdon') . $order->get('cart_cost') . $order->get('delivery_cost') )), 0, 15); } /** * @param msOrder $order * @param array params * * @return array|string */ public function handlePaymentVerification(msOrder $order, $params = array()){ if(isset($params['invoiceID']) && !empty($params['invoiceID'])){ $generateOrderInoiceId = $this->getOrderHash($order); if($params['invoiceID'] == $generateOrderInoiceId){ $authResponse = $this->paymentAuth($order); $verifiedResponse = false; if($authResponse['access_token']){ $getPaymentStatus = $this->jwt_request( $this->config['transactionCheckStatusUrl'].$generateOrderInoiceId, $authResponse['access_token'] ); $verifiedResponse = $getPaymentStatus; } return $this->receive($order, array( 'verifyedResponse' => $verifiedResponse )); } } return false; } /** * @param msOrder $order * @param array $params * * @return bool */ public function receive(msOrder $order, $params = array()) { if(!empty($params['verifyedResponse']) && !empty($params['verifyedResponse']) && !empty($params['verifyedResponse']['resultCode'])){ if ($params['verifyedResponse']['resultCode'] == '100') { $this->ms2->changeOrderStatus($order->get('id'), 2); // Set status "paid" return true; } else { $this->ms2->changeOrderStatus($order->get('id'), 1002); // Set status "Payment error" $msOrder->set('payment_response_status', $result); $msOrder->save(); return false; } } return false; } /** * @param msOrder $order * * @return array|string */ public function send(msOrder $order) { if ($order->get('status') > 1) { return $this->error('ms2_err_status_wrong'); } $authResponse = $this->paymentAuth($order); if (is_array($authResponse) && !empty($authResponse['access_token'])) { // $this->modx->log(1, 'OPLATA_NACHALAS'); $msAddress = $order->getOne('Address'); $orderPhone = $msAddress->get('phone'); $orderEmail = $msAddress->get('email'); $orderReceiver = $msAddress->get('receiver'); if(substr($orderPhone, 0, 1) == '7'){ $orderPhone = '+' . $orderPhone; } $orderHash = $this->getOrderHash($order); // $this->modx->log(1, $this->getOrderHash($order)); $backLinkParams = '&msorder='.$order->get('id').'&mscode='.$this->getOrderHashOld($order).'&invoice_id='.$orderHash; $reqParams = array( 'invoiceId' => $orderHash, 'backLink' => $this->config['postLink'].'?action=success'.$backLinkParams, 'failureBackLink' => $this->$paymentUrl, 'postLink' => $this->$paymentUrl, 'failurePostLink' => $this->$paymentUrl, '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'), 'orderHash' => $this->getOrderHashOld($order), 'invoiceId' => $orderHash, 'phone' => $orderPhone, 'email' => $orderEmail ), 'currency' => $this->config['currency'], 'phone' => $orderPhone, 'email' => $orderEmail, 'cardSave' => true, 'auth' => $authResponse ); return $this->success('', array('payment_response' => $reqParams)); } else { $this->modx->log( modX::LOG_LEVEL_ERROR, '[miniShop2] Payment error while request. Request: ' . print_r( $params, 1 ) . ', authResponse: ' . print_r( $authResponse, 1 ) ); return $this->success('', array('msorder' => $order->get('id'))); } } private function jwt_request($url, $token) { header('Content-Type: application/json'); // Specify the type of data $ch = curl_init($url); // Initialise cURL $authorization = "Authorization: Bearer ".$token; // Prepare the authorisation token curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization )); // Inject the token into the header curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // This will follow any redirects $result = curl_exec($ch); // Execute the cURL statement curl_close($ch); // Close the cURL connection return json_decode($result, true); // Return the received data } /** * 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->$paymentUrl, 'failurePostLink' => $this->$paymentUrl ); $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); // $this->modx->log(1, $response); 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) { $redirectPaymentUrl = $this->config['payPageUrl']; return $redirectPaymentUrl; } } Вопросы / [miniShop2] Почему не подключается самописный сервис оплаты? 17 +2 1
Dan · 31 мая 2023, 13:23 А если так: 'where' => ['Data.old_price > Data.price AND Data.internet_magazin = 1'] Вопросы / [msProducts] Как вывести товары у которых old_price больше чем price 9 +1 2
PageBuilder — визуальный конструктор страниц для MODX 3 Класс! Пара моментов смутила: 1. Почему бы чанки сразу не вынести в файлы? 2. На фронте грузится свой CSS для стандартных блоков<link rel="stylesheet" href="/a...
mxDadata — интеграция DaData (Suggest, Clean, Party) с MODX 3 и MiniShop3 Вышла новая версия: [1.0.2-pl] — 2026-10-06 Fixed #9 Права mxdadata_edit, mxdadata_logs, mxdadata_cache_clear теперь проверяются в connector.php и в Processors\Mgr\Pr...
msp3PaymentSkeleton — шаблон для создания платёжных дополнений MiniShop3 вот круто. я как то писал платежное дополнение и парился как что. а теперь надеюсь все проше будет :-)
MiniShop3 1.2.0 - 1.3.0 Самое интересное Пообщались с клиентом он сказал что тыкал в позицию т.к. она не добавлялась (видимо лагал инет) и вот она размножилась таким образом.
Modx Revo 2.8.8 + Minishop 2 (4.4.2) + Babel 3.5.2 - превью товаров в админке у дополнител... Сначала сравните ответ connector для исходного товара и его перевода во вкладке Network. Если у перевода поле миниатюры пустое, смена чанка или рендерера сама картинку не добавит: ...
Сайт тормозит сервер, грузит процессор на 100% полезно посмотреть, какие URL запрашивают эти боты и сколько времени занимает их обработка. Частые обращения к поиску и фильтрам могут нагружать PHP сильнее, чем обычные страницы. ...
Подскажите насколько это рабочее решение Спасибо за ответ. У меня время создания заказа равно времени оплаты. Заказ оплачивается сразу через iframe на сайте. При нажатии на кнопку «оформить заказ» всплывает окошко робокас...
Не всегда срабатывает JS-событие Здесь лучше разделить «заказ создан» и «заказ оплачен». Первое событие фиксируется при успешном создании заказа, второе — после проверенного уведомления платёжной системы на сервер...
UiCMPGenerator дополнение для создания пакетов на днях начну делать доки, пока без видео обзора чисто текст и скрины, как будут готовы залью пакет
ResVideoGallery Для MODX 3 доступна ResVideoGallery 3.0.0-beta Компонент полностью переписан под MODX Revolution 3.* (PHP 8.4+). Что нового: 10 видеосервисов: YouTube, Vimeo, RuTube, ВКо...
Тут вместо echo нужно сделать return и убрать die(). И тогда если сделать так
то пользователя перекинет на оплату.
ну или просто попроще
внутри этого файла инициализируем MODX в API режиме, читаем, например:
modx.pro/development/3163
А далее просто получаем данные, как нам нужно и выводим в json:
да, если нужны TV поля, то запрос будет сложнее. Но эта информация тоже есть на форуме.
Если уж совсем лень писать запрос — то можно внутри скрипта вызвать сниппет pdoresources:
docs.modx.pro/components/minishop2/development/events
Вот реально там в первом же примере написано, что нужно сделать.
или при возрастающей
А файл что в коре такой, самое последне изменёный