Замечательно) с Unitpay не работал пока что, посмотрим что они смогут предложить, основной вопрос, а работают ли они с физическими лицами?

Сегодня вышла новая сборка магазина ShopModxBox-2.2.3. Изменений в ней не много, и в основном коснулись процессора basket/processors/web/payments/create, который был почти полностью переработан (тем не менее это не скажется на работе старых магазинов). Переработка этого процессора понадобилась для универсальности, ведь теперь добавился третий модуль оплаты - ShopModxUnitPay - для оплаты через агрегатор unitpay.ru. Кстати, если кто-то сталкивался с этой системой, просьба поведать о своем опыте и о плюсах/минусах данного агрегатора. Я в свою очередь могу сказать следующее: на сайте у них указано, что их комиссия не более 1%. В целом это почти так. Почти, потому что на самом деле можно там найти и скрытые проценты. А во-вторых, это их комиссия, но с платежей, которые будут поступать к вам, будет взиматься комиссия и конечных платежных систем. К примеру, вам оплатили 100 рублей через Яндекс.Деньги. На счет вам в их систему упадет только 93 рубля. Из них 5% - это Яндекс заберет (не с конечного пользователя, а именно с этого платежа. Пользователь заплатит как положено 100 рублей). Далее 1% - это их заявленный процент. А еще 1% - это конвертация средств на вебмани внутри системы (это я и назвал скрытым процентом). Тем не менее не все так плохо. Во-первых, примерно такой процент так или иначе будет взиматься на любом другом платежном агрегаторе. Здесь, наверно, самая экономия - это напрямую платеж в Яндекс.Деньги. Там их комиссия до 3%. А если расплачиваться их картой, то вообще ни процента не теряешь. Кстати, модуль данный давно уже почти готов, все никак не доделаю. Если у кого есть интерес, поддержите рублем проект и модуль этот появится в самое ближайшее время. Второй момент: данный процент был озвучен для физлиц. А для юриков процент существенно ниже. К примеру, при оплате теми же Яндекс.Деньгами на юрика конечный процент будет всего 4%, что очень близко к самому минимальному на рынке. А третий момент (который мне больше всех нравится), это то, что можно комиссию полностью переложить на конечных пользователей (а можно и наоборот облегчить их учесть :)). В настройках своего аккаунта в UnitPay можно ползуночками изменить процент комиссии при платеже, и можно таким образом вообще все проценты с платежа переложить на клиента. Вообще полностью, включая процент платежной системы. ? В таком случае пользователь будет оплачивать сумму заказа + установленную комиссию. ? Это особенно хорошо, когда средний чек небольшой, и клиенту лишние 7-10% погоды не сделают. Процент отказов по платежам будет незначительный, а 5% от общего месячного оборота для магазина может оказаться очень существенным. Вы спросите а почему не устанавливать сразу цену на сайте с учетом комиссии? Во-первых, у разных платежных систем разная комиссия, и отслеживать это на стороне сайта гораздо сложнее. Во-вторых, стоимость товара тогда возрастает, и в том же яндекс.маркете вы уже будете выглядеть менее привлекательно, и кто-то с разницей в цене на пару процентов будет в выдаче выше вас. А если вы заявите цену одну, а при оформлении заказа или к оплате укажете другую цену, то яндекс.маркет вас очень быстро и с удовольствием заблокирует. А вот если комиссия появится уже на стороне платежного агрегатора, тут велика вероятность легко откусаться, потому как типа платежный сервис же комиссию берет, а не вы. Но и как разработчик скажу, что хоть и нашел пару ошибок у них в доках да скриптах, в целом интерфейс очень дружественный. Особенно порадовала форма отладки запросов. ? В общем, я бы дал 4+ из пяти. UPD: А, и еще забыл, таки подправил шаблоны товаров, и теперь на странице товаров выводится описание (content). При этом оцените наконец силу Smarty! :) Вот базовый шаблон для товаров. Это только основная карточка с кнопкой заказа. А вот это шаблон для вывода карточек товаров в списке каталога. Все, что там есть: {extends file="shop/products/layout.tpl"} То есть этот шаблон расширяет основной шаблон и ничего больше в себе не несет. А вот это шаблон для конечной страницы товара, где выводится и поле content. Весь его код: {*

Шаблон для вывода товара на собственной странице

*}

{extends file="shop/products/layout.tpl"}

{block name=cart}

    {$smarty.block.parent}

    {block name=product_content}

        

            {$object.content}

        

    {/block}

{/block} То есть он так же расширяет основной шаблон и добавляет блок с выводом контента. А весь родительский шаблон вызывается одной строчкой: {$smarty.block.parent}, то есть инклюдится родительский блок. И стоит только подправить основной шаблон карточки, и изменения будут сразу в обоих дочерних шаблонах, не надо править одно и то же в нескольких местах. И вот уже не сравнивайте, пожалуйста, с чанками. Вы не сделаете расширение одного чанка другим, и не будут видны передаваемые в один чанк параметры внутри другого чанка.

  1. Главное в "коробке" - это продуманная расширяемая система. Ввести несколько цен - дело пары часов. А внести мегауниверсальный механизм нескольких цен - это уже задача гораздо сложнее, так как на разных магазинах часто выставляют разные требования к этому, и на конечном магазине выполнить индивидуальную доработку гораздо проще, чем сделать универсальный механизм, который устроит всех. А мой принцип - лучше сделать "с нуля" малое, чем перелопачивать под себя многое.
  2. Вы можете предложить свою реализацию в виде пуллреквеста, или хотя бы поддержать рублем проект. А так, дареному коню в зубы не смотрят.

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

Ясно, спасибо! Буду стараться...

Здравствуйте. С моделями товаров лучше не заморачиваться, это слишком сложно. Вот подробный топик про дополнительные параметры товаров, там все довольно полно описано. Но ваша задача чуть сложнее (несколько цен), поэтому просто используйте TV migx. Документация: http://rtfm.modx.com/extras/revo/migx/migx.backend-usage. У вас будет две колонки: параметр и цена. Далее развивайте.

Всем добрый день! Подскажите пожалуйста, как реализовать товар с несколькими ценами, которые будут менять в зависимости от свойств товара. Например есть корм: цена будет менять в зависимость от веса. То есть упаковка 200г и 400г. Смотрел вебинар, там было сказано про модель товара, но подробно нигде такой вариант не рассматривался, или я это пропустил. Может быть кто-нибудь подтолкнет в нужном направлении?

Материал для экспертов. В одном из топиков я уже писал довольно подробно про политики безопасности в MODX. Тогда мы разобрались, что основной метод проверки — modAccessibleObject::checkPolicy(). В этот раз мы попробуем более внимательно изучить этот механизм, и рассмотрим очень важную недоработку MODX в этом плане. Во-первых, сразу хочу отметить, что метод checkPolicy не содержится в исходных классах xPDO типа xPDOObject или xPDOSimpleObject. Этот метод появляется только в MODX-классе modAccessibleObject, который входит в сам пакет modx (да, не забываем, что MODX — это надстройка над xPDO и подключается как дополнительный пакет). То есть, если вы хотите использовать чистый xPDO, то имейте ввиду, что механизм политик безопасности там попросту отсутствует. А во-вторых, рассмотрим важную недоработку: отсутствие возможности выполнить проверку доступов к объекту сразу для нескольких пользователей. Простой пример: вот у нас здесь на сайте есть закрытые блоги, к которым имеют доступы только определенные группы пользователей. Встала задача — при публикации нового топика в блог, разослать уведомления всем пользователям, которые имеют доступ к блогу, в который публикуется топик. И вот вопрос: как это сделать? По логике, нам надо получить всех пользователей, перебрать их в цикле и каждого из них проверить на предмет доступа к объекту блога. Это по логике. А на практике? А на практике метод modAccessibleObject::checkPolicy() принимает только два параметра — $criteria и $targets. А внутри метода прописана работа с текущим пользователем MODX $this->xpdo->user. Таким образом проверять права мы можем только для текущего пользователя :) Хотя можно было бы конечно попробовать что-то вроде такого изврата: <?php $modx->switchContext('web'); $blog_id = 1; // ID нужного блога $currentUser = $modx->user; $blog = $modx->getObject('SocietyBlog', $blog_id); foreach($modx->getCollection('modUser' ) as $user){ $modx->user = $user; print "\n<br />HasAccess: ". (int)$blog->checkPolicy('view'); } $modx->user = $currentUser; То есть загоняем текущего MODX-пользователя в переменную, затем в цикле перегружаем текущего пользователя и проверяем доступ к объекту, после чего уже возвращаем текущего пользователя в объект $modx. Но это конечно же не по фэншую. Хотя просто так альтернативы нет… В нашем же случае с топиками и блогами есть вариант — это немного переписать метод checkPolicy() в наших пользовательских классах, добавив третий параметр — $user. К слову, пуллреквест в MODX я уже отправил (смотрите изменения в коде). В результате все получается так, как и должно быть: <?php $modx->switchContext('web'); $blog_id = 1; // ID нужного блога $blog = $modx->getObject('SocietyBlog', $blog_id); foreach($modx->getCollection('modUser' ) as $user){ print "\n<br />HasAccess: ". (int)$blog->checkPolicy('view', null, $user); } Без всякой перегрузки текущего MODX-пользователя. Будем надеяться, что пуллреквест будет приниматься не особо долго. По поводу производительности: на холодную перебор 500 пользователей на предмет доступа к объекту на моем сервере занимает примерно 4-5 секунд. Далее уже значительно быстрее, в районе 0.2-0.3 сек. Здесь играет роль внутренний механизм кеширования доступов для каждого пользователя в отдельности, заложенный в MODX-е, но изучать детально я его буду чуть позже. Тогда и статью по этому поводу напишу отдельно. Опыт подсказывает, что там скрываются очень полезные механизмы, которые можно будет использовать для существенного снижения нагрузки на сайтах с распределенными правами доступов. И напоследок, приведу код метода SocietyTopic::checkPolicy(). Дело в том, что там метод checkPolicy еще чуть более измененный. Во-первых, права проверяются не только на сам топик, но и на доступы к блогам, в которых топик размещен (Да, топик может быть индивидуально ограничен в доступах. И да, топик может располагаться сразу в нескольких блогах. Тогда наличие доступа хотя бы к одному из блогов топика будет свидетельствовать о наличии прав на топик). <?php public function checkPolicy($criteria, $targets = null, modUser $user = null) { if(!$user){ $user = & $this->xpdo->user; } // Проверяем права на блог (хотя бы один) $hasBlogAccess = false; foreach((array)$this->TopicBlogs as $topicblog){ // print_r($topicblog->Blog->toArray()); if( $blog = $topicblog->Blog AND $blog->checkPolicy($criteria, $targets, $user) ){ $hasBlogAccess = true; break; } } if(!$hasBlogAccess){ return false; } if ($criteria && $this->xpdo instanceof modX && $this->xpdo->getSessionState() == modX::SESSION_STATE_INITIALIZED) { if ($user->get('sudo')) return true; if (!is_array($criteria) && is_scalar($criteria)) { $criteria = array("{$criteria}" => true); } $policy = $this->findPolicy(); if (!empty($policy)) { // print "sdfdfd"; $principal = $user->getAttributes($targets); if (!empty($principal)) { foreach ($policy as $policyAccess => $access) { foreach ($access as $targetId => $targetPolicy) { foreach ($targetPolicy as $policyIndex => $applicablePolicy) { if ($this->xpdo->getDebug() === true) $this->xpdo->log(xPDO::LOG_LEVEL_DEBUG, 'target pk='. $this->getPrimaryKey() .'; evaluating policy: ' . print_r($applicablePolicy, 1) . ' against principal for user id=' . $user->id .': ' . print_r($principal[$policyAccess], 1)); $principalPolicyData = array(); $principalAuthority = 9999; if (isset($principal[$policyAccess][$targetId]) && is_array($principal[$policyAccess][$targetId])) { foreach ($principal[$policyAccess][$targetId] as $acl) { $principalAuthority = intval($acl['authority']); $principalPolicyData = $acl['policy']; $principalId = $acl['principal']; if ($applicablePolicy['principal'] == $principalId) { if ($principalAuthority <= $applicablePolicy['authority']) { if (!$applicablePolicy['policy']) { return true; } if (empty($principalPolicyData)) $principalPolicyData = array(); $matches = array_intersect_assoc($principalPolicyData, $applicablePolicy['policy']); if ($matches) { if ($this->xpdo->getDebug() === true) $this->xpdo->log(modX::LOG_LEVEL_DEBUG, 'Evaluating policy matches: ' . print_r($matches, 1)); $matched = array_diff_assoc($criteria, $matches); if (empty($matched)) { return true; } } } } } } } } } } return false; } } return true; } UPD: В итоге я отправил пулл-реквест, который все-таки приняли, и теперь можно проверять права для любых пользователей.