11 октября 2019, 13:19 Хук YandexMoneyHook <?php $eventName = $modx->event->name; $_isAdmin = ($modx->user->sudo == 1); if (!defined('YANDEXMONEY_PATH')) { define('YANDEXMONEY_PATH', MODX_CORE_PATH."components/yandexmoney/"); } require_once YANDEXMONEY_PATH.'model/yandexmoney.class.php'; $snippet = $modx->getObject('modSnippet',array('name' => 'YandexMoney')); $config = $snippet->getProperties(); $ym = new Yandexmoney($modx, $config); if (!empty($_SESSION['shk_lastOrder']) && !empty($_SESSION['shk_lastOrder']['id'])) { $ym->pay_method = !empty($_SESSION['shk_lastOrder']['payment']) ? $_SESSION['shk_lastOrder']['payment'] : ''; $order_id = (int)$_SESSION['shk_lastOrder']['id']; } if (!empty($_POST['payment'])) $ym->pay_method = $_POST['payment']; if (!empty($_POST['email'])) $ym->email = $_POST['email']; if (!empty($_POST['phone'])) $ym->phone = $_POST['phone']; if (!empty($_POST['alfaLogin'])) $ym->alfaLogin = $_POST['alfaLogin']; if (!empty($_POST['qiwiPhone'])) $ym->qiwiPhone = $_POST['qiwiPhone']; if (!$ym->checkPayMethod()) { return false; } $modx->addPackage('shopkeeper3', $modx->getOption('core_path').'components/shopkeeper3/model/'); $order = $modx->getObject('shk_order', $order_id); if (!$order) { return false; } $output = ''; if ($order_id && $_POST['order']) { $ym->userId = $modx->getLoginUserID('web') ? $modx->getLoginUserID('web') : 0; $ym->orderId = $order_id; $ym->orderTotal = $_SESSION['shk_lastOrder']['price']; $ym->orderTotal = floatval(str_replace(array(',',' '), array('.',''), $ym->orderTotal)); $ym->comment = $_POST['message']; $_host = str_replace(array('http://', 'https://'), '' , $modx->config['site_url']); $host = 'https://' . $_host . 'assets/components/yandexmoney/connector_result.php'; $ym->successUrl = $host.'?success=1'; $ym->failUrl = $host.'?fail=1'; echo $ym->createFormHtml(); exit; } return true; Вопросы / Как подружить Яндекс Кассу с Shopkeeper3? 16 0
10 октября 2019, 16:49 Я делал все по гайду яндекса и у меня не заработала. Ниже привел правки в коде Вопросы / Как подружить Яндекс Кассу с Shopkeeper3? 16 0
10 октября 2019, 16:47 Конфиг: 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); } } Вопросы / Как подружить Яндекс Кассу с Shopkeeper3? 16 0
09 октября 2019, 12:59 А как перемещать фильтр по цвету, допустим я хочу поднять его на 1 позицию выше предыдущего фильтра? Сейчас не прокатывает менять местами значения параметра filters в сниппете mFilter2: &filters=`ms$price:number,ms$series:series,ms$tip:tip,msoc$formacherepici~value~pattern,msoc$color~value~pattern` Вопросы / miniShop2. Возможна ли стилизация опций товара? 9 0
30 сентября 2019, 15:21 Прочитите документацию — autocomplete нужно отключить Вопросы / Как сделать выдачу результатов mSearch2 по нажатию кнопки. 2 0
30 сентября 2019, 15:11 ошибка в строке &aliases=`ms$price==price,formacherepici|value==formacherepici`нужно так &aliases=`ms$price==price,formacherepici$value==formacherepici` Вопросы / Как сделать сортировку msoption? 3 0
30 сентября 2019, 15:00 Пробовал так: [[!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`]]не работает. Вопросы / Как сделать сортировку msoption? 3 0
05 июля 2019, 12:28 Совсем забыл сказать, тоже проводил данные манипуляции с файликом core/components/yandexmoney/model/yandexmoney.class.php а так же менял параметр в функции addPackage, там где стоял shopkeeper просто добавлял цифру 3 addPackage('shopkeeper3' ...... );и пути прописывал components/shopkeeper3/model/ Вопросы / Как подружить Яндекс Кассу с Shopkeeper3? 16 0
03 июля 2019, 10:50 Опытным путем выяснил что нужно только через 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 Вопросы / Как подружить Яндекс Кассу с Shopkeeper3? 16 0
27 июня 2019, 18:00 [[+price:replace=` ||`]] — не работает так. Нужно так: [[+pagetitle:replace=`шип==паз`]] Вопросы / Как вычесть одно значение из другого используя PHX модификаторы 7 0
27 июня 2019, 17:53 Получилось! [[+old_price:esc:replace=` ==`:replace=`.==`:replace=`,==`:decr=`[[+price:esc:replace=` ==`:replace=`.==`:replace=`,==`]]`]]Оказывается нужно заменять пробелы точки и запятые! P.S Выглядит как костыль XD Вопросы / Как вычесть одно значение из другого используя PHX модификаторы 7 0
27 июня 2019, 17:39 Пробовал — выводит 1 Вопросы / Как вычесть одно значение из другого используя PHX модификаторы 7 0
26 июня 2019, 15:33 Спасибо, уже разорбрался =) Только это для Formit. Вопросы / AjaxForm свой Hook 2 0
25 июня 2019, 12:38 версия PHP для fastField какая нужна и какая стоит? Вопросы / Испортил сайт инсталляцией fastField 10 0
22 июня 2019, 17:36 Здравствуйте! Решили вопрос? У меня подобная проблема. Вопросы / Какой компонент подходит для я.касссы? 1 0
19 июня 2019, 00:25 Я решил так — перенёс содержимое ресурса в чанк, после чего все сохранилось. У вас случайно не сохраняется ресурс со множеством дочерних ресурсов? Вопросы / зависает при сохранении ресурса. 7 0
21 марта 2019, 11:15 Да я это уже и сделал, поменял рипозиторий на SimpleDream и обновился, а на modx.com последняя версия 1.6.16-pl. Вопросы / [[РЕШЕНО]]Tickets не отправляются комментарии 4 0
21 марта 2019, 10:43 У меня версия 1.6.16-pl Вопросы / [[РЕШЕНО]]Tickets не отправляются комментарии 4 0
14 января 2019, 12:02 это я понял, тут дело в том что есть два сайта на MODX Revolution 2.6.5-pl, у обоих нет этих файлов, у одного есть ошибки, а у другого — нет… Вопросы / [РЕШЕНО]При редактировании ресурса ошибки 2 0
08 декабря 2018, 13:30 Здравствуйте! Вы решили эту проблему? Вопросы / Вывод производителя товара 6 0
MiniShop3 - Не выводятся товары дополнительных категорий @SYAN ваша указанная проблема исправлена еще до версии 1.2.3 @Павлик Мышкин завел: github.com/modx-pro/MiniShop3/issues/480 github.com/modx-pro/MiniShop3/issues/481Исправим в б...
MobileDetect 2.0.0-pl функция "планшеты как стандартные браузеры не работает" в 2.1.0-pl баг исправлен
msImportExport не сохраняет родителя по умолчанию Компонент не понимает кирилические домены при загрузку фото. пример: Error download. Url : https://антаресдвери.рф/upload/iblock/a50/a50b2ef45305a3c18f6e298f1e134880.jpg. Message...
Где можно править тексты и заголовки писем? «Управление словарями» находится в панели администратора по пути: меню Система (иконка в виде шестеренки) -> Управление словарями.
mxBoard: канбан-доска для команд, людей и ИИ-агентов в MODX 3 Токены для ИИ-агентов, чтобы они могли работать с доской. Подробнее написал тут Баг проверю и постараюсь исправить.
Плагин EnvBadge: визуальный индикатор окружения в админке MODX3 Лучше автоматический ci/cd настроить и не править прод напрямую. Это самый безопасный вариант. Другое дело, что далеко не каждый владелец сайта и далеко не каждый сайт готовы в авт...
[videoGallery] Видео галерея YouTube, Vimeo Невозможно установить пакет с подписью: videogallery-1.4.0-beta Ошибка установки Error в /core/packages/videogallery-1.4.0-beta/modCategory/7fc931a7772edc9752c16e9c41eb5e52.reso...
MODX Revolution 2.7.1-pl
shopkeeper3 3.2.7-pl3
yandexmoney 1.0.4-pl
Вывожу через Formit.
Сниппет: shk_fihook
assets/components/yandexmoney/connector_result.php
Не помню, вносил ли правки но кину сюда же
core/components/yandexmoney/model/yandexmoney.class.php
не работает.
core/components/yandexmoney/model/yandexmoney.class.php
а так же менял параметр в функции addPackage, там где стоял shopkeeper просто добавлял цифру 3
и пути прописывал
на
а так же нужно поменять строки в обработчике connector_result.php
Нужно так:
Оказывается нужно заменять пробелы точки и запятые!
P.S Выглядит как костыль XD