Скидка на товар работает. Промокод работает. Цена для оптовика работает. А когда клиент кладёт в корзину акционный товар, вводит промокод и оказывается в группе с оптовой ценой — магазин внезапно продаёт в минус. Никто не заметит, пока не сойдётся отчётность, а к тому времени убыток уже реальный. Корзина ломается не громко, а тихо — в комбинациях, которые никто не проверял.
Разберём, как проводить кросс-проверку корзины, скидок и промокодов в магазине на 1С-Битрикс: как устроен расчёт итоговой суммы через sale.order, где прячутся ошибки приоритетов и граничных случаев, как построить матрицу проверки и закрыть логику автотестами. Настроить и проверить связку заказа с учётом помогает автоматизация продаж и склада на 1С.
Коротко
- Итоговая сумма — результат взаимодействия многих правил; ошибки прячутся в их комбинациях, а не в отдельных скидках.
- Главный источник убытков — неверные приоритеты: скидки складываются там, где должна применяться одна.
- Целенаправленно тестируйте граничные случаи: ноль, минус, пороги срабатывания, округление, промокод на уценённый товар.
- Сумму всегда считает сервер по правилам sale.order, а ключевые сценарии закрывают автотестами и прогоняют при деплое.
Почему корзина ломается тихо
Корзина — самое опасное место магазина, потому что её ошибки не падают с ошибкой сервера, а просто выдают неверную сумму. Товар всё так же добавляется, заказ оформляется, письмо уходит — только цифра неправильная. Такую поломку невозможно заметить по логам; она всплывает, когда клиент удивился, или когда бухгалтерия не сошлась.
Причина в комбинаторике: каждая скидка по отдельности проста, но вместе они образуют сотни сочетаний, и проверить их «на глаз» нельзя. Именно поэтому корзину нужно проверять системно — комбинациями и граничными случаями, а не парой ручных заказов «вроде работает».
Из чего складывается итоговая сумма
Чтобы проверять корзину, нужно понимать, из каких слоёв собирается итог. В 1С-Битрикс на сумму влияют:
- Цена товара по группе. Тип цены зависит от группы клиента (розница, опт, дилер).
- Скидки на товар. Акции и уценки на конкретные позиции.
- Скидки на корзину. Правила от суммы или состава заказа.
- Промокоды. Купоны с собственными условиями и ограничениями.
- Доставка. Платная, бесплатная от суммы, скидка на доставку.
Все эти слои взаимодействуют, и порядок их применения определяет итог. Ошибка на любом стыке искажает сумму, поэтому проверять надо не слои по отдельности, а их совместную работу.
Приоритеты и сложение скидок
Главный источник убытков — неверно настроенные приоритеты. В правилах работы с корзиной у каждой скидки есть приоритет и флаг, прекращать ли дальнейшую обработку. От этого зависит, применится ли только одна лучшая скидка или несколько сложатся.
Кросс-проверка начинается именно здесь: берут пары и тройки скидок и убеждаются, что они складываются (или не складываются) ровно так, как задумано бизнесом. Это первый и самый важный тест.
Промокоды и их взаимодействие со скидками
Промокод — отдельный слой со своими условиями, и его взаимодействие с акциями надо продумать. Типичные вопросы: складывается ли промокод с акционной ценой? применяется ли к уже уценённому товару? действует ли для оптовой группы? Ответ на каждый — бизнес-решение, которое затем проверяют на всех комбинациях.
Частое правило — промокод не суммируется с товарными акциями, иначе маржа уходит в ноль. Но правило само по себе бесполезно, если не проверено: задача кросс-проверки — убедиться, что заявленное поведение реально выполняется, а не только в тех сценариях, что глянули руками.
Граничные случаи
Больше всего ошибок живёт на краях логики. Их надо тестировать целенаправленно:
- Ноль и минус. Скидка делает товар бесплатным или уводит сумму ниже нуля.
- Пороги срабатывания. Скидка «от 5000» ровно на 5000 и на 4999 — включается ли корректно.
- Промокод на уценённое. Купон поверх уже сниженной цены.
- Один товар и много товаров. Корзина из одной позиции и из сотни.
- Удаление позиции. Скидка от суммы отваливается, если убрать товар и сумма упала ниже порога.
«Обычные» заказы такие случаи не покрывают — их надо проверять специально, потому что именно здесь всплывают минусовые суммы и ошибки округления.
Округление и переполнение
Скидки в процентах порождают дробные значения, а деньги считают до копейки — на стыке возникают ошибки округления. Проблема в том, где округлять: на позицию, на строку или на весь заказ; сумма отдельно округлённых позиций может не совпасть с округлённым итогом.
Правильный подход — единое, заранее определённое правило округления по всему расчёту, а не «где как получилось». Проверяют это на суммах, дающих дробные скидки (например, 33% от нечётной цены), и сверяют, что итог, позиции и данные в учёте сходятся до копейки.
Матрица сценариев проверки
Системная проверка строится как матрица: перебор ключевых измерений и сверка фактической суммы с ожидаемой.
| Измерение | Варианты |
|---|---|
| Группа клиента | Розница, опт, дилер |
| Скидка на товар | Нет, акция, уценка |
| Скидка на корзину | Нет, от суммы, от состава |
| Промокод | Нет, процент, фикс, на категорию |
| Порог/граница | Ниже, ровно, выше порога |
Даже сокращённая матрица даёт десятки сценариев — гораздо больше, чем проверяют вручную. Ключевые из них автоматизируют, чтобы прогонять повторно при каждом изменении.
Пересчёт на сервере и безопасность
Итоговую сумму, скидки и применимость промокода всегда считает сервер, а не браузер. Данные, пришедшие от клиента — цена, скидка, итог, — принимать на веру нельзя: подмена цены в запросе иначе превращается в дыру. Сервер заново рассчитывает корзину по правилам sale.order при каждом изменении и обязательно перед оформлением, а фронтенд лишь отображает результат.
Это часть более широкой темы доверия к входным данным. Почему нельзя доверять тому, что прислал клиент, и как защищать серверные точки входа, мы разбирали в статье про REST, вебхуки и безопасность в Битрикс.
Согласование суммы с 1С
Отдельный класс ошибок — расхождение суммы на сайте и в учётной системе. Оно возникает, когда скидки считаются в двух местах по-разному: часть логики на сайте, часть — в 1С. Правильно, когда итог считается в одном месте и передаётся обменом без повторного пересчёта, иначе клиент, бухгалтерия и склад видят разные цифры по одному заказу.
Поэтому кросс-проверка включает сверку: сумма заказа на сайте = сумма в 1С после обмена. Навести порядок в этой связке помогает автоматизация на 1С, а начать при хаотичном обмене логично с диагностики через аудит.
Автотесты на уровне sale.order
Ручная проверка не масштабируется: комбинаций слишком много, а после каждой правки их надо перепроверять. Решение — автотесты на уровне заказа: сценарий собирает корзину программно через sale.order, применяет скидки и промокод и сверяет итог с ожидаемым.
- Опишите ожидания. Для каждого сценария — вход (товары, группа, промокод) и точная ожидаемая сумма.
- Соберите заказ программно. Через API заказа, а не кликами в браузере.
- Примените правила. Дайте системе рассчитать скидки как в бою.
- Сверьте до копейки. Фактический итог должен совпасть с ожидаемым.
- Держите набор в репозитории. Тесты живут с кодом и прогоняются автоматически.
Проверка перед деплоем
Логика корзины — самое хрупкое место магазина: правка одной скидки легко ломает другую. Поэтому набор тестов на скидки прогоняют при каждом развёртывании, до того как изменения увидит покупатель. Это ловит регрессии — случаи, когда «починили одно, сломали другое» — на этапе выкладки, а не в проде.
Встроить прогон тестов в процесс выкладки — часть культуры контролируемого деплоя, о которой мы писали в статье про CI/CD и деплой в Битрикс. Для критичной логики скидок такой автоматический барьер особенно ценен.
Частые ошибки
- Проверяют скидки поодиночке. Каждая работает, а вместе дают минус — комбинации не протестированы.
- Приоритеты «по умолчанию». Скидки складываются там, где должна быть одна, и маржа обнуляется.
- Игнор граничных случаев. Ноль, минус и пороги не проверяются, пока не всплывут в бою.
- Округление в разных местах. Позиции и итог не сходятся до копейки.
- Доверие данным клиента. Сумма берётся из запроса, а не пересчитывается сервером.
- Расхождение с 1С. Скидки считаются дважды по-разному, суммы не совпадают.
- Нет автотестов. Каждый деплой рискует тихо сломать корзину.
Чек-лист проверки
- Приоритеты заданы явно. Решено и настроено, складываются скидки или выбирается одна.
- Промокод × акция. Проверено заявленное поведение во всех комбинациях.
- Граничные случаи. Ноль, минус, пороги, промокод на уценённое — протестированы.
- Округление едино. Одно правило по всему расчёту, позиции и итог сходятся.
- Матрица прогнана. Группы × скидки × промокоды × пороги сверены с ожиданием.
- Считает сервер. Итог рассчитывается по sale.order, данные клиента не в доверии.
- Сумма = 1С. Итог заказа на сайте совпадает с учётом после обмена.
- Тесты в деплое. Сценарии скидок прогоняются при каждой выкладке.
Вывод
Корзина ломается тихо и дорого — не ошибкой сервера, а неверной суммой в комбинации скидок, которую никто не проверял. Поэтому её тестируют системно: приоритеты и сложение скидок, взаимодействие промокодов, граничные случаи и округление — комбинациями, а не поодиночке, через матрицу сценариев с точными ожиданиями.
Считайте сумму только на сервере по правилам sale.order, согласуйте итог с 1С и закройте ключевые сценарии автотестами, которые прогоняются при каждом деплое. Тогда самое хрупкое место магазина перестанет быть источником тихих убытков и станет предсказуемой, проверяемой частью системы.