Промо-механики E-commerce

У оптового магазина «Альянс» каждый клиент работает по своей сетке скидок: проценты назначаются по дереву категорий и коллекций. Задача — показывать персональные цены на всех ключевых страницах магазина и не просаживать при этом скорость. Собрали серверный метод, который отдаёт «дерево скидок» клиента в JSON, и научили каталог, карточку товара и корзину применять его одним запросом на страницу.

Объём работ

  • Серверный метод: дерево скидок клиента в JSON
  • Персональные цены в каталоге, карточке и корзине
  • Один запрос на страницу вместо десятков
  • Пересчёт корзины при изменении состава
  • Обход квирков InSales в объекте корзины
  • Учёт механики выгрузки скидок в 1С

Задача

«Альянс» — оптовый интернет-магазин лакокрасочной продукции на InSales. Оптовые клиенты закупаются по индивидуальным условиям: у каждого своя сетка скидок, привязанная к дереву категорий и коллекций — от процента на всю группу «Аэрозоли» до отдельного значения на конкретную коллекцию внутри неё. Эти персональные цены должны корректно отображаться там, где клиент принимает решение о покупке: в каталоге, в карточке товара и в корзине.

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

Ограничение платформы, от которого мы отталкивались

InSales хранит у товара только полную цену и умеет применять к заказу одну общую скидку на чек — персональных скидок по отдельным позициям на уровне платформы нет. Значит, персональные цены нужно рассчитывать на своей стороне и аккуратно выводить поверх стандартного интерфейса, а не пытаться «переписать» цену в самом InSales. От этого понимания и выстраивали архитектуру.

Как сделали

Дерево скидок в JSON

На сервере собрали метод, который по клиенту отдаёт всё «дерево скидок» одним JSON — со скидками по категориям и коллекциям. Дерево кэшируется, поэтому повторные обращения не бьют по базе.

Один запрос на страницу

Вместо запроса на каждый товар страница делает ровно один запрос за деревом скидок при загрузке и применяет его ко всем позициям сразу. Так работают и каталог, и карточка товара, и корзина: нагрузка предсказуема и не растёт вместе с числом товаров на странице.

Корзина

В корзине персональные цены пересчитываются при изменении состава заказа. Попутно починили давнюю мелочь — при удалении товара страница лишний раз перезагружалась; сделали так, чтобы корзина обновлялась без перезагрузки.

Обход квирков InSales

В объекте корзины InSales коллекция у товара приходила по-разному: то числом (внутренний идентификатор), то целым объектом с описанием структуры — иногда даже в пределах одной корзины. Из-за этого расчёт скидок мог «спотыкаться». Нормализовали данные, чтобы алгоритм одинаково понимал оба формата.

Выгрузка в 1С

Отдельно разобрали, как персональные скидки доходят до 1С. InSales передаёт в учётную систему товары с их полными ценами и общую скидку на заказ, а 1С сам распределяет её по позициям; вдобавок InSales округляет суммы до целого, а 1С — нет, из-за чего расходились копейки. Согласовали правила округления на нашей стороне, чтобы итоги совпадали. Более глубокое управление скидками на уровне отдельных позиций в выгрузке — ограничение связки InSales↔1С, его вынесли в отдельный этап.

Результат

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

InSales Персональные скидки JavaScript JSON API Опт / B2B