Налаштування верифікації телефону під час замовлення 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Налаштування верифікації телефону під час замовлення 1С-Бітрікс
Проста
~1 робочий день
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Налаштування верифікації телефону при замовленні 1С-Бітрікс

OTP-верифікація телефону під час оформлення замовлення вирішує два завдання: підтверджує, що покупець реально існує, та відсікає шахрайські замовлення з неіснуючими номерами. Неверифіковані номери зустрічаються у 15–20% шахрайських замовлень. У Бітрікс OTP реалізується через подію створення замовлення та SMS-шлюз.

Схема верифікації

  1. Користувач вводить номер телефону на сторінці замовлення
  2. AJAX-запит — генеруємо OTP, зберігаємо в сесії/кеші, надсилаємо SMS
  3. Користувач вводить код
  4. AJAX-запит — перевіряємо код, встановлюємо прапор «телефон підтверджено»
  5. При оформленні замовлення — перевіряємо прапор, без нього замовлення не проходить

Генерація та надсилання OTP

// /local/ajax/phone-otp-send.php
\Bitrix\Main\Application::getInstance()->initializeExtended();

$phone  = preg_replace('/\D/', '', $_POST['phone'] ?? '');
$csrfOk = check_bitrix_sessid();

if (!$csrfOk || strlen($phone) < 10 || strlen($phone) > 15) {
    http_response_code(400);
    echo json_encode(['error' => 'Invalid request']);
    exit;
}

// Ліміт: не більше 3 відправок на номер за 10 хвилин
$cacheKey   = 'otp_attempts_' . md5($phone);
$attempts   = (int)(\Bitrix\Main\Application::getInstance()
               ->getManagedCache()->get($cacheKey) ?? 0);

if ($attempts >= 3) {
    echo json_encode(['error' => 'Забагато спроб. Зачекайте 10 хвилин.']);
    exit;
}

// Генеруємо 6-значний код
$code      = (string)random_int(100000, 999999);
$expiresAt = time() + 300; // 5 хвилин

// Зберігаємо в сесії (або в Redis)
\Bitrix\Main\Application::getInstance()->getSession()->set('otp_data', [
    'phone'      => $phone,
    'code'       => password_hash($code, PASSWORD_DEFAULT),
    'expires_at' => $expiresAt,
    'verified'   => false,
]);

// Інкрементуємо лічильник спроб
\Bitrix\Main\Application::getInstance()->getManagedCache()->set($cacheKey, $attempts + 1, 600);

// Надсилаємо SMS через модуль Бітрікс (SMS-провайдер налаштовується в адміністративній частині)
$smsManager = new \Bitrix\MessageService\Sender\MessageManager('sms');
$result     = $smsManager->enqueueMessage([
    'MESSAGE_TO'   => '+' . $phone,
    'MESSAGE_BODY' => "Ваш код підтвердження: {$code}. Дійсний 5 хвилин.",
]);

echo json_encode([
    'success'     => $result->isSuccess(),
    'expires_at'  => $expiresAt,
    'masked_phone' => '+' . substr($phone, 0, 3) . '***' . substr($phone, -2),
]);

Перевірка коду

// /local/ajax/phone-otp-verify.php
\Bitrix\Main\Application::getInstance()->initializeExtended();

$inputCode = trim($_POST['code'] ?? '');
$session   = \Bitrix\Main\Application::getInstance()->getSession();
$otpData   = $session->get('otp_data');

if (!$otpData || time() > $otpData['expires_at']) {
    echo json_encode(['success' => false, 'error' => 'Код застарів. Запросіть новий.']);
    exit;
}

if (!password_verify($inputCode, $otpData['code'])) {
    echo json_encode(['success' => false, 'error' => 'Невірний код.']);
    exit;
}

// Позначаємо телефон як підтверджений
$otpData['verified'] = true;
$session->set('otp_data', $otpData);

echo json_encode(['success' => true]);

Блокування замовлення без верифікації

AddEventHandler('sale', 'OnBeforeOrderFinalAction', function(\Bitrix\Sale\Order $order) {
    if ($order->getId() > 0) return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS);

    $otpData = \Bitrix\Main\Application::getInstance()->getSession()->get('otp_data');
    $props   = $order->getPropertyCollection();
    $phone   = preg_replace('/\D/', '', $props->getItemByOrderPropertyCode('PHONE')?->getValue() ?? '');

    if (empty($otpData['verified'])
        || !$otpData['verified']
        || $otpData['phone'] !== $phone)
    {
        return new \Bitrix\Main\EventResult(
            \Bitrix\Main\EventResult::ERROR,
            new \Bitrix\Main\Error('Будь ласка, підтвердіть номер телефону.')
        );
    }

    // Скидаємо OTP після використання
    \Bitrix\Main\Application::getInstance()->getSession()->delete('otp_data');

    return new \Bitrix\Main\EventResult(\Bitrix\Main\EventResult::SUCCESS);
});

Фронтенд: форма введення коду

class PhoneVerification {
    constructor(formSelector) {
        this.form     = document.querySelector(formSelector);
        this.phoneInput  = this.form?.querySelector('[name="PHONE"]');
        this.otpBlock    = document.createElement('div');
        this.countdown   = null;
    }

    init() {
        this.phoneInput?.addEventListener('blur', () => this.showOtpRequest());
    }

    async sendOtp() {
        const phone = this.phoneInput.value;
        const res   = await fetch('/local/ajax/phone-otp-send.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: `phone=${encodeURIComponent(phone)}&sessid=${BX.bitrix_sessid()}`,
        }).then(r => r.json());

        if (res.success) {
            this.showCodeInput(res.expires_at, res.masked_phone);
        } else {
            this.showError(res.error);
        }
    }

    showCodeInput(expiresAt, maskedPhone) {
        this.otpBlock.innerHTML = `
            <p>Код надіслано на ${maskedPhone}</p>
            <input type="text" id="otp-code" maxlength="6" inputmode="numeric"
                   autocomplete="one-time-code" placeholder="_ _ _ _ _ _">
            <button type="button" id="verify-btn">Підтвердити</button>
            <span id="otp-timer"></span>
        `;
        this.startCountdown(expiresAt);
        document.getElementById('verify-btn').addEventListener('click', () => this.verifyCode());
    }

    async verifyCode() {
        const code = document.getElementById('otp-code').value;
        const res  = await fetch('/local/ajax/phone-otp-verify.php', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: `code=${encodeURIComponent(code)}&sessid=${BX.bitrix_sessid()}`,
        }).then(r => r.json());

        if (res.success) {
            this.otpBlock.innerHTML = '<p class="verified">✓ Телефон підтверджено</p>';
            clearInterval(this.countdown);
            // Розблоковуємо кнопку оформлення замовлення
            document.querySelector('.btn-checkout-submit')?.removeAttribute('disabled');
        } else {
            document.getElementById('otp-code').classList.add('is-error');
        }
    }

    startCountdown(expiresAt) {
        const timer = document.getElementById('otp-timer');
        this.countdown = setInterval(() => {
            const left = Math.max(0, expiresAt - Math.floor(Date.now() / 1000));
            timer.textContent = `Код дійсний ${left} сек`;
            if (left === 0) {
                clearInterval(this.countdown);
                timer.textContent = 'Код застарів. Запросіть новий.';
            }
        }, 1000);
    }
}

SMS-провайдери в Бітрікс

Модуль messageservice підтримує кілька провайдерів з коробки: SMS.ru, SMSC.ru, MessageBird. Налаштування через адміністративну частину: Налаштування → SMS-сервіси. Кастомний провайдер підключається як клас, що реалізує інтерфейс \Bitrix\MessageService\Sender\Base.

Терміни реалізації

Конфігурація Термін
OTP (send + verify + блокування замовлення) 2–3 дні
+ фронтенд з таймером та зворотним зв'язком +1–2 дні
+ кастомний SMS-провайдер +1 день