Всего 123 801 комментарий

Vladimir
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;
}
Николай Савин
12 января 2023, 12:40
0
Кажется мы друг друга не очень понимаем.

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

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

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

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

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

Как его тригерить — посмотрите в том же Paypal или например Робокасса
Vladimir
12 января 2023, 08:43
0
У сервиса оплаты минишопа есть такой метод как «receive», как я понял из сущ пейпала, что это метод при котором отправляется запрос на проверку успешной оплаты, как его за тригерить? или он сам тригерится после возвращение на страницу оформления заказа с параметрами, успеха, номера заказа и хэша заказа?
Vladimir
12 января 2023, 08:37
0
Мне нужно наверно сделать как в пейпале, добавить php, в ассет платежей минишопа, и ловить это сообщение, а потом что сделать? вручную менять статус? или есть у минишопа метод для этого после успешной оплаты?
scorpi71183
12 января 2023, 03:04
0
Подскажите пожалуйста! Как сделать чтобы msOptionsPrice не модицировал цена по умолчанию… Т.е после загрузки страницы не ставил цену и input type=«hidden» name=«options[color]» value=«Яркое блестящее серебро (HPB)»
, а модицировал только при выборе опции кликом… А то получается что первоначальная цена (цена товара дофолтовая) не доступна…
Константин Ильин
11 января 2023, 19:59
+1
@Илья Уткин, НЕ стал создавать пост. Посмотри пожалуйста, вроде как на MySQL 8 не работает сортировка из-за поля rank, т.к. это слово зарезервировано в MySQL 8
Артур Шевченко
11 января 2023, 19:10
0
Вы сейчас удивитесь, но чтобы прикрепить файл к письму отправленному через AjaxForm+FormIt не нужно делать ничего. Главное чтобы у формы был атрибут enctype=«multipart/form-data».
Alex
11 января 2023, 16:55
0
пробую в &where=`{«published:=»:1,«resource_id:=»:[[*id]]}` прописать исключение для b1_json, Ничего не получается.
Подскажите пожалуйста
Иван
11 января 2023, 13:34
0
Думаю какой нибудь ген директор или топ менеджеру оценит работаспособность на iphone или macbook))
Роман
11 января 2023, 13:29
0
В источнике файлов который указываю для TV image+ убрал слеш в начале assets/theme/media/images/ теперь вроде заработал image+ с источником. Но конечно плохо все с этим в MODx, если сравнивать с wordpress даже, разочарован
Димыч
11 января 2023, 13:18
0
Сафари технически поддерживает, только вот он по умолчанию не включен. В следующих релизах обещают полноценную работу. Там проблема в том, что в мобильном Сафари ленивая загрузка через скрипт приводила к тому, что картинки вообще не показывались. По крайней мере в более старых браузерах. По мне, так если браузер не умеет, то пусть хоть загружает нормально.

Роман
11 января 2023, 11:53
0
image+ вроде норм тема, но не могу понять, не работает с созданным источником файлов, только с filesystem :(
Николай Савин
11 января 2023, 08:24
0
Откройте плагин msTelegram и попробуйте заменить строчку

$contacts = $modx->getObject('msOrderAddress', array('id'=> $msOrder->address));
на следующий код

$contacts = $msOrder->Address;
Роман
11 января 2023, 00:27
0
Да вот тоже не требовалось, но теперь с инстаграма фотки человек добавляет, и фото делает для инсты, а там вертикальная ориентация, а обрезать надо под квадрат, а обьект не всегда в центре, то у нижней части то по центру, то в верхней части, заранее подрезать на пк или телефоне не удобно, а скрипт режет в квадрат из вертикальных фото от центра, и все, приехали. Всегда что то подрезается нужное, в общем, нужно подгонять перед добавлением на сайт фото что бы нужная часть фото была по центру.

moreGallery платное дополнение как я понял, не вариант, и слишком навороченное, много всего лишнего, пробую image+
Артур Шевченко
10 января 2023, 23:45
0
У меня за 4 года работы с modx ни разу заказчик такой функционал в админке не просил. Но я наверное всё же сделаю какой-нибудь простенький доп, пусть будет.
Артур Шевченко
10 января 2023, 23:43
0
Если надо просто обрезать, думаю проще всего использовать Image+