Возврат проектируют в последнюю очередь

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

Пока акции простые, разрыв незаметен: вернули товар со скидкой 10%, вернули 90% его цены. Проблемы начинаются с условных акций, где выгода привязана к составу заказа. Таких в рознице большинство: порог суммы, комплект, подарок к покупке, N штук по цене M.

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

Три примера, где арифметика подводит

Цены возьмём круглые, чтобы считать в уме.

Первый пример, три по цене двух. Футболки по 1 000 ₽, покупатель взял три и заплатил 2 000. Одну вернул. Наивный расчёт: он заплатил 2 000 за три, значит, каждая обошлась в 667 ₽, возвращаем 667. Или ещё проще: вернул товар за 1 000, возвращаем 1 000. В обоих случаях у покупателя остаются две футболки дешевле, чем они стоят без акции. Честный расчёт другой: две футболки без акции стоят 2 000, ровно столько он и заплатил. Возвращать нечего.

Второй пример, порог суммы. «От 5 000 ₽ скидка 15%». Заказ на 6 000, скидка 900, оплачено 5 100. Покупатель возвращает позицию за 2 000. Наивно: возвращаем 2 000 за вычетом тех же 15%, то есть 1 700. Но оставшиеся товары стоят 4 000, порог не пройден, скидки на них нет. Заплатить за них нужно 4 000, оплачено 5 100, к возврату 1 100. Разница с наивным расчётом 600 ₽ на одном заказе.

Третий пример, подарок к покупке. Куртка за 10 000 ₽ и шапка в подарок, в заказе она стоит 0. Покупатель вернул куртку и оставил шапку. Если вернуть 10 000, шапка ушла бесплатно без покупки. Вариантов два, и решить между ними должен владелец магазина заранее: либо шапка возвращается вместе с курткой, либо её цена, скажем 1 500 ₽, удерживается из возврата, и покупатель получает 8 500.

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

Одно правило вместо набора исключений

Можно написать для каждой механики свою инструкцию по возврату. Инструкций будет столько же, сколько типов акций, и каждая новая акция потребует ещё одну. Есть способ проще.

Стоимость заказа — это функция от того, что у покупателя осталось на руках. Всё остальное выводится из неё.

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

У правила есть полезное следствие: покупатель никогда не оказывается в лучшем положении, чем если бы сразу заказал только то, что оставил. И никогда в худшем. Это одновременно защита от злоупотреблений и объяснение для службы поддержки, которое можно произнести вслух и не покраснеть.

Одна тонкость. Пересчитывать нужно по условиям акции на момент оформления. Акция могла закончиться, у неё могли поменять процент или состав. Поэтому в заказе должен храниться снимок условий, по которым он был посчитан. Без снимка правило не работает.

Баллы и кэшбэк подчиняются той же логике

С программой лояльности возврат задевает ещё две вещи: баллы, которыми оплатили заказ, и баллы, которые за него начислили.

С начислением проще. Кэшбэк 10% на заказ в 1 200 ₽ дал 120 баллов. Покупатель вернул товар на 500, значит, 50 баллов нужно снять с баланса, а оборот, по которому считается его уровень в программе, уменьшить на те же 500. Если баллы начисляются после получения заказа, а не при оформлении, сторно случается реже. Это отдельный аргумент за такой порядок.

Со списанием сложнее из-за фискального чека. Если баллы живут только на уровне заказа записью «оплачено баллами 300 ₽», позиции чека не сходятся с суммой платежа, и банк такой чек отклоняет. Поэтому баллы должны раскладываться по строкам как скидка. А при возврате деньгами возвращается не больше, чем деньгами было заплачено. Излишек, если он есть, возвращается на счёт баллами.

Как это устроено в Skuby

В Skuby это правило заложено в модуль заказов, а не в инструкцию для поддержки. Один и тот же движок ценообразования считает корзину, оформление, изменение состава заказа и возврат. Условия применённых акций сохраняются в заказе снимком, поэтому пересчёт не зависит от того, что с акцией случилось потом.

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

Три сценария из этой статьи, вместе с порогом суммы и удалением позиции перед оплатой, входят в набор обязательных тестов модуля промо. На демо мы показываем их на живом заказе.

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

Что проверить в своей системе

Менять платформу ради этого не обязательно. Достаточно задать подрядчику или вендору четыре вопроса и попросить показать ответ на тестовом заказе.

  • Заказ по акции «три по цене двух», возврат одной. Сколько система предложит вернуть?
  • Акция с порогом суммы, возврат опускает заказ ниже порога. Пересчитается ли скидка на оставшееся?
  • Подарок к покупке, возврат основного товара. Где задаётся, что делать с подарком?
  • Заказ с кэшбэком получен, баллы начислены. Что происходит с ними при частичном возврате?

Если хотя бы на один вопрос ответ «менеджер посчитает вручную», у вас появилась цифра, которую стоит посчитать: сколько таких возвратов в месяц и во сколько обходится каждый.