Платформа витрин
Товарные опции и дополнительные услуги в корзине витрины
Сделал товарные опции в библиотеке витрин inSales: компонент выбора, пересчёт цены и операции корзины. Один и тот же вариант с разными дополнениями лежит в корзине отдельными позициями.
- Моя роль
- Frontend-разработчик: компонент ui-accessories, цены, API корзины, документация
- Период
- Январь – апрель 2025
- Навыки

На этой странице
Задача
Магазины хотели продавать вместе с товаром дополнения и услуги: подарочную упаковку, открытку, ленту. Одни опции обязательны, другие нет, и у каждой группы свои ограничения. Итоговую цену покупатель должен видеть ещё до того, как положит товар в корзину.
Самое сложное было в корзине. Общая библиотека витрин CommonJS считала позицию корзины вариантом товара. С опциями это перестало быть правдой: букет Classic в обычной упаковке и тот же букет в подарочной коробке с открыткой — две разные покупки с разной ценой. Любое место, которое искало товар в корзине по ID варианта, теперь могло попасть не в ту позицию: изменение количества, удаление, счётчики на карточке и проверка остатков.
Моя роль
Я делал часть на витрине, в CommonJS: компонент ui-accessories, пересчёт цены, операции корзины, вывод опций в корзине и документацию для разработчиков магазинов. Метод корзины, который принимает выбранные опции, сделали бэкенд-разработчики. Мой код проходил ревью и QA.
Что я сделал
Один компонент для обязательных и необязательных групп
ui-accessories подключается через data-accessories="{{ product.id }}" и рендерит группы опций по шаблонам из разметки, поэтому работает и в стандартных виджетах, и в собственном дизайне магазина. У каждой группы есть минимальное и максимальное количество. В демо-магазине упаковку выбирают обязательно и только одну, а дополнений можно взять до двух. Я сделал рендер опций по data-атрибутам, а не привязал его к странице товара: тот же рендер был нужен AJAX-товарам, а чтобы добавить товар с обязательными опциями из превью в категории, данные опций тоже нужны.
Цена зависит от варианта и опций
Цена пересчитывается, когда покупатель меняет вариант или набор опций. В демо-магазине подарочная коробка (+$5) и открытка (+$3) поднимают цену букета Classic с $40 до $48, а те же дополнения для размера Grand — с $60 до $68. Ноль в проверках цены нельзя было считать отсутствием значения: вариант вполне может стоить 0, а обычная упаковка добавляет $0.
Позиция корзины — это вариант вместе с опциями
Я доработал Cart.add, Cart.set, Cart.delete и очередь задач корзины, чтобы вместе с ID варианта они передавали accessory_value_ids, сгруппированные в accessoriable_variant_ids. Изменение количества и удаление теперь касаются одной конкретной комбинации, а не всех позиций с этим вариантом. В виджете корзины у каждой позиции видны названия выбранных опций и их цены.
Демо-магазин: один вариант Classic, две позиции со своими опциями, количеством и ценой.
Счётчики и остатки для разных комбинаций
Раньше на два вопроса был один ответ, теперь ответы разошлись. Счётчик на карточке и кнопка «В корзину» следуют за выбранной комбинацией. Если переключиться с обычной упаковки на подарочную, счётчик меняется, а после удаления обычной позиции снова появляется кнопка добавления, хотя подарочная остаётся в корзине. Остаток же относится к варианту: позиции с разными опциями — это всё равно единицы одного товара, поэтому при проверке их количество складывается. Я прошёл по местам, где товар в корзине искали по ID варианта, и в каждом месте развёл эти два вопроса. В виджете уведомлений появилась отдельная ошибка про неверное количество выбранных опций.
Демо-магазин: 7 + 9 единиц одного варианта в двух позициях. При попытке добавить ещё появляется предупреждение о лимите.
Совместимость и документация
Опции должны были работать в виджете карточки товара, AJAX-товарах, превью в категориях, модальных окнах, мультикорзинах и старых шаблонах. Я составил чек-лист проверки: добавление, изменение количества и удаление обычных товаров, товаров с мультискладом и товаров с опциями во всех этих местах, а также пересчёт цены при смене варианта и опций. Ещё я описал API опций для разработчиков, которые собирают карточки и корзины в собственных шаблонах.
Результат
- Покупатель выбирает обязательные и дополнительные опции, сразу видит итоговую цену и кладёт в корзину именно эту комбинацию.
- Один вариант может лежать в корзине несколькими позициями, а изменение количества и удаление касаются только выбранной.
- У разработчиков магазинов появились компонент и задокументированный API корзины для опций в собственных шаблонах.
- Опции работают в товарных виджетах и AJAX-товарах. Про библиотеку, в которую всё это встроено, — кейс о CommonJS.
Скриншоты сделаны в демо-магазине inSales на фотографиях со свободной лицензией. Товары и цены придуманы для примера и не связаны с реальными продажами.