Налаштування верифікації 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 день |







