WooCommerce: установка авторизации по телефону без SMS-провайдеров

Диагностика проблемы: почему нужны альтернативы SMS-провайдерам

Многие интернет-магазины на WooCommerce хотят реализовать авторизацию по телефону, но без использования платных SMS-провайдеров. Это может быть вызвано желанием избежать затрат, задержек с доставкой SMS или ограничениями по региону. При этом стандартные плагины либо требуют подключения к внешним сервисам, либо не обеспечивают достаточную безопасность.

Основная задача — реализовать подтверждение входа и регистрации по номеру телефона с минимальными затратами и без внешних SMS-сервисов.

Пошаговое решение: как реализовать авторизацию по телефону без SMS-провайдеров

1. Использование Email для отправки кода подтверждения вместо SMS

Самый простой способ — отправлять одноразовый код подтверждения на Email, связанный с номером телефона, или на Email, введённый пользователем. Это снимает зависимость от SMS и позволяет использовать встроенную функцию WordPress wp_mail().

2. Добавление поля телефон в форму регистрации WooCommerce

Для начала расширим форму регистрации, чтобы пользователь вводил телефон:

add_action('woocommerce_register_form_start', function() {
    ?>
    <p class="form-row form-row-wide">
        <label for="reg_billing_phone">Телефон <span class="required">*</span></label>
        <input type="tel" class="input-text" name="billing_phone" id="reg_billing_phone" value="" required />
    </p>
    <?php
});

3. Валидация и сохранение номера телефона

Проверяем, что номер введён и сохраняем его в метаданные пользователя:

add_action('woocommerce_register_post', function($username, $email, $validation_errors) {
    if (empty($_POST['billing_phone']) || !preg_match('/^\+?\d{10,15}$/', $_POST['billing_phone'])) {
        $validation_errors->add('billing_phone_error', 'Введите корректный номер телефона.');
    }
}, 10, 3);

add_action('woocommerce_created_customer', function($customer_id) {
    if (!empty($_POST['billing_phone'])) {
        update_user_meta($customer_id, 'billing_phone', sanitize_text_field($_POST['billing_phone']));
    }
});

4. Генерация и хранение одноразового кода (OTP)

Создадим функцию генерации 6-значного кода и сохраним его в пользовательском мета с ограничением по времени:

function generate_otp($user_id) {
    $otp = wp_rand(100000, 999999);
    update_user_meta($user_id, '_login_otp', $otp);
    update_user_meta($user_id, '_login_otp_expiry', time() + 300); // 5 минут
    return $otp;
}

5. Отправка OTP на Email при попытке входа

Перехватим процесс логина и отправим код на email пользователя с указанным номером телефона:

add_action('wp_authenticate', function($username) {
    $user = get_user_by('login', $username);
    if ($user) {
        $otp = generate_otp($user->ID);
        $email = $user->user_email;
        $subject = 'Ваш код для входа';
        $message = "Ваш код подтверждения для входа: $otp. Код действителен 5 минут.";
        wp_mail($email, $subject, $message);
        // Можно добавить логику временной блокировки входа до ввода OTP
    }
});

6. Создание формы для ввода OTP и проверка кода

Добавим отдельную страницу или форму для ввода OTP и сравним введённый код с сохранённым, проверяя срок действия:

function verify_otp($user_id, $input_otp) {
    $saved_otp = get_user_meta($user_id, '_login_otp', true);
    $expiry = get_user_meta($user_id, '_login_otp_expiry', true);
    if (!$saved_otp || !$expiry) return false;
    if (time() > $expiry) return false;
    if ($input_otp == $saved_otp) {
        delete_user_meta($user_id, '_login_otp');
        delete_user_meta($user_id, '_login_otp_expiry');
        return true;
    }
    return false;
}

Проверка результата после внедрения

  • Зарегистрируйтесь новым пользователем, убедитесь, что номер телефона сохраняется и валидируется.
  • Попробуйте войти под этим пользователем — проверьте, что на связанный email приходит код OTP.
  • Введите код на странице подтверждения и убедитесь, что вход разрешён.
  • Попробуйте ввести неправильный или просроченный код — вход должен запрещаться.

Частые ошибки и как их исправить

  • Код OTP не приходит на email: проверьте работу wp_mail(), настройте SMTP или плагин для отправки почты (например, WP Mail SMTP).
  • Номер телефона не сохраняется: убедитесь, что поле billing_phone есть в форме и правильно обрабатывается в хуках сохранения.
  • Код OTP не совпадает или постоянно истекает: проверьте логику генерации и удаления кода, а также корректность сравнения.
  • Пользователь может войти без ввода OTP: реализуйте блокировку авторизации до проверки OTP, например, через фильтр authenticate.

Практические советы по безопасности и производительности

  • Не храните OTP в открытом виде — для усиления безопасности можно хранить хэш кода.
  • Ограничьте количество попыток ввода OTP, чтобы избежать перебора.
  • Используйте HTTPS для защиты передачи кода.
  • Для почтовых отправок используйте SMTP-серверы с авторизацией для повышения надежности доставки.
  • Удаляйте устаревшие OTP через крон или при успешном вводе.

Сравнение вариантов реализации авторизации по телефону без SMS

МетодОписаниеПлюсыМинусы
Код на Email (через wp_mail()) Отправка OTP на email, связанный с телефоном Без доп. затрат, быстро реализуется Зависит от email, не подходит если нет email
Временные ссылки на телефон (через URL) Отправка ссылки с токеном на email, подтверждающая вход Удобно, не требует ввода кода Нужно корректно обрабатывать безопасность токена
Использование внешних мессенджеров (Telegram, WhatsApp) Отправка кода через бота или чат Отделение от SMS, часто бесплатно Сложнее в реализации, требует интеграции
Как сделать автоматическую разблокировку пользователей в WordPress после блокировки
02.04.2026
WooCommerce: как установить автоматическое блокирование пользователей при подозрительной активности
14.07.2026
WordPress установка и настройка OAuth2 сервера: пошаговое руководство с примерами кода
30.12.2025
WordPress OTP авторизация через SMS и Email: настройка и примеры кода
14.12.2025
WooCommerce: автоматическое отключение подписки и удаление пользователя при отмене
17.07.2026