WooCommerce: авторизация пользователей по телефону с помощью SMS

Проблема: стандартная регистрация WooCommerce не поддерживает вход по телефону

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

Диагностика задачи

Проверьте, какой способ авторизации сейчас используется:

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

Если вы хотите заменить email на телефон и добавить SMS-подтверждение, то потребуется кастомизация или использование SMS-шлюза.

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

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

Для этого используем хуки WooCommerce и немного кода в functions.php вашей темы или в плагине:

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

add_action('woocommerce_register_form_start', 'add_phone_field_to_registration');
function add_phone_field_to_registration() {
    ?>
    <p class="form-row form-row-wide">
        <label for="reg_billing_phone">Номер телефона <span class="required">*</span></label>
        <input type="text" class="input-text" name="billing_phone" id="reg_billing_phone" value="<?php if (! empty($_POST['billing_phone'])) echo esc_attr($_POST['billing_phone']); ?>" />
    </p>
    <?php
}

Шаг 2. Сохраняем номер телефона при регистрации

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

Шаг 3. Реализуем отправку SMS с кодом подтверждения

Подключаем SMS-шлюз (например, Twilio, SMS.ru или другой). Пример функции отправки SMS через API SMS.ru:

function send_sms_code($phone, $code) {
    $api_id = 'ВАШ_API_ID_SMSRU';
    $message = 'Код подтверждения: ' . $code;
    $url = 'https://sms.ru/sms/send?api_id=' . $api_id . '&to=' . urlencode($phone) . '&msg=' . urlencode($message) . '&json=1';
    $response = wp_remote_get($url);
    if (is_wp_error($response)) return false;
    $body = json_decode(wp_remote_retrieve_body($response), true);
    return isset($body['status']) && $body['status'] == 'OK';
}

Шаг 4. Создаем логику проверки кода при входе

При вводе номера телефона генерируем и сохраняем код в сессию, отправляем SMS. Затем показываем форму для ввода кода и сверяем его. Пример генерации и проверки кода:

session_start();

// При отправке номера телефона
if (isset($_POST['phone_for_login'])) {
    $phone = sanitize_text_field($_POST['phone_for_login']);
    $code = wp_rand(100000, 999999);
    $_SESSION['sms_code'] = $code;
    $_SESSION['sms_phone'] = $phone;
    send_sms_code($phone, $code);
    // Отобразить форму ввода кода
}

// При отправке кода
if (isset($_POST['sms_code_input'])) {
    if ($_POST['sms_code_input'] == $_SESSION['sms_code']) {
        // Авторизуем пользователя по номеру телефона
        $user = get_users(['meta_key' => 'billing_phone', 'meta_value' => $_SESSION['sms_phone'], 'number' => 1]);
        if ($user) {
            wp_set_current_user($user[0]->ID);
            wp_set_auth_cookie($user[0]->ID);
            wp_redirect(home_url());
            exit;
        } else {
            echo 'Пользователь с таким номером не найден';
        }
    } else {
        echo 'Неверный код подтверждения';
    }
}

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

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

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

  • Код не приходит по SMS: Проверьте правильность API ключа и баланс сервиса SMS, убедитесь в правильном формате номера телефона.
  • Сессия не сохраняется: Убедитесь, что session_start() вызывается в начале скрипта, не конфликтует с другими плагинами.
  • Пользователь не найден по телефону: Проверьте, что номер телефона сохранен корректно и совпадает по формату с вводимым.
  • Перенаправление после входа не работает: Проверьте wp_redirect и exit после него, чтобы не было вывода до редиректа.

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

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

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

МетодПлюсыМинусы
Использование плагина (например, "WooCommerce Phone Login")Быстрая установка, готовый функционал, поддержкаЧасто платные, ограниченная кастомизация, нагрузка на сайт
Своя реализация через API SMS и кастомный кодПолный контроль, кастомизация под проект, интеграция с любым APIТребует разработки, тестирования, поддержки безопасности
Использование внешних сервисов авторизации (OAuth, OTP)Высокая безопасность, быстрая авторизацияЗависимость от сторонних сервисов, сложность интеграции