Проблема: необходимость подтверждения заказа по телефону в WooCommerce
В стандартной комплектации WooCommerce нет встроенного механизма подтверждения заказов по телефону. Для магазинов с высокой стоимостью товаров или услуг это важный шаг для снижения риска мошенничества и повышения качества обслуживания. В статье разберём, как добавить поле подтверждения телефона при оформлении заказа и отправлять SMS с кодом подтверждения, а также блокировать оформление до успешной верификации.
Диагностика задачи
Перед внедрением решения стоит понять, что именно нужно:
- Добавить обязательное поле для ввода номера телефона при оформлении заказа.
- Отправить одноразовый код подтверждения на указанный номер.
- Запросить ввод кода в том же или следующем шаге оформления заказа.
- Подтвердить заказ только при успешном вводе кода.
Также важно выбрать сервис для отправки SMS (например, sms.ru или Twilio) и подготовить API-ключи.
Пошаговое решение: добавление подтверждения телефона через кастомный код
1. Добавляем поле телефон с подтверждением в форму оформления заказа
В файле functions.php вашей темы или в плагине добавьте следующий код для добавления поля телефона и поля для ввода кода подтверждения:
add_filter('woocommerce_checkout_fields', 'wprus_add_phone_confirmation_field');
function wprus_add_phone_confirmation_field($fields) {
$fields['billing']['billing_phone']['required'] = true;
$fields['billing']['phone_confirmation_code'] = array(
'type' => 'text',
'label' => 'Код подтверждения телефона',
'required' => true,
'class' => array('form-row-wide'),
'priority' => 110,
);
return $fields;
}2. Обработка отправки кода SMS
Добавим AJAX-обработчик, который будет отправлять SMS с кодом на указанный номер. Для этого используем стандартный WordPress AJAX-хук.
add_action('wp_ajax_send_phone_confirmation_code', 'wprus_send_phone_confirmation_code');
add_action('wp_ajax_nopriv_send_phone_confirmation_code', 'wprus_send_phone_confirmation_code');
function wprus_send_phone_confirmation_code() {
if (!isset($_POST['phone'])) {
wp_send_json_error('Номер телефона не передан');
}
$phone = sanitize_text_field($_POST['phone']);
// Генерируем 6-значный код
$code = wp_rand(100000, 999999);
// Сохраняем код и номер в сессии
WC()->session->set('phone_confirmation_code', $code);
WC()->session->set('phone_confirmation_number', $phone);
// Здесь отправка SMS через выбранный сервис
// Пример с sms.ru
$api_key = 'ВАШ_API_КЛЮЧ';
$message = 'Ваш код подтверждения: ' . $code;
$sms_ru_url = 'https://sms.ru/sms/send';
$response = wp_remote_post($sms_ru_url, array(
'body' => array(
'api_id' => $api_key,
'to' => $phone,
'msg' => $message,
'json' => 1
)
));
if (is_wp_error($response)) {
wp_send_json_error('Ошибка при отправке SMS');
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['status']) && $body['status'] == 'OK') {
wp_send_json_success('Код отправлен');
} else {
wp_send_json_error('Не удалось отправить код');
}
}3. Проверка кода при оформлении заказа
Добавим проверку, что введённый код совпадает с сохранённым в сессии и номер телефона не изменился:
add_action('woocommerce_checkout_process', 'wprus_validate_phone_confirmation_code');
function wprus_validate_phone_confirmation_code() {
$input_code = isset($_POST['phone_confirmation_code']) ? sanitize_text_field($_POST['phone_confirmation_code']) : '';
$input_phone = isset($_POST['billing_phone']) ? sanitize_text_field($_POST['billing_phone']) : '';
$session_code = WC()->session->get('phone_confirmation_code');
$session_phone = WC()->session->get('phone_confirmation_number');
if (empty($input_code) || empty($input_phone)) {
wc_add_notice('Пожалуйста, введите код подтверждения телефона', 'error');
return;
}
if ($input_phone !== $session_phone) {
wc_add_notice('Номер телефона изменён после отправки кода, пожалуйста, запросите код заново', 'error');
return;
}
if ($input_code != $session_code) {
wc_add_notice('Неверный код подтверждения телефона', 'error');
}
}4. Добавим кнопку для отправки кода и JS скрипт
В шаблоне оформления заказа (или с помощью woocommerce_after_checkout_billing_form) добавьте кнопку «Отправить код» и скрипт, который будет отправлять AJAX-запрос:
add_action('woocommerce_after_checkout_billing_form', 'wprus_add_send_code_button');
function wprus_add_send_code_button() {
?>
<button type="button" id="send-phone-code" class="button">Отправить код подтверждения</button>
<script>
jQuery(function($) {
$('#send-phone-code').on('click', function() {
var phone = $('#billing_phone').val();
if (!phone) {
alert('Введите номер телефона');
return;
}
$.ajax({
url: wc_checkout_params.ajax_url,
method: 'POST',
data: {
action: 'send_phone_confirmation_code',
phone: phone
},
success: function(response) {
if(response.success) {
alert('Код отправлен на номер ' + phone);
} else {
alert('Ошибка: ' + response.data);
}
},
error: function() {
alert('Ошибка при отправке запроса');
}
});
});
});
</script>
<?php
}Проверка результата после внедрения
Чтобы проверить работоспособность решения:
- Перейдите на страницу оформления заказа WooCommerce.
- Введите номер телефона и нажмите «Отправить код». Убедитесь, что SMS приходит на указанный номер.
- В поле «Код подтверждения телефона» введите полученный код.
- Попробуйте оформить заказ с правильным кодом — заказ должен успешно оформиться.
- Попробуйте оформить заказ с неправильным кодом или без ввода — должна появиться ошибка.
- Измените номер телефона после отправки кода, попробуйте оформить заказ — должна появиться ошибка о необходимости заново запросить код.
Частые ошибки и как их исправить
- Не отправляется SMS: Проверьте правильность API-ключа и настройки сервиса SMS, а также корректность номера телефона в международном формате.
- Код не сохраняется в сессии: Убедитесь, что сессия WooCommerce и PHP-сессии включены и работают корректно.
- Код не проверяется или ошибки не выводятся: Проверьте, что хук
woocommerce_checkout_processне конфликтует с другими плагинами, отключите кеширование на странице оформления заказа. - JS кнопка не работает: Убедитесь, что jQuery подключён и скрипт не вызывает ошибок в консоли браузера.
Практические советы по безопасности и производительности
- Не храните код подтверждения в базе данных без необходимости — используйте сессии.
- Ограничьте частоту отправки SMS, чтобы предотвратить спам и излишние расходы.
- Используйте проверку формата номера телефона на клиенте и сервере.
- Обрабатывайте ошибки API SMS-сервиса и логируйте их для диагностики.
- Минимизируйте количество AJAX-запросов и кешируйте страницу оформления заказа без форм.
Таблица сравнения вариантов реализации
| Вариант | Преимущества | Недостатки | Пример |
|---|---|---|---|
| Плагин SMS подтверждения | Быстрая настройка, поддержка разных сервисов | Может быть платным, ограниченная кастомизация | Clearfy Pro (частично) |
| Кастомный код с sms.ru | Полный контроль, адаптация под задачи | Требует навыков программирования, поддержка и доработка — на вас | Пример в статье |
| Внешние сервисы (Twilio и т.п.) | Надёжность, дополнительные функции (голосовые вызовы и др.) | Стоимость, сложность интеграции | Аналогично кастомному коду с другой API |