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

Проблема: как реализовать авторизацию по телефону без сторонних SMS-сервисов

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

Диагностика задачи: что нужно учесть при реализации

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

Пошаговое решение: реализация авторизации по телефону с подтверждением через email

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

Для регистрации и входа расширим формы WooCommerce, добавим поле phone_number и обработаем его.

add_action('woocommerce_register_form_start', function() {
    echo '<p class="form-row form-row-wide"><label for="reg_phone_number">Телефонный номер <span class="required">*</span></label><input type="text" class="input-text" name="phone_number" id="reg_phone_number" value="' . ( isset( $_POST['phone_number'] ) ? esc_attr( $_POST['phone_number'] ) : '' ) . '" /></p>';
});

add_action('woocommerce_login_form', function() {
    echo '<p class="form-row form-row-wide"><label for="login_phone_number">Телефонный номер</label><input type="text" class="input-text" name="phone_number" id="login_phone_number" value="' . ( isset( $_POST['phone_number'] ) ? esc_attr( $_POST['phone_number'] ) : '' ) . '" /></p>';
});

2. Валидация и сохранение телефона при регистрации

Проверяем поле и сохраняем телефон в метаданных пользователя.

add_action('woocommerce_register_post', function($username, $email, $validation_errors) {
    if ( empty( $_POST['phone_number'] ) ) {
        $validation_errors->add('phone_number_error', 'Пожалуйста, введите телефонный номер.');
    } elseif ( ! preg_match('/^[0-9]{10,15}$/', $_POST['phone_number']) ) {
        $validation_errors->add('phone_number_format_error', 'Введите корректный телефонный номер (только цифры, 10-15 символов).');
    }
    return $validation_errors;
}, 10, 3);

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

3. Авторизация по телефону с подтверждением через email (временный код)

Реализуем механизм, при котором пользователь вводит телефон, получает на email ссылку с временным токеном для входа.

Шаги:

  • Проверяем номер телефона, ищем пользователя по метаданным.
  • Генерируем одноразовый токен, сохраняем в user_meta с временем истечения.
  • Отправляем email с ссылкой на вход, содержащей токен.
  • При переходе по ссылке проверяем токен и авторизуем пользователя.
function send_login_link_by_email($phone_number) {
    $users = get_users([
        'meta_key' => 'phone_number',
        'meta_value' => $phone_number,
        'number' => 1,
    ]);
    if (empty($users)) {
        return new WP_Error('no_user', 'Пользователь с таким номером не найден.');
    }
    $user = $users[0];
    $token = wp_generate_password(20, false);
    update_user_meta($user->ID, 'login_token', $token);
    update_user_meta($user->ID, 'login_token_expiry', time() + 900); // 15 минут

    $login_url = add_query_arg([
        'phone_login_token' => $token,
        'user_id' => $user->ID
    ], site_url('/')); // можно заменить на страницу входа

    wp_mail($user->user_email, 'Ссылка для входа', 'Перейдите по ссылке для входа: ' . $login_url);
    return true;
}

add_action('init', function() {
    if ( isset($_GET['phone_login_token'], $_GET['user_id']) ) {
        $user_id = intval($_GET['user_id']);
        $token = sanitize_text_field($_GET['phone_login_token']);
        $saved_token = get_user_meta($user_id, 'login_token', true);
        $expiry = get_user_meta($user_id, 'login_token_expiry', true);

        if ($token === $saved_token && time() <= $expiry) {
            wp_set_auth_cookie($user_id);
            delete_user_meta($user_id, 'login_token');
            delete_user_meta($user_id, 'login_token_expiry');
            wp_redirect(home_url());
            exit;
        } else {
            wp_die('Ссылка недействительна или истекла.');
        }
    }
});

4. Форма для запроса ссылки на вход по телефону

Добавим простую форму на страницу входа, чтобы пользователь мог запросить ссылку.

add_action('woocommerce_login_form', function() {
    echo '<form method="post" style="margin-top:20px;">'
       . '<p><label for="phone_login">Телефон для входа по ссылке</label><br/>'
       . '<input type="text" name="phone_login" id="phone_login" required /></p>'
       . '<p><input type="submit" name="send_phone_login_link" value="Получить ссылку" /></p>'
       . '</form>';

    if ( isset($_POST['send_phone_login_link']) && !empty($_POST['phone_login']) ) {
        $result = send_login_link_by_email(sanitize_text_field($_POST['phone_login']));
        if (is_wp_error($result)) {
            echo '<p style="color:red;">' . esc_html($result->get_error_message()) . '</p>';
        } else {
            echo '<p style="color:green;">Ссылка для входа отправлена на ваш email.</p>';
        }
    }
});

Проверка результата

  • Зарегистрируйтесь с номером телефона, проверьте сохранение в профиле (в базе в usermeta).
  • На странице входа введите номер телефона в форму запроса ссылки.
  • Проверьте, что на email пользователя приходит письмо со ссылкой.
  • Перейдите по ссылке, убедитесь, что происходит вход без пароля.
  • Проверьте, что после входа токен удаляется и ссылка не работает повторно.

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

  • Пользователь с номером не найден. — проверьте, что номер сохраняется в usermeta, формат совпадает, нет пробелов.
  • Письмо не приходит. — проверьте конфигурацию wp_mail, используйте SMTP-плагин.
  • Ссылка не работает или всегда выдает ошибку. — проверьте, что токен и время истечения корректно сохраняются и сравниваются.
  • Форма запроса ссылки не отображается. — убедитесь, что хук woocommerce_login_form активен и код не конфликтует с другими плагинами.

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

  • Ограничьте количество запросов на отправку ссылки по телефону с одного IP за промежуток времени.
  • Используйте SSL для защиты передачи токенов по ссылке.
  • Очищайте устаревшие токены периодически с помощью wp_cron.
  • Используйте фильтры и проверки для предотвращения SQL-инъекций и XSS, особенно для номеров телефонов.

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

МетодТребованияПлюсыМинусы
SMS через провайдерАккаунт у SMS-провайдера, смс-отправкаПрямое подтверждение номера, быстрый входСтоимость, зависимость от сервиса, сложность настройки
Подтверждение через emailДоступ к email, настройки почты WordPressБез затрат на SMS, простота реализацииЗависимость от email, задержки доставки
Временные ссылки с токеномХранение токенов, отправка emailБезопасно, легко отменить токеныТребует внимательности к срокам и безопасности
WordPress REST API: создание кастомной аутентификации по токену
25.01.2026
WordPress авторизация без cookie: решение проблем и примеры кода
06.02.2026
Как защитить REST API WordPress от неавторизованных запросов
16.02.2026
WordPress двухфакторная аутентификация: локальное решение с примером кода
21.12.2025
Как отключить REST API для неавторизованных пользователей в WordPress
18.01.2026