# Yandex SmartCaptcha

{% hint style="success" %}
До 10 тысяч запросов в месяц бесплатно
{% endhint %}

## Создать капчу

1. В [консоли управления](https://console.yandex.cloud/) выберите каталог.
2. Выберите сервис **Yandex SmartCaptcha**.
3. Нажмите **Создать капчу**.

<div data-full-width="true"><figure><img src="/files/gwuaH0uLlsfbnBElrgCd" alt=""><figcaption></figcaption></figure></div>

4. Внесите нужные настройки, настройте внешний вид и нажмите Создать

<div data-full-width="true"><figure><img src="/files/gWnYwBje5gY9PyhbxgTp" alt=""><figcaption></figcaption></figure></div>

## Получить ключи капчи

1. Нажмите на имя капчи
2. На вкладке **Обзор** скопируйте значения полей **Ключ клиента** и **Ключ сервера**.

### Замена стандартной капчи на Yandex SmartCaptcha в формах модуля «Формы»

#### Интеграция на стороне клиента

Вставьте этот фрагмент перед закрывающим тегом в HTML-коде:

{% code fullWidth="true" %}

```html
<script src="https://smartcaptcha.cloud.yandex.ru/captcha.js" defer></script>
```

{% endcode %}

#### Интеграция на стороне сервера

В XSL-шаблон в тег вносим строку виджета каптчи там, где нужен показ:

{% code fullWidth="true" %}

```html
<div id="captcha-container" class="smart-captcha" data-sitekey="{/form/site_key}"
></div>
```

{% endcode %}

Когда пользователи отправляют форму со встроенной проверкой **Yandex SmartCaptcha**, вместе с прочими данными вы получаете строку `smart-token`. Чтобы узнать, прошел ли пользователь проверку, отправьте GET-запрос. Если получили успешный ответ, то форма отправляется.

{% code lineNumbers="true" fullWidth="true" %}

```php
if (Core::moduleIsActive('form'))
{
  $oForm = Core_Entity::factory('Form', Core_Array::get(Core_Page::instance()->libParams, 'formId'));

  $Form_Controller_Show = new Form_Controller_Show($oForm);

  $xslName = Core_Array::get(Core_Page::instance()->libParams, 'formXsl');
  
  $sSecretKey = "xxx"; // Указывается Ключ сервера Yandex SmartCaptcha

  if (!is_null(Core_Array::getPost($oForm->button_name)))
  {
   if (Core_Array::getPost('smart-token'))
   {
    $token = Core_Array::getPost('smart-token');

    $sUrl = 'https://smartcaptcha.yandexcloud.net/validate?';
    
    $aParams = array(
      "secret" => $sSecretKey,
      "token" => $token,
      "ip" => $_SERVER['REMOTE_ADDR'],
	  ); 

    $Core_Http = Core_Http::instance('curl')
			->clear()
			->url($sUrl .  http_build_query($aParams))
			->execute();
			
    $data = $Core_Http->getDecompressedBody();
    $oAnswer = json_decode($data);    
    
    if (isset($oAnswer->status) && $oAnswer->status == 'ok')
    {
     $Form_Controller_Show
      ->values($_POST + $_FILES)
      // 0 — html, 1- plain text
      ->mailType(Core_Array::get(Core_Page::instance()->libParams, 'mailType'))
      ->mailXsl(
       Core_Entity::factory('Xsl')->getByName(Core_Array::get(Core_Page::instance()->libParams, 'notificationMailXsl'))
      )
      ->mailFromFieldName(Core_Array::get(Core_Page::instance()->libParams, 'emailFieldName'))
      ->process();
    }
    else
    {
    Core_Log::instance()->clear()
     ->status(Core_Log::$ERROR)
     ->write('Yandex SmartCaptcha: '. $data);
    }  
   }
   else
 {
  $Form_Controller_Show->addEntity(
  Core::factory('Core_Xml_Entity')
  ->name('errorId')
  ->value(0)
  );
 } 
  }

  $Form_Controller_Show
   ->xsl(
    Core_Entity::factory('Xsl')->getByName($xslName)
   )
   ->addEntity(
    Core::factory('Core_Xml_Entity')
     ->name('site_key')->value('yyy') // Указываете Ключ клиента Yandex SmartCaptcha
   )
   ->show();
}
```

{% endcode %}

### Замена стандартной капчи на Yandex SmartCaptcha в комментариях

Рассмотрим пример замены капчи для комментариев магазина. Для комментариев информационных систем точно такой же алгоритм.

#### Интеграция на стороне клиента

1\. Если у вас стандартные комментарии системы, то вставьте этот фрагмент перед закрывающим тегом \</head> в HTML-коде, указав вместо **your\_key** Ключ клиента, который был получен ранее:

```html
<script type="text/javascript">
    function onloadFunction() {
        if (window.smartCaptcha) {
            document.querySelectorAll('.smart-captcha').forEach((el, index) => {
                const widgetId = window.smartCaptcha.render(el, {
                    sitekey: 'your_key',
                });
            });
        }
    }
</script>

<script src="https://smartcaptcha.cloud.yandex.ru/captcha.js?render=onload&onload=onloadFunction" defer></script>
```

2. Если у вас комментарии без возможности ответов на уже добавленные комментарии, т.е. форма комментариев одна на странице, то вставьте этот фрагмент перед закрывающим тегом в HTML-коде:

```html
<script src="https://smartcaptcha.cloud.yandex.ru/captcha.js" defer></script>
```

#### Интеграция на стороне сервера

В XSL-шаблоне карточки товара, в темлейт формирующий форму комментариев, в тег вносим строку виджета каптчи там, где нужен показ:

```html
<!-- Showing captcha -->
<xsl:if test="/shop/use_captcha = 1 and /shop/siteuser_id = 0">
 <div id="captcha-container" class="smart-captcha" data-sitekey="{/shop/site_key}"
></div>
</xsl:if>
```

Когда пользователи отправляют форму со встроенной проверкой **Yandex SmartCaptcha**, вместе с прочими данными вы получаете строку `smart-token`. Чтобы узнать, прошел ли пользователь проверку, отправьте GET-запрос. Если получили успешный ответ, то форма отправляется.

Переходим в типовую динамическую страницу магазина и настраиваем её на обработку **Yandex SmartCaptcha**:

1. В коде типовой динамической страницы, после `$Shop_Controller_Show = Core_Page::instance()->object;` добавляем передачу в XML Ключ клиента, который был получен выше.

```php
// Yandex SmartCaptcha
$Shop_Controller_Show->addEntity(
  Core::factory('Core_Xml_Entity')
   ->name('site_key')->value('yyy') // Указываете Ключ клиента Yandex SmartCaptcha
);
```

2. Следующий шаг — замена стандартной обработки капчи. Для этого строку:

```php
if ($oInformationsystem->use_captcha == 0 || $siteuser_id > 0 || Core_Captcha::valid(Core_Array::getPost('captcha_id', '', 'str'), Core_Array::getPost('captcha', '', 'str')))
```

заменяется на:

```php
$sSecretKey = "xxx"; // Указывается Ключ сервера Yandex SmartCaptcha

$token = Core_Array::getPost('smart-token');

$sUrl = 'https://smartcaptcha.yandexcloud.net/validate?';
    
$aParams = array(
  "secret" => $sSecretKey,
  "token" => $token,
  "ip" => $_SERVER['REMOTE_ADDR'],
); 

$Core_Http = Core_Http::instance('curl')
			->clear()
			->url($sUrl .  http_build_query($aParams))
			->execute();
			
$data = $Core_Http->getDecompressedBody();
$oAnswer = json_decode($data);    

if (isset($oAnswer->status) && $oAnswer->status == 'ok')
// тут уже код который был
```

где в переменной `$sSecretKey` указывается Ключ сервера, который был получен вместе с ключом клиента при регистрации в Yandex SmartCaptcha.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://support.morozovpimnev.ru/poleznosti/yandex-smartcaptcha.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
