Настройка верификации email при заказе 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка верификации email при заказе 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1260
  • 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 Appointment Booking Widget for a Medical Center
    584
  • 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 день