Это классический вариант: каптча видна в форме, и человек проходит её до отправки.
Ниже даю готовый блок для functions.php и тег для Contact Form 7.
Что нужно
Установлен и включён Contact Form 7
Ключи Yandex SmartCaptcha: sitekey и secret
Куда вставлять код
Я открываю functions.php активной темы
и вставляю блок ниже целиком. Если старый вариант уже стоит, просто заменяю его.
Полный код для functions.php
// Yandex Smart Captcha для Contact Form 7 - тег [yandex_captcha]
if (!defined('YANDEX_SMARTCAPTCHA_SITEKEY')) {
define('YANDEX_SMARTCAPTCHA_SITEKEY', 'ваш_клиентский_ключ');
}
if (!defined('YANDEX_SMARTCAPTCHA_SECRET')) {
define('YANDEX_SMARTCAPTCHA_SECRET', 'ваш_серверный_ключ');
}
add_action('wpcf7_before_send_mail', 'yandex_smart_captcha_verify', 10, 3);
function yandex_smart_captcha_verify($contact_form, &$abort = false, $submission = null) {
$submission = WPCF7_Submission::get_instance();
if (!$submission) {
return;
}
$smart_captcha_token = isset($_POST['smart-token']) ? sanitize_text_field(wp_unslash($_POST['smart-token'])) : '';
if ($smart_captcha_token === '') {
$submission->set_status('spam');
$submission->set_response('Пройдите проверку каптчи');
$abort = true;
return;
}
// POST https://captcha-api.yandex.ru/validate (без /v1/ - иначе 404)
$url = 'https://captcha-api.yandex.ru/validate';
$response = wp_remote_post($url, [
'timeout' => 10,
'body' => [
'secret' => YANDEX_SMARTCAPTCHA_SECRET,
'token' => $smart_captcha_token,
'ip' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '',
],
]);
if (is_wp_error($response) || (int) wp_remote_retrieve_response_code($response) !== 200) {
$submission->set_status('spam');
$submission->set_response('Ошибка проверки каптчи');
$abort = true;
return;
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if (!is_array($body) || !isset($body['status']) || $body['status'] !== 'ok') {
$submission->set_status('spam');
$submission->set_response('Каптча не пройдена');
$abort = true;
}
}
add_action('wpcf7_init', 'kpv_add_yandex_captcha_cf7_tag');
function kpv_add_yandex_captcha_cf7_tag() {
if (function_exists('wpcf7_add_form_tag')) {
wpcf7_add_form_tag('yandex_captcha', 'kpv_yandex_captcha_tag_handler', ['nameless' => true]);
} elseif (function_exists('wpcf7_add_shortcode')) {
wpcf7_add_shortcode('yandex_captcha', 'kpv_yandex_captcha_tag_handler');
}
}
function kpv_yandex_captcha_tag_handler($tag) {
$uid = 'ysc-token-' . wp_generate_password(12, false, false);
$sitekey = YANDEX_SMARTCAPTCHA_SITEKEY;
return sprintf(
'<div class="form__captcha"><span class="wpcf7-form-control-wrap yandex-captcha-wrap" data-token-field="%1$s">'
. '<div class="smart-captcha" data-sitekey="%2$s" data-token-field="%1$s"></div>'
. '<input type="hidden" name="smart-token" id="%1$s" value="" />'
. '</span></div>',
esc_attr($uid),
esc_attr($sitekey)
);
}
add_action('wp_enqueue_scripts', 'kpv_yandex_captcha_inline_style', 20);
function kpv_yandex_captcha_inline_style() {
wp_add_inline_style('main', '.form__captcha{margin-bottom:20px;}');
}
add_action('wp_footer', 'kpv_yandex_captcha_scripts', 20);
function kpv_yandex_captcha_scripts() {
if (is_admin()) {
return;
}
if (!defined('WPCF7_VERSION')) {
return;
}
?>
<script src="https://smartcaptcha.yandexcloud.net/captcha.js" defer></script>
<script>
(function () {
function renderAll() {
if (!window.smartCaptcha || typeof window.smartCaptcha.render !== 'function') {
return false;
}
document.querySelectorAll('.smart-captcha[data-sitekey]').forEach(function (el) {
if (el.getAttribute('data-ysc-rendered')) {
return;
}
var tokenId = el.getAttribute('data-token-field');
var input = tokenId ? document.getElementById(tokenId) : null;
window.smartCaptcha.render(el, {
sitekey: el.getAttribute('data-sitekey'),
hl: 'ru',
callback: function (token) {
if (input) {
input.value = token;
}
}
});
el.setAttribute('data-ysc-rendered', '1');
});
return true;
}
function tick() {
if (renderAll()) {
return;
}
setTimeout(tick, 50);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', tick);
} else {
tick();
}
})();
</script>
<?php
}
Что писать в форме CF7
В редакторе формы добавляю тег:
[yandex_captcha]
Пример целиком:
[text* your-name placeholder "Имя"]
[tel* your-phone placeholder "Телефон"]
[submit "Отправить"]
[yandex_captcha]
Проверка
- Откройте страницу с формой
Обновляю страницу с очисткой кэша через Ctrl+F5.
- Отправка без каптчи
Проверяю, что без каптчи отправка блокируется сообщением вроде «Пройдите проверку каптчи».
- Пройдите каптчу и отправьте
Прохожу каптчу и смотрю, что письмо и статус CF7 проходят штатно.
| Элемент | Роль |
|---|---|
| [yandex_captcha] | Показывает виджет и добавляет hidden-поле smart-token |
| wpcf7_before_send_mail | На сервере проверяет токен через API Яндекса |
| captcha-api.yandex.ru/validate | URL проверки, важно использовать без /v1/ |
Безопасность ключей
Я храню ключи не в теме, а в wp-config.php —
так при смене темы ничего не теряется:
define('YANDEX_SMARTCAPTCHA_SITEKEY', 'ваш_клиентский_ключ');
define('YANDEX_SMARTCAPTCHA_SECRET', 'ваш_серверный_ключ');
В этом варианте виджет всегда перед глазами.
Если хотите без чекбокса, берите мою статью про invisible SmartCaptcha.
Комментарии
Пока нет комментариев — можете написать первый.