Диагностика задачи: зачем подтверждать номер телефона в WooCommerce
В интернет-магазинах, построенных на WooCommerce, часто возникает потребность в подтверждении правильности номера телефона клиента. Это важно для связи с покупателем, доставки, а также для борьбы с мошенничеством. Стандартный WooCommerce не содержит функционала ввода и подтверждения номера телефона с кодом, поэтому необходимо добавить кастомное поле с валидацией и механизмом проверки.
Добавление поля ввода номера телефона и поля для кода подтверждения
Чтобы добавить два новых поля на страницу оформления заказа — номер телефона и код подтверждения — воспользуемся хуком woocommerce_checkout_fields. Поле телефон можно сделать обязательным, а поле кода — скрытым до момента отправки кода.
add_filter('woocommerce_checkout_fields', function($fields) {
$fields['billing']['billing_phone'] = [
'label' => 'Номер телефона',
'required' => true,
'class' => ['form-row-wide'],
'type' => 'tel',
'priority' => 25,
'custom_attributes' => [
'pattern' => '\\+?\\d{10,15}',
'title' => 'Введите номер телефона в формате +71234567890',
],
];
$fields['billing']['billing_phone_confirmation_code'] = [
'label' => 'Код подтверждения',
'required' => true,
'class' => ['form-row-wide'],
'type' => 'text',
'priority' => 26,
'custom_attributes' => [
'maxlength' => 6,
'autocomplete' => 'off',
],
];
return $fields;
});После добавления полей нужно вывести кнопку «Отправить код» рядом с полем телефона с помощью JavaScript и AJAX (подробнее ниже).
Реализация отправки и проверки кода подтверждения через AJAX
Для отправки кода на телефон используем сторонний SMS API (например, Twilio, SMS.ru, или любой другой, который у вас есть). В этом примере покажу пример AJAX-запроса и серверного обработчика, который сгенерирует код и отправит его, а также сохранит в сессию для последующей проверки.
JavaScript для кнопки отправки кода
jQuery(function($){
var timer;
$('#billing_phone').after('<button type="button" id="send_sms_code" class="button" style="margin-left:10px;">Отправить код</button>');
$('#send_sms_code').on('click', function(){
var phone = $('#billing_phone').val();
if(!phone.match(/^\\+?\\d{10,15}$/)) {
alert('Введите корректный номер телефона в международном формате');
return;
}
$(this).attr('disabled', true).text('Отправляем...');
$.post(woocommerce_params.ajax_url, {
action: 'send_sms_code',
phone: phone
}, function(response){
if(response.success) {
alert('Код отправлен');
$('#billing_phone_confirmation_code').focus();
} else {
alert('Ошибка: ' + response.data);
}
$('#send_sms_code').attr('disabled', false).text('Отправить код');
});
});
});PHP: обработчик AJAX для отправки кода
add_action('wp_ajax_send_sms_code', 'send_sms_code_callback');
add_action('wp_ajax_nopriv_send_sms_code', 'send_sms_code_callback');
function send_sms_code_callback() {
if(empty($_POST['phone'])) {
wp_send_json_error('Телефон не указан');
}
$phone = sanitize_text_field($_POST['phone']);
// Генерируем случайный 6-значный код
$code = wp_rand(100000, 999999);
// Сохраняем код и телефон в сессию (или в пользовательские мета, если пользователь авторизован)
if(!session_id()) session_start();
$_SESSION['phone_confirmation_code'] = $code;
$_SESSION['phone_for_confirmation'] = $phone;
// TODO: отправка SMS через API
// Пример: send_sms($phone, "Ваш код подтверждения: $code");
// Для демонстрации отправим код в ответе (уберите в продакшене!)
wp_send_json_success('Код отправлен');
}Валидация кода подтверждения при оформлении заказа
Чтобы проверить, что введённый код совпадает с отправленным, используем хук woocommerce_checkout_process:
add_action('woocommerce_checkout_process', function() {
if(!session_id()) session_start();
$input_code = isset($_POST['billing_phone_confirmation_code']) ? sanitize_text_field($_POST['billing_phone_confirmation_code']) : '';
$input_phone = isset($_POST['billing_phone']) ? sanitize_text_field($_POST['billing_phone']) : '';
if(empty($input_code)) {
wc_add_notice('Пожалуйста, введите код подтверждения телефона.', 'error');
return;
}
if(empty($_SESSION['phone_confirmation_code']) || empty($_SESSION['phone_for_confirmation'])) {
wc_add_notice('Код подтверждения не был отправлен. Пожалуйста, отправьте код.', 'error');
return;
}
if($input_phone !== $_SESSION['phone_for_confirmation']) {
wc_add_notice('Номер телефона изменился после отправки кода. Пожалуйста, отправьте код заново.', 'error');
return;
}
if($input_code != $_SESSION['phone_confirmation_code']) {
wc_add_notice('Неверный код подтверждения телефона.', 'error');
return;
}
// При успешном подтверждении можно очистить код из сессии
unset($_SESSION['phone_confirmation_code']);
unset($_SESSION['phone_for_confirmation']);
});Проверка результата после внедрения
- Перейдите на страницу оформления заказа WooCommerce.
- В поле Номер телефона введите номер в формате +71234567890.
- Нажмите кнопку Отправить код.
- Убедитесь, что появилось уведомление об успешной отправке кода (для теста код можно вывести в лог или в ответ AJAX).
- Введите полученный код в поле Код подтверждения.
- Попытайтесь оформить заказ. Ошибок быть не должно, если код введён правильно.
- Попробуйте ввести неправильный код или изменить номер телефона после отправки — должны появляться ошибки.
Частые ошибки и как их исправить
- Код не отправляется, кнопка не работает: убедитесь, что подключен jQuery и параметр
woocommerce_params.ajax_urlдоступен. Проверьте консоль браузера на ошибки JS. - Сессия PHP не стартует: если в вашем серверном окружении сессии отключены, замените хранение кода на пользовательские мета или transient.
- Код всегда неверный: проверьте, что сессия сохраняет и читает одинаковые значения, и что поле телефона не изменяется после отправки кода.
- SMS не отправляются: интегрируйте реальный SMS API, проверьте ключи и настройки сервиса.
Практические советы по безопасности и производительности
- Не храните коды подтверждения в базе данных без шифрования, используйте сессию или transient с ограничением по времени.
- Ограничьте количество отправок кода на один номер и IP, чтобы предотвратить спам и злоупотребления.
- Используйте HTTPS для защиты данных при передаче.
- Внедрите таймер повторной отправки кода (например, 60 секунд), чтобы пользователь не мог нажать кнопку слишком часто.
- Минимизируйте количество запросов и используйте кеширование, если применимо.
Сравнение вариантов реализации подтверждения телефона в WooCommerce
| Метод | Плагин | Код | Плюсы | Минусы |
|---|---|---|---|---|
| Плагин SMS подтверждения | Twilio SMS Verification | Нет | Готовое решение, поддержка и обновления | Стоимость, зависимость от стороннего сервиса |
| Кастомный код с AJAX | Нет | Да | Полный контроль, без лишних функций | Требует разработки и поддержки, необходим сервис SMS |
| Плагин с интеграцией SMS API | WP SMS, WooSMS | Минимум | Быстрая настройка, много функций | Иногда избыточно, могут быть баги |