Диагностика задачи: зачем нужна авторизация через SMS в WooCommerce
Стандартная регистрация и авторизация в WooCommerce базируется на email и пароле. Однако для магазинов с быстрой конверсией, мобильной аудиторией или в случаях, когда email не обязателен, удобнее использовать авторизацию по номеру телефона с подтверждением через SMS. Это снижает порог входа и повышает лояльность пользователей.
Основные вопросы, которые нужно решить:
- Как получить и проверить номер телефона пользователя при регистрации и входе.
- Как отправить SMS с кодом подтверждения.
- Как проверить код и авторизовать пользователя.
- Как интегрировать это решение с WooCommerce без сторонних плагинов.
Как реализовать авторизацию через SMS в WooCommerce: пошаговое руководство
1. Добавляем поле для номера телефона в формы регистрации и входа
Для регистрации добавим поле с атрибутом required и проверкой на корректность номера.
add_action('woocommerce_register_form_start', function() {
?>
<p class="form-row form-row-wide">
<label for="reg_phone">Номер телефона <span class="required">*</span></label>
<input type="tel" class="input-text" name="phone" id="reg_phone" value="" required pattern="\+?\d{10,15}" placeholder="+79991234567" />
</p>
<?php
});2. Сохраняем номер телефона и проверяем уникальность
При регистрации нужно проверить, что номер не занят, и сохранить его в мета данных пользователя.
add_action('woocommerce_register_post', function($username, $email, $validation_errors) {
if (empty($_POST['phone']) || !preg_match('/^\+?\d{10,15}$/', $_POST['phone'])) {
$validation_errors->add('phone_error', 'Введите корректный номер телефона');
} else {
$phone = sanitize_text_field($_POST['phone']);
$users = get_users(array('meta_key' => 'phone', 'meta_value' => $phone));
if (!empty($users)) {
$validation_errors->add('phone_exists', 'Этот номер уже зарегистрирован');
}
}
}, 10, 3);
add_action('woocommerce_created_customer', function($customer_id) {
if (!empty($_POST['phone'])) {
update_user_meta($customer_id, 'phone', sanitize_text_field($_POST['phone']));
}
});3. Реализация отправки SMS с кодом подтверждения
Для отправки SMS используем внешний сервис (например, Twilio, SMS.ru, или любой другой с API). Ниже пример с псевдокодом для отправки через SMS.ru.
function send_sms_code($phone, $code) {
$api_id = 'ВАШ_API_ID';
$url = 'https://sms.ru/sms/send?api_id=' . $api_id . '&to=' . urlencode($phone) . '&msg=' . urlencode('Код подтверждения: ' . $code) . '&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 с кодом, который нужно ввести для авторизации.
add_action('woocommerce_login_form', function() {
?>
<p class="form-row form-row-wide">
<label for="login_phone">Номер телефона</label>
<input type="tel" name="login_phone" id="login_phone" class="input-text" required pattern="\+?\d{10,15}" placeholder="+79991234567"/>
</p>
<p class="form-row form-row-wide">
<label for="login_code">Код из SMS</label>
<input type="text" name="login_code" id="login_code" class="input-text" required maxlength="6" placeholder="Введите код"/>
</p>
<?php
});5. Обработка отправки кода и входа
При первом шаге отправляем код и сохраняем его в сессии или transient, при втором — проверяем код и выполняем вход.
add_action('wp_ajax_nopriv_send_sms_code', function() {
$phone = sanitize_text_field($_POST['phone']);
if (!preg_match('/^\+?\d{10,15}$/', $phone)) {
wp_send_json_error('Неверный формат номера');
}
$users = get_users(array('meta_key' => 'phone', 'meta_value' => $phone));
if (empty($users)) {
wp_send_json_error('Номер не зарегистрирован');
}
$code = rand(100000, 999999);
set_transient('sms_code_' . md5($phone), $code, 5 * MINUTE_IN_SECONDS);
if (send_sms_code($phone, $code)) {
wp_send_json_success('Код отправлен');
} else {
wp_send_json_error('Ошибка отправки SMS');
}
});
add_action('wp_ajax_nopriv_sms_login', function() {
$phone = sanitize_text_field($_POST['phone']);
$code = sanitize_text_field($_POST['code']);
$saved_code = get_transient('sms_code_' . md5($phone));
if ($saved_code !== $code) {
wp_send_json_error('Неверный код');
}
$users = get_users(array('meta_key' => 'phone', 'meta_value' => $phone));
if (empty($users)) {
wp_send_json_error('Пользователь не найден');
}
wp_clear_auth_cookie();
wp_set_current_user($users[0]->ID);
wp_set_auth_cookie($users[0]->ID);
delete_transient('sms_code_' . md5($phone));
wp_send_json_success('Вы успешно вошли');
});Проверка результата после внедрения авторизации через SMS
- Проверьте, что при регистрации номер телефона сохраняется и отображается в профиле пользователя.
- Попробуйте войти через форму с телефоном и получить SMS с кодом.
- Введя корректный код, убедитесь, что пользователь авторизован и перенаправлен на нужную страницу.
- Проверьте, что при вводе неверного кода доступ закрывается.
Частые ошибки и способы их исправления
- Номер телефона не сохраняется: проверьте, что поле
phoneкорректно обрабатывается и сохраняется вuser_meta. - Код не отправляется: убедитесь, что API ключи и параметры SMS-сервиса правильные, а сервер имеет доступ к внешнему API.
- Код не совпадает: проверьте, что транзиенты не удаляются преждевременно и время жизни кода достаточно.
- Пользователь не авторизуется после ввода кода: убедитесь, что функции
wp_set_auth_cookieиwp_set_current_userвызываются корректно.
Практические советы по безопасности и производительности
- Храните SMS-коды в transient с коротким временем жизни (5 минут максимум).
- Ограничьте количество попыток ввода кода для предотвращения перебора.
- Используйте HTTPS для защиты передачи данных формы.
- Кэшируйте ответы API SMS-сервиса, если это возможно, или используйте очередь для массовых отправок.
- Логируйте ошибки отправки SMS для оперативного реагирования.
Таблица сравнения способов реализации авторизации через SMS в WooCommerce
| Метод | Плюсы | Минусы | Особенности |
|---|---|---|---|
| Плагин (например, OTP Verification) | Быстрое внедрение, поддержка | Нагрузка, лишний код, зависимость | Простая настройка, минимум кода |
| Собственная реализация через API SMS | Гибкость, контроль, нет лишних функций | Требует навыков, больше времени | Полное управление логикой и интерфейсом |
| Внешний сервис с готовым виджетом | Простота, надежность | Зависимость от сервиса, стоимость | Интеграция через iframe или JS |