Платформа витрин
Защита от ботов для оформления заказа и форм покупателей
Невидимая капча внутри отправки форм inSales — в оформлении заказа, личном кабинете и формах магазина. Затем выбор между Google reCAPTCHA и Yandex SmartCaptcha одной настройкой магазина.
- 2 провайдера капчи, Google и Яндекс, на выбор для поддерживаемых форм магазина
- 3 поколения оформления заказа с капчей: 1.0, 2.0 и 3.0
- 4 семейства форм витрины в общей JavaScript-библиотеке
- Моя роль
- Отвечал за frontend-интеграцию, общий код капчи и выпуск
- Период
- Октябрь 2023 – июль 2026
- Навыки
На этой странице
Задача
В магазинах на inSales покупатели через формы оформляют заказы, входят в кабинет, регистрируются, восстанавливают доступ, пишут отзывы и обращения. Владельцы магазинов входят в свой аккаунт платформы. Всё это интересно ботам: при атаке они могли создавать сотни заказов в секунду. При этом защита не должна мешать живому покупателю нажать «Отправить» и оформить заказ.
Раньше перед отправкой нужно было отметить «Я не робот». В 2025 году продуктовая команда принесла вторую проблему: клиентов беспокоило, что персональные данные обрабатывает зарубежный сервис, а у части покупателей Google не открывался. Нужна была альтернатива, которую магазин включает одной настройкой, без переделки каждой формы. Сложность была в самой платформе. Формы жили в двух поколениях личного кабинета, трёх поколениях оформления заказа, серверных шаблонах, Vue-приложениях, штатных виджетах и в коде, который клиенты правили сами. Часто несколько форм оказывались на одной странице.
Моя роль
Frontend был на мне: точки интеграции, общий код и компоненты, тестовые сборки, сопровождение QA, выпуск и поддержка после релиза. Проверку токена на сервере делали backend-разработчики, контракты запросов я согласовывал с ними. За пределами фронтенда сделал одну точечную правку в Rails. Google-этап выпустил в 2023 году, выбор провайдера добавил в 2025-м (основной релиз 26 августа 2025 года), сопровождение продолжалось и в 2026-м.
Что я сделал
Проверка стала частью отправки
Я встроил Google reCAPTCHA Invisible в существующую отправку форм. Форма проверяет поля как обычно, ждёт токен капчи и только потом отправляется, а сервер проверяет токен и решает, принимать ли запрос. Сервис по-прежнему может показать задание, если ему это нужно. Для AJAX-форм сделал отдельное продолжение отправки, чтобы они не превращались в переход на другую страницу. Прежние правила сохранились: при входе по паролю капча нужна только после нескольких неудачных попыток, а у входа по одноразовому коду свои формы и обработчики.
Ответ капчи относится к одной форме
Покупатель открывает форму обратной связи, запускает проверку и закрывает задание. Потом отправляет отзыв и проходит проверку уже там. Если оба обработчика ждут одно общее событие, токен от отзыва может отправить форму обратной связи. В ранней версии всё усугубляла шина событий: новому подписчику она могла вернуть старые данные. Я привязал обработчик проверки к конкретной форме вместе с её экземпляром капчи и токеном.
Одна настройка и три слоя интеграции
Я предложил настройку типа капчи в настройках магазина и выпускал её под фича-флагом. С бэкендом договорился, как передавать значение в Liquid-шаблоны, чтобы системные формы, библиотека и виджеты темы читали одно и то же. Новый провайдер подхватывается после перезагрузки страницы: открытая форма не меняет сервис посреди заполнения.
Интеграцию сделал в трёх местах, по устройству платформы. В CommonJS, общей JavaScript-библиотеке витрин, — модуль для 4 семейств форм: обратная связь, отзывы, комментарии, заказ в один клик. Для личных кабинетов и оформления заказа 1.0 и 2.0 — переиспользуемые Slim-шаблоны. Для checkout 3.0 и входа владельцев магазинов — Vue-компонент. Отрисовка, получение токена и отправка остались отдельными шагами, поэтому форма, которую отправляет собственный скрипт, может включить только отрисовку.
Один скрипт на страницу
SmartCaptcha могли подключить и системная форма, и виджет магазина. Повторная загрузка создавала новый window.smartCaptcha, который ничего не знал об уже отрисованных экземплярах. Покупатель видел кнопку «Отправить», которая не работала, причём только при определённом порядке загрузки частей страницы. Я доработал загрузчики в шаблонах и библиотеке: если скрипт уже есть на странице, он используется повторно.
Сбои и старые аккаунты
Если покупатель закрывал задание, форма так и оставалась в состоянии отправки. Я сделал так, что закрытие сбрасывает это состояние и можно попробовать ещё раз. При повторной попытке и после долгого ожидания форма получает свежий токен. Первую выкатку системных форм в августе 2025 года пришлось откатить: в части старых магазинов капча не появлялась вовсе. У этих аккаунтов не было записи с настройками, и условие, которое ждало «google» или «yandex», не срабатывало ни для одного варианта. Я добавил в Rails-модель аккаунта Google по умолчанию для такого случая. Исправление вышло через три дня.
В Safari после отправки страница неожиданно прокручивалась наверх, это я тоже исправил. На некоторых Android-устройствах клавиатура закрывала поле внутри задания провайдера. Полностью решить это на нашей стороне не получилось, поэтому я собрал тестовую страницу, записал видео и передал проблему в поддержку Yandex Cloud.
Результат
- 2 провайдера, Google reCAPTCHA и Yandex SmartCaptcha, выбираются 1 настройкой магазина для поддерживаемых форм.
- Капча работает в 3 поколениях оформления заказа, 2 поколениях личного кабинета, 4 семействах форм витрины и во входе владельцев магазинов.
- Поддерживаемые формы отправляются с невидимой проверкой, без обязательного чекбокса.
- Разработчики магазинов получили документированные API и примеры для подключения капчи к своим формам: для Google reCAPTCHA и Yandex SmartCaptcha.
Ограничения
Выбор провайдера не сделал капчу обязательной везде: у каждой формы остались свои правила, когда проверка нужна. Формы, встроенные в старые темы, и кастомные виджеты со своей интеграцией нужно было обновлять вручную. Покрыты не все формы админки.