Настройка подтверждения заказа через SMS-код 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка подтверждения заказа через SMS-код 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка подтверждения заказа через SMS-код 1С-Битрикс

На крупных магазинах с высоким средним чеком встречается задача: перед финальным оформлением заказа подтвердить намерение покупателя по SMS. Это снижает число «случайных» заказов и верифицирует номер телефона, который потом используется в программе лояльности. Стандартный чекаут 1С-Битрикс такого механизма не имеет — нужно вмешиваться в процесс оформления.

Архитектура подтверждения

Процесс: покупатель заполнил форму заказа → нажал «Оформить» → система отправляет SMS с кодом на указанный телефон → покупатель вводит код → заказ создаётся. Заказ в Битрикс создаётся только после успешной верификации кода, не раньше.

Хранение кодов — в таблице local_order_confirmations:

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).

Интеграция в чекаут

Если используется 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]);
    }
}

Код хранится в базе в хешированном виде — password_hash(). Даже при утечке базы коды не скомпрометированы.

Проверка токена при создании заказа

Перед стандартным созданием заказа через 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. Переключение провайдера без изменения бизнес-логики.

Состав работ

  • Таблица подтверждений, логика rate limit и попыток
  • API-контроллер: отправка кода, верификация, выдача токена
  • Интеграция с чекаутом (перехват JS, передача токена)
  • Проверка токена перед созданием заказа
  • Подключение SMS-провайдера

Сроки: 5–7 дней с одним провайдером SMS. 1.5–2 недели при кастомном чекауте.