Roman

Roman

С нами с 21 августа 2017; Место в рейтинге пользователей: #136
Roman
10 октября 2019, 16:47
0
Конфиг:
MODX Revolution 2.7.1-pl
shopkeeper3 3.2.7-pl3
yandexmoney 1.0.4-pl
Вывожу через Formit.
[[!FormIt?
&hooks=`spam,shk_fihook,email,FormItAutoResponder,YandexMoneyHook,redirect`
&submitVar=`order-[[+id]]`
&emailTpl=`shopOrderReport`
&emailSubject=`В интернет-магазине [[++site_name]] сделан новый заказ`
&emailTo=`info@blabla.ru`
&emailFrom=`info@blabla.ru`

&fiarSubject=`Вы сделали заказ в интернет-магазине [[++site_name]]`
&fiarTpl=`shopOrderReport`
&fiarFromName=`[[++site_name]]`
&fiarFrom=`info@blabla.ru`
&fiarReplyTo=`[[++emailsender]]`
&fiarToField=`email`


&redirectTo=`357`
&validate=`agree:required,email:required,fullname:required,phone:required:regexp="^\+7\s\(\d{3}\)\s\d{3}\s\d{2}\s\d{2}$",course:required,g-recaptcha-response:required`
&errTpl=`<br /><span class="error">[[+error]]</span>`
]]
Сниппет: shk_fihook
<?php
/**
 * FormIt hook for Shopkeeper 3.x
 */

//ini_set('display_errors',1);
//error_reporting(E_ALL);

$output = false;

if(!defined('SHOPKEEPER_PATH')){
    define('SHOPKEEPER_PATH', MODX_CORE_PATH."components/shopkeeper3/");
}

//Определяем параметры сниппета Shopkeeper
$sys_property_sets = $modx->getOption( 'shk3.property_sets', $modx->config, 'default' );
$sys_property_sets = explode( ',', $sys_property_sets );
$propertySetName = trim( current( $sys_property_sets ) );

$snippet = $modx->getObject('modSnippet',array('name'=>'Shopkeeper3'));
$properties = $snippet->getProperties();
if( $propertySetName != 'default' && $modx->getCount( 'modPropertySet', array( 'name' => $propertySetName ) ) > 0 ){
    $propSet = $modx->getObject( 'modPropertySet', array( 'name' => $propertySetName ) );
    $propSetProperties = $propSet->getProperties();
    if(is_array($propSetProperties)) $properties = array_merge($properties,$propSetProperties);
}

$lang = $modx->getOption( 'lang', $properties, 'ru' );
$modx->getService( 'lexicon', 'modLexicon' );
$modx->lexicon->load( $lang . ':shopkeeper3:default' );

if( !empty( $_SESSION['shk_order'] ) ){
    
    require_once SHOPKEEPER_PATH . "model/shopkeeper.class.php";
    $shopCart = new Shopkeeper( $modx, $properties );
    
    $modx->addPackage( 'shopkeeper3', SHOPKEEPER_PATH . 'model/' );
    
    //shopkeeper settings
    $contacts_fields = array();
    $response = $modx->runProcessor('getsettings',
        array( 'settings' => array('contacts_fields') ),
        array( 'processors_path' => $modx->getOption( 'core_path' ) . 'components/shopkeeper3/processors/mgr/' )
    );
    if ($response->isError()) {
        echo $response->getMessage();
    }
    if($result = $response->getResponse()){
        
        $temp_arr = !empty( $result['object']['contacts_fields'] ) ? $result['object']['contacts_fields'] : array();
        if( !empty( $temp_arr ) ){
            
            foreach( $temp_arr as $opt ){
                
                $contacts_fields[$opt['name']] = $opt;
                
            }
            
        }
        
    }
    
    $userId = $modx->getLoginUserID( $modx->context->key );
    if( !$userId ) $userId = 0;
    
    //Контактные данные
    $contacts = array();
    $allFormFields = $hook->getValues();
    foreach( $allFormFields as $key => $val ){
        
        if( in_array( $key, array_keys( $contacts_fields ) ) ){
            
            $temp_arr = array(
                'name' => $contacts_fields[$key]['name'],
                'value' => $val,
                'label' => $contacts_fields[$key]['label']
            );
            
            array_push( $contacts, $temp_arr );
            
        }
        
    }
    
    $contacts = json_encode( $contacts );
    
    $emailField = $modx->getOption( 'fiarToField', $hook->config, 'email' );
    $phoneField = $modx->getOption( 'phoneField', $hook->config, 'phone' );
    $deliveryField = $modx->getOption( 'deliveryField', $hook->config, 'shk_delivery' );
    $paymentField = $modx->getOption( 'paymentField', $hook->config, 'payment' );
    
    //Доставка
    $delivery_price = !empty( $shopCart->delivery['price'] ) ? $shopCart->delivery['price'] : 0;
    $delivery_name = !empty( $shopCart->delivery['label'] ) ? $shopCart->delivery['label'] : '';
    if( !$delivery_name ){
	$delivery_name = !empty( $allFormFields[$deliveryField] ) ? $allFormFields[$deliveryField] : '';
    }
    
    //Сохраняем данные заказа
    $order = $modx->newObject('shk_order');
    $insert_data = array(
        'contacts' => $contacts,
        'options' => '',
        'price' => Shopkeeper::$price_total,
        'currency' => $shopCart->config['currency'],
        'date' => strftime('%Y-%m-%d %H:%M:%S'),
        'sentdate' => strftime('%Y-%m-%d %H:%M:%S'),
        'note' => '',
        'email' => isset( $allFormFields[$emailField] ) ? $allFormFields[$emailField] : '',
        'delivery' => $delivery_name,
        'delivery_price' => $delivery_price,
        'payment' => isset( $allFormFields[$paymentField] ) ? $allFormFields[$paymentField] : '',
        'tracking_num' => '',
        'phone' => isset( $allFormFields[$phoneField] ) ? $allFormFields[$phoneField] : '',
        'status' => $modx->getOption( 'shk3.first_status', null, '1' )
    );
    if( $userId ){
        $insert_data['userid'] = $userId;
    }
    $order->fromArray($insert_data);
    $saved = $order->save();
    
    //Сохраняем товары заказа
    if( $saved ){

        $purchasesData = $shopCart->getProductsData( true );

        foreach( $shopCart->data as $key => $p_data ){

            $options = !empty( $p_data['options'] ) ? json_encode( $p_data['options'] ) : '';
            $fields_data = !empty( $purchasesData[ $key ] ) ? $purchasesData[ $key ] : array();
            $fields_data['url'] = !empty( $p_data['url'] ) ? $p_data['url'] : '';
            unset( $fields_data['id'] );
            $fields_data_str = json_encode( $fields_data );

            $insert_data = array(
                'p_id' => $p_data['id'],
                'order_id' => $order->id,
                'name' => $p_data['name'],
                'price' => $p_data['price'],
                'count' => $p_data['count'],
                'class_name' => $p_data['className'],
                'package_name' => $p_data['packageName'],
                'data' => $fields_data_str,
                'options' => $options
            );

            $purchase = $modx->newObject('shk_purchases');
            $purchase->fromArray( $insert_data );
            $purchase->save();

        }

        $shopCart->setOrderDataSession( $order->toArray() );

    }
    
    $modx->invokeEvent( 'OnSHKChangeStatus', array( 'order_ids' => array( $order->id ), 'status' => $order->status ) );
    
    $orderOutputData = $shopCart->getOrderData( $order->id );
    
    //OnSHKsaveOrder
    $evtOut = $modx->invokeEvent('OnSHKsaveOrder',array('order_id' => $order->get('id')));
    if(is_array($evtOut)) $orderOutputData .= implode('',$evtOut);
    
    $hook->setValues(array(
        'orderID' => $order->get('id'),
        'orderDate' => $order->get('date'),
        'orderPrice' => $order->get('price'),
        'orderCurrency' => $shopCart->config['currency'],
        'orderOutputData' => $orderOutputData
    ));
    
    $shopCart->request_empty( false );
    
    $output = true;
    
}else{
    
    $hook->addError( 'error_message', $modx->lexicon('shk.order_empty') );
    $output = false;
    
}

return $output;
assets/components/yandexmoney/connector_result.php
<?php
require_once dirname(dirname(dirname(dirname(__FILE__)))).'/config.core.php';

require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';

$modx = new modX();
$modx->initialize('web');

$snippet = $modx->getObject('modSnippet', array('name' => 'YandexMoney'));
$config  = $snippet->getProperties();

if (!defined('YANDEXMONEY_PATH')) {
    define('YANDEXMONEY_PATH', MODX_CORE_PATH."components/yandexmoney/");
}

require_once YANDEXMONEY_PATH.'model/yandexmoney.class.php';

if (isset($_GET['fail']) && $_GET['fail'] == 1) {
    if ($res = $modx->getObject('modResource', $config['fail_page_id'])) {
        $modx->sendRedirect($modx->makeUrl($config['fail_page_id'], '', '', 'full'));
    }
    exit;
} elseif (isset($_GET['success']) && $_GET['success'] == 1) {
    if ($res = $modx->getObject('modResource', $config['success_page_id'])) {
        $modx->sendRedirect($modx->makeUrl($config['success_page_id'], '', '', 'full'));
    }
    exit;
} elseif (isset($_GET['return']) && $_GET['return'] == 1) {
    $orderId = isset($_GET['order_id']) ? (int)$_GET['order_id'] : 0;
    if ($orderId !== 0) {
        $modx->addPackage('shopkeeper3',  $modx->getOption('core_path').'components/shopkeeper3/model/');;
        $order = $modx->getObject('shk_order',array('id'=>$orderId));
        if ($order) {
            $sql  = 'SELECT payment_id FROM '.$modx->getTableName('YandexMoneyKassaPayment').' WHERE `order_id` = :orderId';
            $stmt = $modx->prepare($sql);
            $stmt->bindValue(':orderId', $orderId, \PDO::PARAM_INT);
            $stmt->execute();
            $dataSet = $stmt->fetch();
            $stmt->closeCursor();
            if (!empty($dataSet)) {
                $paymentId = $dataSet[0];
                $ym        = new Yandexmoney($modx, $config);
                $payment   = $ym->getPaymentById($paymentId);
                if ($payment !== null) {
                    if ($payment->getPaid()) {
                        if ($payment->getStatus() === \YandexCheckout\Model\PaymentStatus::WAITING_FOR_CAPTURE) {
                            $ym->capturePayment($payment, false);
                        }
                        $paymentInfo = $ym->getPaymentById($paymentId);
                        if ($paymentInfo->getStatus() == \YandexCheckout\Model\PaymentStatus::SUCCEEDED) {
                            $ym->updateOrderStatus($order, $config['ya_billing_status']);
                        }
                        if ($res = $modx->getObject('modResource', $config['success_page_id'])) {
                            $modx->sendRedirect($modx->makeUrl($config['success_page_id'], '', '', 'full'));
                        }
                        exit;
                    }
                }
            }
        }
    }
    if ($res = $modx->getObject('modResource', $config['fail_page_id'])) {
        $modx->sendRedirect($modx->makeUrl($config['fail_page_id'], '', '', 'full'));
    }
    exit;
} elseif (isset($_GET['notification']) && $_GET['notification'] == 1) {
    $source = file_get_contents('php://input');
    $ym     = new Yandexmoney($modx, $config);
    if (empty($source)) {
        $ym->log('notice', 'Call capture notification controller without body');
        header('HTTP/1.1 400 Empty notification object');

        return;
    }
    $ym->log('info', 'Notification body: '.$source);
    $json = json_decode($source, true);
    if (empty($json)) {
        if (json_last_error() === JSON_ERROR_NONE) {
            $message = 'empty object in body';
        } else {
            $message = 'invalid object in body: '.json_last_error_msg();
        }
        $ym->log('warning', 'Invalid parameters in capture notification controller - '.$message);
        header('HTTP/1.1 400 Invalid notification object');

        return;
    }
    try {
        if ($json['event'] == \YandexCheckout\Model\NotificationEventType::PAYMENT_WAITING_FOR_CAPTURE) {
            $object = new YandexCheckout\Model\Notification\NotificationWaitingForCapture($json);
            $ym->log('error', 'Notification waiting for capture init');
        } else {
            $object = new YandexCheckout\Model\Notification\NotificationSucceeded($json);
            $ym->log('error', 'Notification succeeded init');
        }
    } catch (\Exception $e) {
        $ym->log('error', 'Invalid notification object - '.$e->getMessage());
        header('HTTP/1.1 500 Server error: '.$e->getMessage());

        return;
    }
    $payment = $ym->getPaymentById($object->getObject()->getId());
    if ($payment === null) {
        $ym->log('error', 'Payment not found ');
        echo json_encode(array('success' => false, 'reason' => 'Payment not found'));
        exit();
    }
    $result = $ym->capturePayment($object->getObject());
    if (!$result) {
        header('HTTP/1.1 500 Server error 1');
        exit();
    }
    if ($result->getStatus() === \YandexCheckout\Model\PaymentStatus::SUCCEEDED) {
        try {
            $orderId = $object->getObject()->getMetadata()->offsetGet('order_id');
            $modx->addPackage('shopkeeper3',  $modx->getOption('core_path').'components/shopkeeper3/model/');
            $order = $modx->getObject('shk_order',array('id'=>$orderId));
            
            $res   = $ym->updateOrderStatus($order, $config['ya_billing_status']);
        } catch (Exception $e) {
            $ym->log('info', var_export($e, true));
        }
    } else {
        $ym->log('info', 'Failed');
    }

    echo json_encode(array('success' => ($result->getStatus() === \YandexCheckout\Model\PaymentStatus::SUCCEEDED)));
    exit();
}

$ym = new Yandexmoney($modx, $config);
$ym->ProcessResult();
Не помню, вносил ли правки но кину сюда же
core/components/yandexmoney/model/yandexmoney.class.php
<?php

/**
 * YandexMoney for MODX Revo
 *
 * Payment
 *
 * @author YandexMoney
 * @package yandexmoney
 * @version 2.0.0
 */

use YandexCheckout\Model\Payment;

require_once YANDEXMONEY_PATH.'lib/autoload.php';

$modx->addPackage('yandexmoney', YANDEXMONEY_PATH . 'model/');

class Yandexmoney
{
    /** @var int Оплата через yandex.деньги вообще не используется */
    const MODE_NONE = 0;

    /** @var int Оплата производится через Яндекс.Кассу */
    const MODE_KASSA = 1;

    /** @var int Оплата производится через Яндекс.Деньги */
    const MODE_MONEY = 2;

    /** @var int Оплата производится через Яндекс.Платёжку */
    const MODE_BILLING = 3;

    /** @var int Какой способ оплаты используется, одна из констант MODE_XXX */
    private $mode;

    private $paymode;

    public $email = false;
    public $phone = false;

    public $test_mode;
    public $org_mode;

    public $orderId;
    public $orderTotal;
    public $userId;

    public $successUrl;
    public $failUrl;

    public $reciver;
    public $formcomment;
    public $short_dest;
    public $writable_targets = 'false';
    public $comment_needed = 'true';
    public $label;
    public $quickpay_form = 'shop';
    public $payment_type = '';
    public $targets;
    public $sum;
    public $comment;
    public $need_fio = 'true';
    public $need_email = 'true';
    public $need_phone = 'true';
    public $need_address = 'true';

    public $shopid;
    public $account;
    public $password;

    public $method_ym;
    public $method_cards;
    public $method_cash;
    public $method_wm;
    public $method_ab;
    public $method_sb;
    public $method_installments;

    public $pay_method;

    public $alfaLogin;
    public $qiwiPhone;

    public $debug_log;

    /** @var string Идентификатор магазина в Яндекс.Платёжке */
    public $ya_billing_id;

    /** @var string Описание платежа, заданное из админки */
    public $ya_billing_purpose;

    /** @var string ФИО плательщика, переданное из запроса пользователя */
    public $ya_billing_fio;

    private $_apiClient;

    function __construct(modX &$modx, $config = array())
    {
        $this->mode = self::MODE_NONE;
        switch ($config['mode']) {
            case 1:
                $this->mode = self::MODE_MONEY;
                break;
            case 2:
            case 3:
                $this->mode = self::MODE_KASSA;
                break;
            case 4:
                $this->mode = self::MODE_BILLING;
                break;
        }

        $this->org_mode = ($config['mode'] == 2 || $config['mode'] == 3);
        $this->paymode = (bool) ($config['mode'] == 3);

        if (isset($config) && is_array($config)){
            foreach ($config as $k=>$v){
                if ($k != 'mode') {
                    $this->$k = $v;
                }
            }
        }
        $this->modx =& $modx;
        $this->config = $config;

        if (empty($this->debug_log)) {
            $this->debug_log = false;
        } else {
            $this->debug_log = true;
        }
    }

    public function getFormUrl()
    {
        if ($this->mode != self::MODE_BILLING) {
            $demo = ($this->test_mode) ? 'demo' : '';
            $mode = ($this->org_mode) ? '/eshop.xml' : '/quickpay/confirm.xml';
            return 'https://' . $demo . 'money.yandex.ru' . $mode;
        }
        return 'https://money.yandex.ru/fastpay/confirm';
    }

    public function checkPayMethod()
    {
        if ($this->mode == self::MODE_BILLING) {
            $fio = explode(' ', $_POST['ya-billing-fio']);
            if (count($fio) != 3) {
                return false;
            }
            foreach ($fio as $index => $value) {
                $value = trim($value);
                if (empty($value)) {
                    return false;
                }
                $fio[$index] = $value;
            }
            $this->ya_billing_fio = implode(' ', $fio);
            return true;
        }
        if ($this->mode == self::MODE_KASSA) {
            if (!$this->paymode) {
                if (in_array($this->pay_method, \YandexCheckout\Model\PaymentMethodType::getEnabledValues())) {
                    if ($this->pay_method === \YandexCheckout\Model\PaymentMethodType::QIWI) {
                        $phone = preg_replace('/[^\d]+/', '', $this->qiwiPhone);
                        if (empty($phone)) {
                            return false;
                        }
                        $this->qiwiPhone = $phone;
                    }
                    if ($this->pay_method === \YandexCheckout\Model\PaymentMethodType::ALFABANK) {
                        $login = trim($this->alfaLogin);
                        if (empty($login)) {
                            return false;
                        }
                        $this->alfaLogin = $login;
                    }
                }
            }
            return true;
        }
        return (in_array($this->pay_method, array('PC','AC','MC','GP','WM','AB','SB','MA','PB','QW', 'installments')) || $this->paymode);
    }

    public function getSelectHtml()
    {
        $result = json_encode(array('mode' => $this->mode));
        if ($this->mode == self::MODE_MONEY) {
            return "<option value=''>Яндекс.Касса (банковские карты, электронные деньги и другое)</option>";
        } elseif ($this->mode == self::MODE_KASSA) {
            if ($this->paymode) {
                return "<option value=''>Яндекс.Касса (банковские карты, электронные деньги и другое)</option>";
            }
            $translations = array(
                \YandexCheckout\Model\PaymentMethodType::ALFABANK => array('ab', 'Оплата через Альфа-Клик'),
                \YandexCheckout\Model\PaymentMethodType::MOBILE_BALANCE => array('ma', 'Платеж со счета мобильного телефона'),
                \YandexCheckout\Model\PaymentMethodType::CASH => array('cash', 'Оплата наличными через кассы и терминалы'),
                \YandexCheckout\Model\PaymentMethodType::WEBMONEY => array('wm', 'Оплата из кошелька в системе WebMoney'),
                \YandexCheckout\Model\PaymentMethodType::QIWI => array('qw', 'Оплата через QIWI Wallet'),
                \YandexCheckout\Model\PaymentMethodType::SBERBANK => array('sb', 'Оплата через Сбербанк: оплата по SMS или Сбербанк Онлайн'),
                \YandexCheckout\Model\PaymentMethodType::YANDEX_MONEY => array('ym', 'Оплата из кошелька в Яндекс.Деньгах'),
                \YandexCheckout\Model\PaymentMethodType::BANK_CARD => array('cards', 'Оплата с произвольной банковской карты'),
                \YandexCheckout\Model\PaymentMethodType::INSTALLMENTS => array('installments', 'Заплатить по частям'),
                \YandexCheckout\Model\PaymentMethodType::TINKOFF_BANK => array('tinkoff_bank', 'Интернет-банк Тинькофф'),
            );
            $list_methods = array();
            foreach (\YandexCheckout\Model\PaymentMethodType::getEnabledValues() as $paymentMethodCode) {
                $list_methods[$paymentMethodCode] = array(
                    'key'   => $translations[$paymentMethodCode][0],
                    'label' => $translations[$paymentMethodCode][1],
                );
            }
            $output = '';
            foreach ($list_methods as $long_name => $method_desc) {
                $key = $method_desc['key'];
                $by_default = (in_array($key, array('ym', 'cards'))) ? true : $this->org_mode;
                if ($this->{'method_' . $key} == 1 && $by_default) {
                    $output .= '<option value="' . $long_name . '"';
                    if ($this->pay_method == $long_name) {
                        $output .= ' selected ';
                    }
                    $output .= '>' . $method_desc['label'] . '</option>';
                }
            }
            return $output;
        } elseif ($this->mode == self::MODE_BILLING) {
            return "<option value='4'>Яндекс.Платежка (банковские карты, кошелек)</option>";
        }
        return $result;
    }

    public function createFormHtml()
    {
        global $modx;

        /** @var shk_order $order */
        $order = $modx->getObject('shk_order',array('id' => $this->orderId));

        if ($this->mode == self::MODE_KASSA) {
            $redirectUrl = 'https://' . str_replace(array('http://', 'https://'), '' , $modx->config['site_url'])
                . 'assets/components/yandexmoney/connector_result.php?return=1&order_id=' . $this->orderId;
            $payment = $this->createKassaPayment($order, $redirectUrl);
            if ($payment === null) {
                header('Location: ' . $root.'assets/components/yandexmoney/connector_result.php?fail=1');
                exit();
            }
        }

        $html = '';

        $site_url = $modx->config['site_url'];
        $payType = ($this->paymode) ? '' : $this->pay_method;
        $addInfo = ($this->email!==false)?'<input type="hidden" name="cps_email" value="'.$this->email.'" >':'';
        $addInfo .= ($this->phone!==false)?'<input type="hidden" name="cps_phone" value="'.$this->phone.'" >':'';
        $html .= '<form method="POST" action="'.$this->getFormUrl().'"  id="paymentform" name = "paymentform">';
        if ($this->mode == self::MODE_KASSA) {
            /** @var \YandexCheckout\Model\Confirmation\ConfirmationRedirect $confirmation */
            $confirmation = $payment->getConfirmation();
            if ($confirmation !== null && $confirmation->getType() === \YandexCheckout\Model\ConfirmationType::REDIRECT) {
                $redirectUrl = $confirmation->getConfirmationUrl();
            }
            $html = '<script> document.location = "' . $redirectUrl . '"; </script>';
        } elseif ($this->mode == self::MODE_MONEY) {
            $html .= '  <input type="hidden" name="receiver" value="'.$this->account.'">
                       <input type="hidden" name="formcomment" value="Order '.$this->orderId.'">
                       <input type="hidden" name="short-dest" value="Order '.$this->orderId.'">
                       <input type="hidden" name="writable-targets" value="'.$this->writable_targets.'">
                       <input type="hidden" name="comment-needed" value="'.$this->comment_needed.'">
                       <input type="hidden" name="label" value="'.$this->orderId.'">
                       <input type="hidden" name="quickpay-form" value="'.$this->quickpay_form.'">
                       <input type="hidden" name="paymentType" value="'.$this->pay_method.'">
                       <input type="hidden" name="targets" value="Заказ '.$this->orderId.'">
                       <input type="hidden" name="sum" value="'.$this->orderTotal.'" data-type="number" >
                       <input type="hidden" name="comment" value="'.$this->comment.'" >
                       <input type="hidden" name="need-fio" value="'.$this->need_fio.'">
                       <input type="hidden" name="need-email" value="'.$this->need_email.'" >
                       <input type="hidden" name="need-phone" value="'.$this->need_phone.'">
                       <input type="hidden" name="need-address" value="'.$this->need_address.'">
                        <input type="hidden" name="successUrl" value="'.$site_url.'assets/components/yandexmoney/connector_result.php?success=1">';
        } elseif ($this->mode == self::MODE_BILLING) {
            $narrative = $this->parsePlaceholders($this->ya_billing_purpose, $order);
            $html .= '<input type="hidden" name="formId" value="'.$this->ya_billing_id.'" />
                <input type="hidden" name="narrative" value="'.htmlspecialchars($narrative).'" />
                <input type="hidden" name="fio" value="'.htmlspecialchars($this->ya_billing_fio).'" />
                <input type="hidden" name="sum" value="'.$this->orderTotal.'" />
                <input type="hidden" name="quickPayVersion" value="2" />';
            $this->updateOrderStatus($order, $this->config['ya_billing_status']);
        }
        if ($this->mode !== self::MODE_KASSA) {
            $html .= '<input type="hidden" name="cms_name" value="modx" >
                </form>
                <script type="text/javascript">
                    document.getElementById("paymentform").submit();
                </script>';
        }

        echo $html;
        exit;
    }

    /**
     * @param shk_order $order
     * @param string $redirectUrl
     * @return \YandexCheckout\Model\PaymentInterface
     */
    private function createKassaPayment($order, $redirectUrl)
    {
        try {
            $builder = \YandexCheckout\Request\Payments\CreatePaymentRequest::builder();
            $builder->setClientIp($_SERVER['REMOTE_ADDR'])
                ->setAmount($this->orderTotal)
                ->setCapture(true)
                ->setDescription($this->createDescription($order))
                ->setMetadata(array(
                    'order_id' => $this->orderId,
                    'cms_name' => 'ya_api_modx_revolution',
                    'module_version' => '1.0.4',
                ));
            $confirmation = array(
                'type' => \YandexCheckout\Model\ConfirmationType::REDIRECT,
                'returnUrl' => $redirectUrl,
            );
            if (!$this->paymode) {
                if ($this->pay_method === \YandexCheckout\Model\PaymentMethodType::ALFABANK) {
                    $paymentMethod = array(
                        'type' => $this->pay_method,
                        'login' => $this->alfaLogin,
                    );
                    $confirmation = \YandexCheckout\Model\ConfirmationType::EXTERNAL;
                } elseif ($this->pay_method === \YandexCheckout\Model\PaymentMethodType::QIWI) {
                    $paymentMethod = array(
                        'type' => $this->pay_method,
                        'phone' => $this->qiwiPhone,
                    );
                } else {
                    $paymentMethod = $this->pay_method;
                }
                $builder->setPaymentMethodData($paymentMethod);
            }
            $builder->setConfirmation($confirmation);
            if (isset($this->config['ya_kassa_send_check']) && $this->config['ya_kassa_send_check']) {
                $this->addReceipt($builder, $order);
            }
            $request = $builder->build();
            if (isset($this->config['ya_kassa_send_check']) && $this->config['ya_kassa_send_check']) {
                $request->getReceipt()->normalize($request->getAmount());
            }
        } catch (\Exception $e) {
            $this->log('error', 'Failed to create request: ' . $e->getMessage());
            return null;
        }

        try {
            $response = $this->getClient()->createPayment($request);
        } catch (\Exception $e) {
            $this->log('error', 'Failed to create payment: ' . $e->getMessage());
            return null;
        }

        global $modx;

        /** @var YandexMoneyKassaPayment $record */
        $record = $modx->getObject('YandexMoneyKassaPayment', $this->orderId);
        $this->log('debug', 'Fetching payment from db: ' . ($record === null ? 'null' : $record->get('payment_id')));
        if ($record === null) {
            $this->log('debug', 'Create db payment');
            $record = $modx->newObject('YandexMoneyKassaPayment');
            $record->set('order_id', $this->orderId);
        }
        $record->set('payment_id', $response->getId());
        $record->save();

        return $response;
    }

    /**
     * @param string $paymentId
     * @return \YandexCheckout\Model\PaymentInterface|null
     */
    public function getPaymentById($paymentId)
    {
        try {
            $payment = $this->getClient()->getPaymentInfo($paymentId);
        } catch (Exception $e) {
            $this->log('error', 'Failed to find payment ' . $paymentId);
            $payment = null;
        }
        return $payment;
    }

    /**
     * @param \YandexCheckout\Model\PaymentInterface $payment
     * @param bool $fetch
     * @return \YandexCheckout\Model\PaymentInterface|null
     */
    public function capturePayment($payment, $fetch = true)
    {
        if ($fetch) {
            $payment = $this->getPaymentById($payment->getId());
            if ($payment === null) {
                return null;
            }
        }
        if ($payment->getStatus() === \YandexCheckout\Model\PaymentStatus::WAITING_FOR_CAPTURE) {
            try {
                $builder = \YandexCheckout\Request\Payments\Payment\CreateCaptureRequest::builder();
                $builder->setAmount($payment->getAmount());
                $request = $builder->build();
            } catch (Exception $e) {
                return null;
            }
            try {
                $response = $this->getClient()->capturePayment($request, $payment->getId());
            } catch (\Exception $e) {
                return null;
            }
        } else {
            $response = $payment;
        }
        return $response;
    }

    /**
     * @param \YandexCheckout\Request\Payments\CreatePaymentRequestBuilder $builder
     * @param shk_order $order
     */
    private function addReceipt($builder, $order)
    {
        $builder->setReceiptEmail($order->_fields['email']);

        $shippingMethod = null;
        $shippingPrice = 0;
        if ($content = unserialize($order->_fields['content'])) {
            foreach ($content as $item) {
                if ($item['price'] > 0) {
                    $builder->addReceiptItem($item['name'], $item['price'], $item['count'], $this->config['tax_id']);
                } elseif (isset($item['tv_add']['shk_delivery'])) {
                    $shippingMethod = $item['tv_add']['shk_delivery'];
                }
            }
        }

        if (!empty($shippingMethod)) {
            foreach (unserialize($order->_fields['addit']) as $items) {
                foreach ($items as $item) {
                    if (isset($item[0]) && $item[0] === $shippingMethod) {
                        $shippingPrice = $item[1];
                    }
                }
            }
        }

        if ($shippingMethod && $shippingPrice > 0) {
            $builder->addReceiptShipping($shippingMethod, $shippingPrice, $this->config['tax_id']);
        }
    }

    public function checkSign($callbackParams)
    {
        if ($this->org_mode) {
            $string = $callbackParams['action'].';'.$callbackParams['orderSumAmount'].';'.$callbackParams['orderSumCurrencyPaycash'].';'.$callbackParams['orderSumBankPaycash'].';'.$callbackParams['shopId'].';'.$callbackParams['invoiceId'].';'.$callbackParams['customerNumber'].';'.$this->password;
            $md5 = strtoupper(md5($string));
            return ($callbackParams['md5']==$md5);
        } else {
            $string = $callbackParams['notification_type'].'&'.$callbackParams['operation_id'].'&'.$callbackParams['amount'].'&'.$callbackParams['currency'].'&'.$callbackParams['datetime'].'&'.$callbackParams['sender'].'&'.$callbackParams['codepro'].'&'.$this->password.'&'.$callbackParams['label'];
            $check = (sha1($string) == $callbackParams['sha1_hash']);
            if (!$check){
                header('HTTP/1.0 401 Unauthorized');
                return false;
            }
            return true;
        }
    }

    public function sendCode($callbackParams, $code)
    {
        if (!$this->org_mode) {
            if ($code === 0) {
                header('HTTP/1.0 200 OK');
            } else {
                header('HTTP/1.0 401 Unauthorized');
            }
            return;
        }
        header("Content-type: text/xml; charset=utf-8");
        $xml = '<?xml version="1.0" encoding="UTF-8"?>
            <'.$callbackParams['action'].'Response performedDatetime="'.date("c").'" code="'.$code.'" invoiceId="'.$callbackParams['invoiceId'].'" shopId="'.$this->shopid.'"/>';
        echo $xml;
    }

    /* оплачивает заказ */
    public function ProcessResult()
    {
        $callbackParams = $_POST;
        if ($this->checkSign($callbackParams)) {
            $order_id = ($this->org_mode)? intval($callbackParams["orderNumber"]):intval($callbackParams["label"]);
            if ($order_id) {
                $this->modx->addPackage('shopkeeper3', MODX_CORE_PATH."components/shopkeeper3/model/");
                $order = $this->modx->getObject('shk_order',array('id'=>$order_id));
                $amount = number_format($order->get('price'),2,".",'');
                $pay_amount = number_format($callbackParams[($this->org_mode)?'orderSumAmount':'amount'], 2, '.', '');
                if ($pay_amount === $amount) {
                    if ($callbackParams['action'] == 'paymentAviso' || !$this->org_mode){
                        $order->set('status', 5);
                        $order->save();
                    }
                    $this->sendCode($callbackParams, 0);
                } else {
                    $this->sendCode($callbackParams, 100);
                }
            } else {
                $this->sendCode($callbackParams, 200);
            }
        } else {
            $this->sendCode($callbackParams, 1);
        }
    }

    /**
     * @return int
     */
    public function getMode()
    {
        return $this->mode;
    }

    /**
     * Преобразует шаблон назначения платежа в удобоваримую строку
     * @param string $template Шаблон назначения платежя
     * @param shk_order $order Информация о заказе
     * @return string Строка для отправки в Яндекс.Деньги
     */
    private function parsePlaceholders($template, shk_order $order)
    {
        $replace = array(
            '%order_id%' => $order->id,
        );
        foreach ($order->toArray() as $key => $value) {
            if (is_scalar($value)) {
                $replace['%' . $key . '%'] = $value;
            }
        }
        return strtr($template, $replace);
    }

    /**
     * Устанавливает новый статус исполнения заказа
     * @param shk_order $order Инстанс изменяемого заказа
     * @param string $status Новый статус заказа
     */
    public function updateOrderStatus(shk_order $order, $status)
    {

        if ($status > 0) {
            $order->set('status', $status);
            return $order->save();
        }
    }

    private function getClient()
    {
        if ($this->_apiClient === null) {
            $this->_apiClient = new \YandexCheckout\Client();
            $this->_apiClient->setAuth($this->shopid, $this->password);
            $this->_apiClient->setLogger($this);
        }
        return $this->_apiClient;
    }

    public function log($level, $message, $context = array())
    {
        if (!$this->debug_log) {
            return;
        }
        if (!empty($context) && (is_array($context) || $context instanceof Traversable)) {
            $search = array();
            $replace = array();
            foreach ($context as $key => $value) {
                $search[] = '{' . $key . '}';
                $replace[] = $value;
            }
            $message = str_replace($search, $replace, $message);
        }
        $path = YANDEXMONEY_PATH . '/logs';
        if (!file_exists($path)) {
            mkdir($path);
        }
        $fileName = $path . '/module.log';
        $fd = fopen($fileName, 'a');
        flock($fd, LOCK_EX);
        fwrite($fd, date(DATE_ATOM) . ' [' . $level . '] - ' . $message . PHP_EOL);
        flock($fd, LOCK_UN);
        fclose($fd);
    }

    /**
     * @param $order
     * @return string
     */
    private function createDescription($order)
    {
        $descriptionTemplate = !empty($this->config['description_template'])
            ? $this->config['description_template']
            : 'Оплата заказа №%id%';

        $replace  = array();
        $patterns = explode('%', $descriptionTemplate);
        foreach ($patterns as $pattern) {
            $value = $order->get($pattern);
            if (!is_null($value) && is_scalar($value)) {
                $replace['%'.$pattern.'%'] = $value;
            }
        }

        $description = strtr($descriptionTemplate, $replace);

        return (string)mb_substr($description, 0, Payment::MAX_LENGTH_DESCRIPTION);
    }
}
Roman
09 октября 2019, 12:59
0
А как перемещать фильтр по цвету, допустим я хочу поднять его на 1 позицию выше предыдущего фильтра? Сейчас не прокатывает менять местами значения параметра filters в сниппете mFilter2:
&filters=`ms$price:number,ms$series:series,ms$tip:tip,msoc$formacherepici~value~pattern,msoc$color~value~pattern`
Roman
30 сентября 2019, 15:21
0
Прочитите документацию — autocomplete нужно отключить
Roman
30 сентября 2019, 15:11
0
ошибка в строке
&aliases=`ms$price==price,formacherepici|value==formacherepici`
нужно так
&aliases=`ms$price==price,formacherepici$value==formacherepici`
Roman
30 сентября 2019, 15:00
0
Пробовал так:
[[!mFilter2?

&filter_delimeter=`$` 
&limit=`24` 
&where =`ms$price:asc` 
&parents=`808,836,837,838,839,840,842,844,845,847,848,849,974,1589,1895,5522,5941,5945`
&element=`msProducts`
    &leftJoin=`{
        "Forma": {
            "class": "msProductOption",
            "on": "Forma.key = 'formacherepici' and Forma.product_id = msProduct.id"
        }
    }`
&sortAliases=`{"formacherepici":"Forma"}`
&aliases=`ms$price==price,formacherepici|value==formacherepici`
&filters=`ms$price:number,parent:categories,msoption$formacherepici:option,ms$tip:tip,msoption$tipbituma:option` 
&tpls=`tpl.msProducts.row,tpl.msProducts.row2` 
&class=`msProduct` 
&sort=`formacherepici:desc`
 
&tplOuter=`tpl.mFilter2.outer.2` 
&tplFilter.outer.price=`tpl.mFilter2.filter.slider` 
&tplFilter.row.price=`tpl.mFilter2.filter.number` 
&tplFilter.row.resource$parent=`tpl.mFilter2.filter.checkboxshinglas`
&tplFilter.outer.msoption$formacherepici=`tpl.mFilter2.filter.checkboxshinglasforma`
&suggestionsRadion=`ms$tip`
&suggestionsRadion=`ms$formacherepici`]]
не работает.
Roman
05 июля 2019, 12:28
0
Совсем забыл сказать, тоже проводил данные манипуляции с файликом
core/components/yandexmoney/model/yandexmoney.class.php
а так же менял параметр в функции addPackage, там где стоял shopkeeper просто добавлял цифру 3
addPackage('shopkeeper3' ...... );
и пути прописывал
components/shopkeeper3/model/
Roman
03 июля 2019, 10:50
0
Опытным путем выяснил что нужно только через Formit, через AjaxForm ни в какую не хотел работать. Так же если у Вас Shopkeeper3 а ЯндексКасса самая старая — yandexmoney-1.1.0-pl то возникнут проблемы, для их устранения нужно поменять в YandexMoneyHook следующие строки:
$modx->addPackage('shopkeeper',  $modx->getOption('core_path').'components/shopkeeper/model/');

    $order = $modx->getObject('SHKorder', $order_id);
на
$modx->addPackage('shopkeeper3',  $modx->getOption('core_path').'components/shopkeeper3/model/');
  $order = $modx->getObject('shk_order', $order_id);
а так же нужно поменять строки в обработчике connector_result.php
Roman
27 июня 2019, 18:00
0
[[+price:replace=` ||`]]
— не работает так.
Нужно так:
[[+pagetitle:replace=`шип==паз`]]
Roman
27 июня 2019, 17:53
0
Получилось!
[[+old_price:esc:replace=` ==`:replace=`.==`:replace=`,==`:decr=`[[+price:esc:replace=` ==`:replace=`.==`:replace=`,==`]]`]]
Оказывается нужно заменять пробелы точки и запятые!
P.S Выглядит как костыль XD
Roman
26 июня 2019, 15:33
0
Спасибо, уже разорбрался =) Только это для Formit.
Roman
25 июня 2019, 12:38
0
версия PHP для fastField какая нужна и какая стоит?
Roman
22 июня 2019, 17:36
0
Здравствуйте! Решили вопрос? У меня подобная проблема.
Roman
19 июня 2019, 00:25
0
Я решил так — перенёс содержимое ресурса в чанк, после чего все сохранилось. У вас случайно не сохраняется ресурс со множеством дочерних ресурсов?
Roman
21 марта 2019, 11:15
0
Да я это уже и сделал, поменял рипозиторий на SimpleDream и обновился, а на modx.com последняя версия 1.6.16-pl.
Roman
21 марта 2019, 10:43
0
У меня версия 1.6.16-pl
Roman
14 января 2019, 12:02
0
это я понял, тут дело в том что есть два сайта на MODX Revolution 2.6.5-pl, у обоих нет этих файлов, у одного есть ошибки, а у другого — нет…
Roman
08 декабря 2018, 13:30
0
Здравствуйте! Вы решили эту проблему?
Roman
07 декабря 2018, 13:58
0
Чтобы обновить url (alias) товаров Minishop'а немного модернизировал Ваш код=)
$pages = $modx->getIterator('msProduct', array('class_key' => 'msProduct'));

foreach ($pages as $p) {
  $title = $p->get('pagetitle');
  $alias = $p->get('alias');	
  $alias = $p->cleanAlias($title);
  $p->set('alias', $alias);
  $p->save();
}
Roman
13 ноября 2018, 17:49
0
Не знаю, как это расценивать, баг или недочет. Вообщем ситуация следущая. Есть товар, у этого товара цена зависит от цвета и от типа покрытия.
У этого товара нет в некоторых цветах других покрытий и выводится цена карточки товара.
Пример:
krovlya-yuga.ru/products/keram_cherepica/czelnaya-cherepicza-creaton-seriya-ratio-hongeda/
черный цвет, покрытие глазурь — такой товар есть, а вот цвет черный, покрытие — натуральное — такого товара нет и выводится цена карточки товара. Кто сталкивался с таким?