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

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

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

Фіктивний email у замовленні — це втрачений контакт із покупцем, повернення листа з трекінгом у нікуди, іноді — сигнал шахрайського замовлення. Email-верифікація при оформленні замовлення підтверджує, що адреса існує та належить користувачу. Для гостьових покупок це особливо важливо.

Два рівні верифікації

Синтаксична перевірка — мінімальна валідація формату та DNS MX-запису домену. Швидка, без відправки листа, ловить помилки та неіснуючі домени.

Повна верифікація через посилання — надсилаємо лист із посиланням, користувач переходить, підтверджує. Надійна, але вимагає дії від користувача.

Для замовлень найчастіше достатньо першого рівня з можливістю увімкнути другий для підозрілих адрес.

Синтаксична перевірка + MX

namespace Local\Validation;

class EmailValidator
{
    public static function validate(string $email): ValidationResult
    {
        // Формат
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return new ValidationResult(false, 'Невірний формат email');
        }

        $domain = strtolower(substr(strrchr($email, '@'), 1));

        // Одноразові домени
        if (self::isDisposable($domain)) {
            return new ValidationResult(false, 'Тимчасові email-адреси не приймаються');
        }

        // Перевірка MX-запису
        if (!self::hasMxRecord($domain)) {
            return new ValidationResult(false, 'Домен не приймає пошту');
        }

        return new ValidationResult(true, '');
    }

    private static function isDisposable(string $domain): bool
    {
        $disposable = [
            'mailinator.com', 'guerrillamail.com', 'tempmail.com',
            'throwam.com', 'yopmail.com', '10minutemail.com',
            'trashmail.com', 'dispostable.com', 'fakeinbox.com',
            'getairmail.com', 'sharklasers.com',
        ];
        return in_array($domain, $disposable, true);
    }

    private static function hasMxRecord(string $domain): bool
    {
        // getmxrr працює надійно, але потребує DNS-резолвера
        // Таймаут ~1-2 сек при недоступному DNS
        return (bool)@getmxrr($domain, $mxHosts);
    }
}

Застосування в обробнику замовлення

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

    $props = $order->getPropertyCollection();
    $email = trim($props->getItemByOrderPropertyCode('EMAIL')?->getValue() ?? '');

    if (empty($email)) {
        return new \Bitrix\Main\EventResult(
            \Bitrix\Main\EventResult::ERROR,
            new \Bitrix\Main\Error('Вкажіть email для отримання підтвердження замовлення')
        );
    }

    $result = \Local\Validation\EmailValidator::validate($email);

    if (!$result->isValid()) {
        return new \Bitrix\Main\EventResult(
            \Bitrix\Main\EventResult::ERROR,
            new \Bitrix\Main\Error($result->getError())
        );
    }

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

Повна верифікація через посилання (для авторизованих)

При реєстрації або першому замовленні — надсилаємо посилання з токеном:

namespace Local\Validation;

class EmailVerificationService
{
    public static function sendVerification(int $userId, string $email): bool
    {
        $token = bin2hex(random_bytes(32));
        $exp   = time() + 86400; // 24 години

        // Зберігаємо токен
        $hlEntity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity(
            \Bitrix\Highloadblock\HighloadBlockTable::getById(EMAIL_VERIFY_HLBLOCK_ID)->fetch()
        );
        $hlEntity->getDataClass()::add([
            'UF_USER_ID'   => $userId,
            'UF_EMAIL'     => $email,
            'UF_TOKEN'     => $token,
            'UF_EXPIRES'   => \Bitrix\Main\Type\DateTime::createFromTimestamp($exp),
            'UF_CONFIRMED' => false,
        ]);

        // Надсилаємо лист
        $verifyUrl = 'https://' . SITE_SERVER_NAME . '/local/verify-email.php?token=' . $token;

        return \CEvent::Send('EMAIL_VERIFICATION', SITE_ID, [
            'EMAIL'      => $email,
            'VERIFY_URL' => $verifyUrl,
            'EXPIRES_AT' => date('d.m.Y H:i', $exp),
        ]);
    }

    public static function confirmToken(string $token): bool
    {
        $hlEntity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity(
            \Bitrix\Highloadblock\HighloadBlockTable::getById(EMAIL_VERIFY_HLBLOCK_ID)->fetch()
        );
        $dataClass = $hlEntity->getDataClass();

        $row = $dataClass::getRow([
            'filter' => [
                'UF_TOKEN'     => $token,
                'UF_CONFIRMED' => false,
                '>=UF_EXPIRES' => new \Bitrix\Main\Type\DateTime(),
            ],
            'select' => ['ID', 'UF_USER_ID'],
        ]);

        if (!$row) return false;

        $dataClass::update($row['ID'], ['UF_CONFIRMED' => true]);

        // Оновлюємо прапор у профілі користувача
        \CUser::Update($row['UF_USER_ID'], ['UF_EMAIL_VERIFIED' => 'Y']);

        return true;
    }
}

Сторінка підтвердження email

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

$token  = trim($_GET['token'] ?? '');
$result = false;

if (strlen($token) === 64 && preg_match('/^[a-f0-9]+$/', $token)) {
    $result = \Local\Validation\EmailVerificationService::confirmToken($token);
}

// Редирект із повідомленням
if ($result) {
    LocalRedirect('/personal/?email_verified=1');
} else {
    LocalRedirect('/personal/?email_verify_error=1');
}

Валідація на стороні клієнта

Швидкий зворотний зв'язок до відправки форми — перевіряємо синтаксис і показуємо підказку:

const emailInput = document.querySelector('[name="ORDER_EMAIL"]');

emailInput?.addEventListener('blur', async () => {
    const email = emailInput.value.trim();
    if (!email) return;

    // Синтаксична перевірка на клієнті
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
        showFieldError(emailInput, 'Перевірте правильність email');
        return;
    }

    // Перевірка на сервері (MX + disposable)
    const res = await fetch('/local/ajax/validate-email.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email }),
    }).then(r => r.json());

    if (!res.valid) {
        showFieldError(emailInput, res.error);
    } else {
        clearFieldError(emailInput);
    }
});
// /local/ajax/validate-email.php
\Bitrix\Main\Application::getInstance()->initializeExtended();

$email  = json_decode(file_get_contents('php://input'), true)['email'] ?? '';
$result = \Local\Validation\EmailValidator::validate($email);

header('Content-Type: application/json');
echo json_encode(['valid' => $result->isValid(), 'error' => $result->getError()]);

Продуктивність

MX-запит через getmxrr() займає 50–500 мс. При повільному DNS-резолвері — до 2 секунд. Якщо це критично: кешуємо результат за доменом на 1 годину, виконуємо перевірку асинхронно (після введення email, не при сабміті форми).

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

Конфігурація Термін
Синтаксис + одноразові домени + MX 1–2 дні
+ верифікація через посилання в листі +2–3 дні
+ клієнтська валідація з AJAX +1 день