WooCommerce: как реализовать авторизацию через OTP без SMS-провайдеров

Что такое OTP-авторизация без SMS-провайдеров и зачем она нужна в WooCommerce

Одноразовый пароль (OTP) часто используется для повышения безопасности входа. В WooCommerce стандартно OTP отправляется по SMS через сторонних провайдеров, что влечет за собой дополнительные расходы и сложности с настройкой. Альтернатива — реализовать OTP без SMS, используя email или генерацию кода локально, что снижает затраты и упрощает интеграцию.

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

  • Высокая стоимость SMS-рассылок при большом числе клиентов.
  • Необходимость регистрации и настройки аккаунтов у сторонних провайдеров.
  • Зависимость от стабильности API провайдера.
  • Задержки в доставке сообщений, влияющие на удобство пользователя.

Пошаговое решение: реализация OTP через email в WooCommerce

1. Генерация одноразового кода при попытке входа

При вводе email на странице входа мы создаем случайный шестизначный код, сохраняем его в пользовательских мета и отправляем на email.

add_action('wp_ajax_nopriv_send_otp_email', 'send_otp_email_callback');
function send_otp_email_callback() {
    $user_email = sanitize_email($_POST['email']);
    if (!is_email($user_email)) {
        wp_send_json_error('Неверный email');
    }

    $user = get_user_by('email', $user_email);
    if (!$user) {
        wp_send_json_error('Пользователь не найден');
    }

    $otp_code = wp_rand(100000, 999999);
    update_user_meta($user->ID, '_otp_code', $otp_code);
    update_user_meta($user->ID, '_otp_code_time', time());

    $subject = 'Ваш одноразовый код для входа';
    $message = 'Ваш код: ' . $otp_code . ". Срок действия 10 минут.";
    wp_mail($user_email, $subject, $message);

    wp_send_json_success('Код отправлен');
}

2. Валидация кода и вход пользователя

Проверяем, совпадает ли введенный пользователем код с сохраненным и не истек ли срок его действия (10 минут). Если все верно — авторизуем пользователя.

add_action('wp_ajax_nopriv_verify_otp_login', 'verify_otp_login_callback');
function verify_otp_login_callback() {
    $user_email = sanitize_email($_POST['email']);
    $otp_input = sanitize_text_field($_POST['otp']);

    if (!is_email($user_email) || empty($otp_input)) {
        wp_send_json_error('Неверные данные');
    }

    $user = get_user_by('email', $user_email);
    if (!$user) {
        wp_send_json_error('Пользователь не найден');
    }

    $saved_otp = get_user_meta($user->ID, '_otp_code', true);
    $otp_time = (int) get_user_meta($user->ID, '_otp_code_time', true);

    if (!$saved_otp || !$otp_time || time() - $otp_time > 600) { // 600 секунд = 10 минут
        wp_send_json_error('Код истек или не найден');
    }

    if ($otp_input !== $saved_otp) {
        wp_send_json_error('Неверный код');
    }

    // Удаляем код после успешной проверки
    delete_user_meta($user->ID, '_otp_code');
    delete_user_meta($user->ID, '_otp_code_time');

    wp_clear_auth_cookie();
    wp_set_current_user($user->ID);
    wp_set_auth_cookie($user->ID);

    wp_send_json_success('Успешный вход');
}

3. Добавление интерфейса на страницу входа WooCommerce

Встраиваем поля для email и OTP, а также кнопки для отправки кода и входа с проверкой.

add_action('woocommerce_login_form', 'add_otp_login_fields');
function add_otp_login_fields() {
    ?>
    <p class="form-row form-row-wide">
        <label for="otp_email">Email <span class="required">*</span></label>
        <input type="email" class="input-text" name="otp_email" id="otp_email" autocomplete="email" />
    </p>
    <p class="form-row form-row-wide">
        <button type="button" id="send_otp_code">Отправить код</button>
    </p>
    <p class="form-row form-row-wide">
        <label for="otp_code">Код OTP <span class="required">*</span></label>
        <input type="text" class="input-text" name="otp_code" id="otp_code" autocomplete="one-time-code" />
    </p>
    <p class="form-row form-row-wide">
        <button type="button" id="verify_otp_login">Войти по коду</button>
    </p>
    <script>
    jQuery(function($) {
        $('#send_otp_code').on('click', function() {
            var email = $('#otp_email').val();
            $.post(ajaxurl, { action: 'send_otp_email', email: email }, function(response) {
                alert(response.data || response.data);
            });
        });
        $('#verify_otp_login').on('click', function() {
            var email = $('#otp_email').val();
            var otp = $('#otp_code').val();
            $.post(ajaxurl, { action: 'verify_otp_login', email: email, otp: otp }, function(response) {
                if (response.success) {
                    location.reload();
                } else {
                    alert(response.data || 'Ошибка');
                }
            });
        });
    });
    </script>
    <?php
}

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

  • Откройте страницу входа WooCommerce, введите email зарегистрированного пользователя.
  • Нажмите кнопку «Отправить код», проверьте почту – должен прийти шестизначный OTP.
  • Введите полученный код в поле «Код OTP» и нажмите «Войти по коду».
  • Если код верный и не просрочен, произойдет вход в аккаунт без пароля.

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

  • Не приходит письмо с кодом: проверьте настройки почты на сервере, используйте SMTP-плагин для надежной отправки.
  • Код всегда считается неверным: убедитесь, что вы используете правильный email, и код совпадает с тем, что пришел на email; проверьте, не превышен ли таймаут 10 минут.
  • Ajax-запросы не работают: убедитесь, что ajaxurl определен в JS (в админке он есть по умолчанию, для фронтенда нужно подключать локализацию скрипта).
  • Пользователь не авторизуется после проверки кода: проверьте, что функции wp_set_current_user и wp_set_auth_cookie вызываются корректно и нет конфликтов с другими плагинами авторизации.

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

  • Ограничьте количество запросов на отправку OTP с одного IP или email за определенный промежуток времени.
  • Используйте HTTPS для защиты передачи данных.
  • Храните коды OTP в мета-полях с префиксом, чтобы избежать коллизий с другими данными.
  • Удаляйте коды после их использования или по истечении срока действия.
  • Для улучшения UX добавьте таймер обратного отсчета для повторной отправки кода.

Сравнение вариантов реализации OTP в WooCommerce

МетодПлюсыМинусыТребования
OTP через SMS-провайдерыВысокая надежность доставки, знакомый формат для пользователейСтоимость, настройка, зависимость от сторонних сервисовАккаунт у SMS-провайдера, API ключи
OTP через Email (локальная генерация)Бесплатно, просто внедрять, не требует сторонних сервисовЗависимость от почтового сервера, может попадать в спамКорректно настроенный email сервер, SMTP
Локальная генерация и ввод кода без отправки (например, через приложение)Максимальная безопасность, отсутствие сетевых задержекСложно для пользователей, требует отдельное приложениеДополнительное ПО для пользователей
WooCommerce: автоматическое удаление пользователя при отмене подписки
05.06.2026
WooCommerce: автоматическое блокирование пользователей при подозрительной активности
16.06.2026
WooCommerce: автоматическое отключение подписки и удаление пользователя при отмене
17.07.2026
WooCommerce: автоматическое удаление пользователя при отмене подписки
23.06.2026
WooCommerce: автоматическое удаление пользователя при отмене подписки
20.05.2026