# Защита от ботов для оформления заказа и форм покупателей

> Невидимая капча внутри отправки форм inSales — в оформлении заказа, личном кабинете и формах магазина. Затем выбор между Google reCAPTCHA и Yandex SmartCaptcha одной настройкой магазина.

- Адрес: https://anu3ev.com/ru/work/form-protection/
- Период: Октябрь 2023 – июль 2026
- Где: inSales
- Роль: Отвечал за frontend-интеграцию, общий код капчи и выпуск
- Навыки: JavaScript, Vue, Slim, Liquid, Google reCAPTCHA, Yandex SmartCaptcha
- Результаты:
  - 2: провайдера капчи, Google и Яндекс, на выбор для поддерживаемых форм магазина
  - 3: поколения оформления заказа с капчей: 1.0, 2.0 и 3.0
  - 4: семейства форм витрины в общей JavaScript-библиотеке

## Задача

В магазинах на 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](https://docs.liquidhub.ru/Примеры%20работы%20с%20данными%20магазина/reCAPTCHA/recaptcha-common/) и [Yandex SmartCaptcha](https://www.insales.ru/collection/primery-raboty-s-dannymi-magazina/product/yandex-captcha).

## Ограничения

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