Интернет-магазин с высоким средним чеком теряет до 30% заказов из‑за ложных оформлений. Покупатель случайно нажал «Оформить», а менеджер тратит 2–3 часа в день на прозвон невалидных заказов. Это не только трата времени, но и потеря реальных клиентов: пока менеджер обзванивает «пустышки», он не обрабатывает горячие лиды. Решение — подтверждение заказа через SMS‑код. Мы внедряем этот механизм в 1С‑Битрикс, сохраняя стандартный UX чекаута и не заставляя клиента прыгать по страницам. Уже на первых неделях экономится до 80% времени на обработку заказов, а конверсия в оплату вырастает на 15–20%. Результат достигается за счёт трёх компонентов: rate‑limit на отправку, хеширование кода через password_hash и интеграция с любым SMS‑провайдером через интерфейс SmsProviderInterface. По сравнению с ручной модерацией, автоматическая верификация сокращает время обработки заказа в 5 раз.
Документация события OnBeforeSaleOrderSaved
Как работает SMS‑верификация заказа?
Покупатель заполняет форму заказа, нажимает «Оформить». Система отправляет SMS с шестизначным кодом на указанный телефон. Код действует 5 минут, попыток ввода — 3. После успешной верификации создаётся заказ. До этого момента заказ не существует в системе.
Хранение кодов реализовано в отдельной таблице:
CREATE TABLE local_order_confirmations ( ID INT AUTO_INCREMENT PRIMARY KEY, PHONE VARCHAR(20) NOT NULL, CODE VARCHAR(6) NOT NULL, SESSION_ID VARCHAR(128), ATTEMPTS TINYINT DEFAULT 0, CONFIRMED CHAR(1) DEFAULT 'N', CREATED_AT DATETIME NOT NULL, EXPIRES_AT DATETIME NOT NULL, INDEX idx_phone_code (PHONE, CODE), INDEX idx_session (SESSION_ID) ); Срок жизни кода — 5 минут. Максимум попыток — 3. После исчерпания — новый запрос кода с задержкой (rate limit: не более 3 отправок в 15 минут). Такая защита снижает нагрузку на SMS‑провайдер в 15 раз по сравнению с открытым запросом.
Почему хеширование кода важно?
Код хранится в базе в хешированном виде — password_hash(). Даже при утечке базы коды не скомпрометированы. Это обязательное условие для соответствия 54‑ФЗ и защиты персональных данных.
Интеграция в стандартный чекаут
JavaScript‑перехват — sms верификация заказов
Если используется sale.order.ajax, мы вмешиваемся в его JavaScript. Перехватываем событие отправки формы:
// В result_modifier.php компонента или подключаемом JS BX.addCustomEvent('onSaleComponentOrderSuccess', function(order) { // Стандартная обработка — отключаем }); document.querySelector('.order-confirm-btn').addEventListener('click', async (e) => { e.preventDefault(); const phone = document.querySelector('[name="ORDER_PROP_PHONE"]').value; // Запрашиваем SMS const res = await fetch('/local/api/order-confirm/send', { method: 'POST', headers: {'Content-Type': 'application/json', 'X-Bitrix-Csrf-Token': BX.bitrix_sessid()}, body: JSON.stringify({phone}) }); if (res.ok) { showCodeInputModal(phone); } }); После успешного подтверждения кода фронтенд отправляет токен подтверждения вместе с данными заказа, сервер проверяет токен до создания заказа.
Серверный контроллер и хеширование
class OrderConfirmController { public function sendCode(): void { $phone = $this->normalizePhone($_POST['phone'] ?? ''); if (!$phone) { $this->error('Неверный номер телефона'); } // Rate limit: не более 3 отправок в 15 минут if ($this->isRateLimited($phone)) { $this->error('Слишком много запросов. Подождите 15 минут.'); } $code = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT); $expiresAt = (new \DateTime())->modify('+5 minutes'); OrderConfirmationTable::add([ 'PHONE' => $phone, 'CODE' => password_hash($code, PASSWORD_DEFAULT), // не храним открытый код 'SESSION_ID' => session_id(), 'EXPIRES_AT' => \Bitrix\Main\Type\DateTime::createFromTimestamp($expiresAt->getTimestamp()), ]); SmsService::send($phone, "Код подтверждения заказа: {$code}. Действует 5 минут."); $this->success(['expires_in' => 300]); } public function verifyCode(): void { $phone = $this->normalizePhone($_POST['phone'] ?? ''); $code = $_POST['code'] ?? ''; $record = OrderConfirmationTable::getActiveRecord($phone, session_id()); if (!$record) { $this->error('Код не найден или истёк срок действия'); } // Increment attempts OrderConfirmationTable::incrementAttempts($record['ID']); if ($record['ATTEMPTS'] >= 3) { $this->error('Превышено число попыток. Запросите новый код.'); } if (!password_verify($code, $record['CODE'])) { $this->error('Неверный код'); } // Код верный — выдаём одноразовый токен для создания заказа $token = bin2hex(random_bytes(32)); OrderConfirmationTable::markConfirmed($record['ID'], $token); $this->success(['token' => $token]); } } Проверка токена при создании заказа
Перед стандартным созданием заказа через OnBeforeSaleOrderSaved или переопределение контроллера:
AddEventHandler('sale', 'OnBeforeSaleOrderSaved', function(\Bitrix\Sale\Order $order, array $data) { if (!ConfirmConfig::isRequiredForOrder($order)) { return; // не все заказы требуют подтверждения } $token = $_POST['confirm_token'] ?? ''; if (!OrderConfirmationTable::isValidToken($token, session_id())) { throw new \Exception('Заказ не подтверждён по SMS'); } }); Выбор SMS‑провайдера
Интеграция с провайдером через абстракцию:
interface SmsProviderInterface { public function send(string $phone, string $message): bool; } Реализации: SMS.ru, SMSC.ru, МТС Коммуникатор, интеграция через Битрикс24 SMS. Переключение провайдера без изменения бизнес‑логики.
Сравнение провайдеров
| Провайдер | Скорость доставки | Поддержка UTM |
|---|---|---|
| SMS.ru | 1-3 сек | Да |
| SMSC.ru | 2-5 сек | Нет |
| МТС Коммуникатор | 1-2 сек | Да |
Развёрнутая таблица сравнения провайдеров
| Провайдер | API‑документация | Цена за SMS | Интеграция с Битрикс24 |
|---|---|---|---|
| SMS.ru | REST, JSON | от 0.5 руб | Через модуль |
| SMSC.ru | REST, XML | от 0.6 руб | Через SMSC.ru |
| МТС Коммуникатор | SOAP, REST | от 0.7 руб | Через модуль |
Внедрение и результаты
Пошаговая инструкция внедрения
- Создайте таблицу
local_order_confirmationsпо приведённому SQL. - Реализуйте контроллер
OrderConfirmControllerс методамиsendCodeиverifyCode. - Интегрируйте JavaScript в чекаут — перехватите событие отправки формы.
- Добавьте обработчик
OnBeforeSaleOrderSavedдля проверки токена. - Подключите SMS‑провайдер через интерфейс.
- Проведите нагрузочное тестирование (1000 запросов).
Ожидаемые результаты
| Параметр | Без SMS‑кода | С SMS‑кодом |
|---|---|---|
| Ложные заказы | до 30% | менее 5% |
| Затраты менеджеров на прозвон | 2‑3 часа/день | 0 |
| Время оформления заказа | 1‑2 мин | 3‑4 мин |
| Конверсия в оплату | 60% | 85% |
Что входит в работу и сроки
- Создание таблицы
local_order_confirmationsи миграции - Реализация API‑контроллера с rate limit и хешированием кода
- Интеграция с чекаутом: перехват JS, модальное окно, передача токена
- Обработчик
OnBeforeSaleOrderSavedдля проверки токена - Подключение SMS‑провайдера (любой из трёх)
- Документация по установке и настройке
- Нагрузочное тестирование (до 1000 одновременных запросов)
Сроки: 5–7 дней с одним провайдером SMS. 1.5–2 недели при кастомном чекауте.
Наша команда имеет 8‑летний опыт разработки на 1С‑Битрикс и реализовала 70+ проектов с кастомными чекаутами. Мы гарантируем стабильную работу под нагрузкой и предоставляем поддержку в течение 3 месяцев после внедрения.
Свяжитесь с нами для бесплатной оценки проекта. Получите консультацию прямо сейчас.







