ms3PromoCode

Встречайте новый компонент экосистемы — ms3PromoCode. Промо-коды (скидочные купоны) для магазинов на MiniShop3: гибкие правила применения, ручная и пакетная генерация по маске, Vue-админка с аналитикой, готовая форма для покупателя.



Зачем он нужен



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

Для покупателя



В шаблон корзины добавляется один сниппет:

{'!ms3PromoCodeForm' | snippet}
Это классическая форма, которая рендерит себя еще на сервере без «мигания» при загрузке страницы. В наличии поле для ввода и Кнопки «Применить» и «Снять». После любого изменения корзины скидка автоматически пересчитывается, код тихо снимается, если новые позиции под его правила больше не подходят — с записью в msOrderLog.



Для менеджера магазина



В админке появляется раздел «Промо-коды» с двумя разделами:

  • Управление кодами — таблица со всеми фильтрами и сортировками, редактор кода с тремя вкладками (Основное / Правила / Стастистика), массовые действия.
  • Аналитика — KPI (количество применений, суммарная скидка) и детальный лог использования с фильтром по датам, заказам и клиентам.




Плюс — отдельная вкладка «Промо-код» прямо в карточке заказа. Можно применить или снять код на уже созданном заказе в пару кликов, стоимость пересчитается на лету. В определённых статусах (настраивается) вкладка блокируется от редактирования — защита от случайных правок по отгруженным заказам.



Правила применения — гибкий таргетинг



Скидка может действовать на всю корзину или только на подходящие позиции. Правила — шесть секций в редакторе:

  • Разрешённые товары и исключения.
  • Категории и исключения категорий.
  • Бренды.
  • Универсальный фильтр по любому полю таблицы modx_ms3_products — с операторами =, !=, <, >, IN, BETWEEN, LIKE, CONTAINS.
  • Фильтр по опции товара (варианты, цвета, размеры).
Секции комбинируются по AND, значения внутри одной секции — по OR. Этого хватает, чтобы собрать правила уровня «скидка 15% на всё, кроме распродажных, у брендов A, B, C, при цене от 5000 руб».

Жизненный цикл кода тоже под контролем: период действия с датами старта и окончания, общий лимит применений, минимальная сумма заказа, выключатель. Компонент сам считает статус — scheduled, expired, exhausted, disabled. Отключённый код сообщает покупателю «не найден», чтобы не палить факт существования временно выключенной акции.



Пакетная генерация по маске



Для раздачи уникальных кодов (например, каждому подписчику рассылки — свой) — генератор по маске. Символы # (цифра), ? (буква), * (и то и другое), плюс литералы для префиксов-суффиксов. Например, маска SUMMER-**** выдаёт коды вида SUMMER-K3B9. Набор символов по умолчанию — без визуально неоднозначных (нет 0/O, 1/I/L), чтобы клиенты не гадали, что им прислали. Защита от коллизий, живое превью в админке.





Для разработчика



На фронте — headless JS-ядро window.ms3PromoCode. Можно писать свой UI поверх, если стандартная форма не подходит:

await window.ms3PromoCode.init();
const result = await window.ms3PromoCode.apply('SALE10');

if (result.success) {
    console.log('Скидка:', result.data.discount);
}

window.ms3PromoCode.on('applied', (data) => { /* ... */ });
window.ms3PromoCode.on('auto-removed', (data) => { /* ... */ });
Всё что нужно для интеграции с React, Vue, Alpine или просто своим ванильным JS — init, apply, remove, validate, getCurrent, refresh, подписка на события applied / auto-removed.

Web API на случай полностью своего фронта:

  • POST /api/v1/promo/apply — применить код к корзине.
  • POST /api/v1/promo/remove — снять применённый код.
  • POST /api/v1/promo/validate — проверить без записи (можно с пустой корзиной).
  • GET /api/v1/promo/current — текущий применённый код.
Авторизация, CORS, rate limiting — наследуются от роутера MiniShop3. Маршруты монтируются через новый механизм ms3.routes.d/ (про который писал в посте про релизы MS3), никаких отдельных точек входа.

Отдельно — override-директория. Любой файл, положенный в assets/components/ms3promocode-overrides/, прозрачно подменяет аналогичный файл пакета. Можно переопределить CSS, JS, чанки — без правок самого компонента, обновления не затрут ваши изменения.

Интеграция с MiniShop3



Компонент не патчит ядро MS3 — только подписывается на официальные события:

  • msOnAddToCart / msOnChangeInCart / msOnRemoveFromCart — любое изменение корзины триггерит восстановление исходных цен, пересчёт скидки и повторное применение. Если корзина больше не удовлетворяет условиям — код автоматически снимается, событие логируется.
  • msOnCreateOrder — при сабмите заказа применение записывается в ms3_promo_code_usages с полным breakdown по позициям и счётчиком кода инкрементируется.
  • msOnChangeOrderStatus — переход в один из статусов из настройки ms3promocode.cancel_statuses (обычно — «отменён») помечает применение как cancelled и декрементирует счётчик кода. Возврат заказа из отменённого состояния — восстанавливает.
То есть если клиент отменил заказ — код возвращается в пул доступных, лимиты живут честно.

Работа в новой Vue-админке MS3



В MiniShop3 1.10 карточка заказа окончательно переехала на Vue (писал о этом в посте про релизы MS3). ms3PromoCode корректно работает и там: ручное добавление, изменение или удаление позиции в Vue-админке автоматически перераспределяет скидку. Нативных событий для таких действий в MS3 пока нет (вопрос висит в issue #207), поэтому временно используется JS-интерсептор, который после каждого запроса на изменение позиции дёргает processor Mgr/Order/Resync. Как только в MS3 появятся штатные события — перейду на них, текущая реализация рассчитана на этот переход.

Установка и совместимость



  • MODX Revolution 3.0+
  • MiniShop3 1.10+
  • PHP 8.2+
  • pdoTools (для Fenom-чанков фронтенд-формы)
  • VueTools (для админ-панели)
Ставится как обычный пакет через «Управление пакетами» MODX. Phinx-миграции (две таблицы — ms3_promo_codes и ms3_promo_code_usages) применяются автоматически. При деинсталляции таблицы остаются на месте — чтобы история применений не терялась, если компонент переустанавливают. Удалить руками, если уверены, что данные не нужны.

Что дальше



Релиз — 1.0.0-beta1, статус открытой беты. В планах: интеграция с накопительными скидками клиентов, поддержка стеков кодов (можно ли применять два сразу — и если да, как), UI-виджет выбора кода из списка собственных сохранённых. Обратная связь, баг-репорты и feature-requests — через issue-трекер.

Готов услышать — что ещё хочется видеть в v1.0 стабильной, какие сценарии из вашей практики не покрываются текущими правилами, и где интеграция с корзиной ведёт себя неочевидно.
Николай Савин
Вчера в 17:29
modx.pro
63
0
Поблагодарить автора Отправить деньги

Комментарии: 0

Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
0