БЕЗОПАСНОСТЬ / reCaptcha V3 в корзине

Заметка создана: 25 февраля 2025 г.

Подключаем в head скрипт reCaptcha

<script src="https://www.google.com/recaptcha/api.js" async="" defer=""></script>

и добавляем в макет корзины

  <script>
 function onSubmit(token) {
     document.getElementById("cmsm-form-cart").submit();
   }
  </script>

Ниже приведена ТДС корзины на одной странице. Если использовать данный вариант, то в XSL шаблонах для Адреса доставки, Доставок и Платёжных систем закомментировать тег form 

<!--form-->
....
<!--/form-->

В XSL шаблон Платёжных систем кнопка отправки заказа примет вид

<button type="submit" class="btn btn-blue btn-lg g-recaptcha" data-sitekey="ключ-reCaptcha" data-callback="onSubmit" data-action="submit">ОТПРАВИТЬ ЗАКАЗ →</button>

PHP . ТДС корзины с обработкой reCaptcha

<?php


$Shop_Cart_Controller_Show = Core_Page::instance()->object;


$oShop = $Shop_Cart_Controller_Show->getEntity();


Shop_Payment_System_Handler::checkAfterContent($oShop);


Shop_Delivery_Handler::checkAfterContent($oShop);


// ------------------------------------------------
// Вывод информации о статусе платежа после его совершения и перенаправления с платежной системы
// ------------------------------------------------
if (isset($_REQUEST['payment']) || (isset($_GET['action']) && ($_GET['action'] == 'PaymentSuccess' || $_GET['action'] == 'PaymentFail')) || isset($_REQUEST['pg_order_id']))
{
     // Получаем ID заказа
     if (isset($_REQUEST['order_id']))
     {
          $order_id = intval(Core_Array::getRequest('order_id'));
     }
     //от Яндекса
     elseif(isset($_GET['orderNumber']))
     {
          $order_id = intval(Core_Array::getGet('orderNumber'));
     }
     //от PayPal
     elseif(isset($_REQUEST['invoice']))
     {
          $oShop_Order = Core_Entity::factory('Shop_Order')->getByGuid(Core_Array::getRequest('invoice'));
          $order_id = $oShop_Order ? intval($oShop_Order->id) : NULL;
     }
     //от IntellectMoney
     elseif(isset($_REQUEST['orderId']))
     {
          $order_id = intval(Core_Array::getGet('orderId'));
     }
     //от Platron
     elseif(isset($_REQUEST['pg_order_id']))
     {
          $order_id = intval(Core_Array::getRequest('pg_order_id'));
     }
     else
     {
          $order_id = intval(Core_Array::getRequest('InvId'));
     }


     $oShop_Order = Core_Entity::factory('Shop_Order')->find($order_id);


     if (Core::moduleIsActive('siteuser'))
     {
          $siteuser_id = 0;


          $oSiteuser = Core_Entity::factory('Siteuser')->getCurrent();
          if ($oSiteuser)
          {
               $siteuser_id = $oSiteuser->id;
          }
     }
     else
     {
          $siteuser_id = FALSE;
     }


     // Если заказ принадлежит текущему авторизированному пользователю
     if ($oShop_Order->siteuser_id == $siteuser_id)
     {
          if (Core_Array::getRequest('payment') == 'success' || Core_Array::getRequest('action') == 'PaymentSuccess' || Core_Array::getRequest('pg_order_id') > 0)
          {
               ?><h1>Подтверждение платежа</h1>
               <p>Спасибо, информация об оплате заказа <strong>№ <?php echo $oShop_Order->invoice?></strong>
получена.</p>
               <?php
          }
          else
          {
               ?><h1>Платеж не получен</h1>
               <p>К сожалению при оплате заказа <strong>№ <?php echo $oShop_Order->invoice?></strong> произошла ошибка.</p>
               <?php
          }
     }
     // Для случаев, когда отключен модуль "Пользователи сайта"
     elseif ($siteuser_id === FALSE)
     {
          ?><h1>Подтверждение платежа</h1>
          <p>Благодарим за посещение нашего магазина!</p>
          <?php
     }
     else
     {
          ?><h1>Ошибка</h1>
          <p>Неверный номер заказа!</p>
          <?php
     }


     // Прерываем выполнение типовой динамической страницы
     return TRUE;
}

$xslName = Core_Array::get(Core_Page::instance()->libParams, 'cartXsl');


Core_Session::start();


if (Core_Array::getPost('oneStepCheckout'))
{
    // Сбрасываем информацию о последнем заказе
    $_SESSION['last_order_id'] = 0;


    // Оформление в один шаг
    $Shop_Cart_Controller = Shop_Cart_Controller::instance();
    $aShop_Cart = $Shop_Cart_Controller->getAll($oShop);
    foreach ($aShop_Cart as $oShop_Cart)
    {
        $Shop_Cart_Controller
            ->shop_item_id($oShop_Cart->shop_item_id)
            ->delete();
    }


    $shop_item_id = intval(Core_Array::getRequest('shop_item_id'));


    if ($shop_item_id)
    {
        Shop_Cart_Controller::instance()
            ->shop_item_id($shop_item_id)
            ->quantity(floatval(Core_Array::getRequest('count', 1)))
            ->add();
    }


    $_SESSION['hostcmsOrder'] = array();


    $_SESSION['hostcmsOrder']['shop_country_id'] = intval(Core_Array::getPost('shop_country_id', 0));
    $_SESSION['hostcmsOrder']['shop_country_location_id'] = intval(Core_Array::getPost('shop_country_location_id', 0));
    $_SESSION['hostcmsOrder']['shop_country_location_city_id'] = intval(Core_Array::getPost('shop_country_location_city_id', 0));
    $_SESSION['hostcmsOrder']['shop_country_location_city_area_id'] = intval(Core_Array::getPost('shop_country_location_city_area_id', 0));
    $_SESSION['hostcmsOrder']['postcode'] = Core_Str::stripTags(strval(Core_Array::getPost('postcode')));
    $_SESSION['hostcmsOrder']['address'] = Core_Str::stripTags(strval(Core_Array::getPost('address')));
    $_SESSION['hostcmsOrder']['house'] = Core_Str::stripTags(strval(Core_Array::getPost('house')));
    $_SESSION['hostcmsOrder']['flat'] = Core_Str::stripTags(strval(Core_Array::getPost('flat')));
    $_SESSION['hostcmsOrder']['surname'] = Core_Str::stripTags(strval(Core_Array::getPost('surname')));
    $_SESSION['hostcmsOrder']['name'] = Core_Str::stripTags(strval(Core_Array::getPost('name')));
    $_SESSION['hostcmsOrder']['patronymic'] = Core_Str::stripTags(strval(Core_Array::getPost('patronymic')));
    $_SESSION['hostcmsOrder']['phone'] = Core_Str::stripTags(strval(Core_Array::getPost('phone')));
    $_SESSION['hostcmsOrder']['email'] = Core_Str::stripTags(strval(Core_Array::getPost('email')));
    $_SESSION['hostcmsOrder']['description'] = Core_Str::stripTags(strval(Core_Array::getPost('description')));


    // Additional order properties
    $_SESSION['hostcmsOrder']['properties'] = array();


    $oShop_Order_Property_List = Core_Entity::factory('Shop_Order_Property_List', $oShop->id);


    $aProperties = $oShop_Order_Property_List->Properties->findAll();
    foreach ($aProperties as $oProperty)
    {
        // Св-во может иметь несколько значений
        $aPropertiesValue = Core_Array::getPost('property_' . $oProperty->id);


        if (!is_null($aPropertiesValue))
        {
            !is_array($aPropertiesValue) && $aPropertiesValue = array($aPropertiesValue);
            foreach ($aPropertiesValue as $sPropertyValue)
            {
                $_SESSION['hostcmsOrder']['properties'][] = array($oProperty->id, $sPropertyValue);
            }
        }
    }


    $shop_delivery_condition_id = strval(Core_Array::getPost('shop_delivery_condition_id', 0));


    if (is_numeric($shop_delivery_condition_id))
    {
        $_SESSION['hostcmsOrder']['shop_delivery_condition_id'] = intval($shop_delivery_condition_id);


        $oShop_Delivery_Condition = Core_Entity::factory('Shop_Delivery_Condition', $_SESSION['hostcmsOrder']['shop_delivery_condition_id']);
        $_SESSION['hostcmsOrder']['shop_delivery_id'] = $oShop_Delivery_Condition->shop_delivery_id;
    }


    $_POST['step'] = 4;
}


// Проверяем наличие товара в корзины
$Shop_Cart_Controller = Shop_Cart_Controller::instance();
$aShop_Cart = $Shop_Cart_Controller->getAll($oShop);


switch (Core_Array::getPost('recount') || !count($aShop_Cart) ? 0 : Core_Array::getPost('step'))
{
     // Окончание оформления заказа
     case 4:
          // Сбрасываем информацию о последнем заказе
          $_SESSION['last_order_id'] = 0;
         
          // Заполнение данных доставки
          $_SESSION['hostcmsOrder']['shop_country_id'] = intval(Core_Array::getPost('shop_country_id', 0));
          $_SESSION['hostcmsOrder']['shop_country_location_id'] = intval(Core_Array::getPost('shop_country_location_id', 0));
          $_SESSION['hostcmsOrder']['shop_country_location_city_id'] = intval(Core_Array::getPost('shop_country_location_city_id', 0));
          $_SESSION['hostcmsOrder']['shop_country_location_city_area_id'] = intval(Core_Array::getPost('shop_country_location_city_area_id', 0));
          $_SESSION['hostcmsOrder']['postcode'] = strval(Core_Array::getPost('postcode'));
          $_SESSION['hostcmsOrder']['address'] = strval(Core_Array::getPost('address'));
          $_SESSION['hostcmsOrder']['surname'] = strval(Core_Array::getPost('surname'));
          $_SESSION['hostcmsOrder']['name'] = strval(Core_Array::getPost('name'));
          $_SESSION['hostcmsOrder']['patronymic'] = strval(Core_Array::getPost('patronymic'));
          $_SESSION['hostcmsOrder']['company'] = strval(Core_Array::getPost('company'));
          $_SESSION['hostcmsOrder']['phone'] = strval(Core_Array::getPost('phone'));
          $_SESSION['hostcmsOrder']['fax'] = strval(Core_Array::getPost('fax'));
          $_SESSION['hostcmsOrder']['email'] = strval(Core_Array::getPost('email'));
          $_SESSION['hostcmsOrder']['description'] = strval(Core_Array::getPost('description'));
          $_SESSION['hostcmsOrder']['tin'] = strval(Core_Array::getPost('tin'));
          $_SESSION['hostcmsOrder']['kpp'] = strval(Core_Array::getPost('kpp'));


$_SERVER['send_emails'] = false;
$_SESSION['hostcmsOrder']['company'] = '0';

// RECAPTCHA

if (isset($_POST['g-recaptcha-response'])) {
    $captcha_token = $_POST['g-recaptcha-response'];
    $captcha_action = 'submit';
    
    $url = 'https://www.google.com/recaptcha/api/siteverify';
    $params = [
        'secret' => 'секретный-ключ-reCaptcha',
        'response' => $captcha_token,
        'remoteip' => $_SERVER['REMOTE_ADDR']
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    
    $response = curl_exec($ch);
    if(!empty($response)) $decoded_response = json_decode($response);
    
    //$success = false;
    
    if ($decoded_response && $decoded_response->success && 
        $decoded_response->action == $captcha_action && 
        $decoded_response->score > 0.5) 
    {
        $_SESSION['hostcmsOrder']['company'] = $decoded_response->score;
        $_SERVER['send_emails'] = true;
    }        
}
if ($_SERVER['send_emails'] == false) {
    $_SESSION['hostcmsOrder']['surname'] = 'SPAM ' . $_SESSION['hostcmsOrder']['surname'];
}

          // Additional order properties
          $_SESSION['hostcmsOrder']['properties'] = array();


          $oShop_Order_Property_List = Core_Entity::factory('Shop_Order_Property_List', $oShop->id);


          $aProperties = $oShop_Order_Property_List->Properties->findAll();
          foreach ($aProperties as $oProperty){
               // Св-во может иметь несколько значений
               $aPropertiesValue = Core_Array::getPost('property_' . $oProperty->id);


               if (!is_null($aPropertiesValue))
               {
                    !is_array($aPropertiesValue) && $aPropertiesValue = array($aPropertiesValue);
                    foreach ($aPropertiesValue as $sPropertyValue)
                    {
                         $_SESSION['hostcmsOrder']['properties'][] = array($oProperty->id, $sPropertyValue);
                    }
               }
          }
          //~~ Заполнение данных доставки
    
          // Выбор условия доставки
          $shop_delivery_condition_id = strval(Core_Array::getPost('shop_delivery_condition_id', 0));


          if (is_numeric($shop_delivery_condition_id))
          {
               $_SESSION['hostcmsOrder']['shop_delivery_condition_id'] = intval($shop_delivery_condition_id);
          }
          else
          {
               $_SESSION['hostcmsOrder']['shop_delivery_condition_id'] = 0;


               // в shop_delivery_condition_id тогда "123#", ID элемента массива в сессии, в котором
               // хранится стоимость доставки, налог, название специфичного условия доставки
               list($shopDeliveryInSession) = explode('#', $shop_delivery_condition_id);


               if (isset($_SESSION['hostcmsOrder']['deliveries'][$shopDeliveryInSession]))
               {
                    $aTmp = $_SESSION['hostcmsOrder']['deliveries'][$shopDeliveryInSession];


                    $_SESSION['hostcmsOrder']['shop_delivery_id'] = $aTmp['shop_delivery_id'];
                    $_SESSION['hostcmsOrder']['shop_delivery_price'] = $aTmp['price'];
                    $_SESSION['hostcmsOrder']['shop_delivery_rate'] = $aTmp['rate'];
                    $_SESSION['hostcmsOrder']['shop_delivery_name'] = $aTmp['name'];
               }
          }
          //~~ Выбор условия доставки
    
          // Выбор формы оплаты
          $shop_payment_system_id = $_SESSION['hostcmsOrder']['shop_payment_system_id'] = intval(Core_Array::getPost('shop_payment_system_id', 0));


          // Если выбрана платежная система
          if ($_SESSION['hostcmsOrder']['shop_payment_system_id'])
          {
               Shop_Payment_System_Handler::factory(
                    Core_Entity::factory('Shop_Payment_System', $shop_payment_system_id)
               )
               ->orderParams($_SESSION['hostcmsOrder'])
               ->execute();
          }
          else
          {
               ?><h1>Ошибка! Не указана ни одна платежная система.</h1><?php
          }
          //~~ Выбор формы оплаты
     break;    
     // Адрес доставки
     case 1:
     // Способ доставки
     case 2:
     // Форма оплаты
     case 3:
     default:
          echo '<form method="post" action="./" id="cmsm-form-cart">';
          echo '<scr'.strtolower('I').'pt>';
          echo '$(function(){
               $("#cmsm-form-cart").on("change", "select[name=shop_country_id], select[name=shop_country_location_id], select[name=shop_country_location_city_id], select[name=shop_country_location_city_area_id], input[name=postcode], input[name=coupon_text]", function(){
                    $.loadingScreen("show"); // Крутилка         
                    $.ajax({
                         url: "./",
                         type: "GET",
                         data: ({"CMSMajaxLoadDelivery" : 1, "shop_country_id" : $("select[name=shop_country_id] :selected").val(), "shop_country_location_id" : $("select[name=shop_country_location_id] :selected").val(), "shop_country_location_city_id" : $("select[name=shop_country_location_city_id] :selected").val(), "shop_country_location_city_area_id" : $("select[name=shop_country_location_city_area_id] :selected").val(), "postcode" : $("input[name=postcode]").val(), "coupon_text" : $("input[name=coupon_text]").val()}),
                         dataType: "html",
                         success: function(html){
                              $("#shop-delivery-block").empty().append(html);
                              $.loadingScreen("hide"); // Убираем крутилку
                              $("input[name=shop_delivery_condition_id]").change();
                         }
                    });
                    return true;
               });
              
               $("#cmsm-form-cart").on("change", "input[name=shop_delivery_condition_id]", function(){
                    $.loadingScreen("show"); // Крутилка         
                    $.ajax({
                         url: "./",
                         type: "GET",
                         data: ({"CMSMajaxLoadPayment" : 1, "shop_delivery_condition_id" : $("input[name=shop_delivery_condition_id]:checked").val()}),
                         dataType: "html",
                         success: function(html){
                              $("#shop-payment-block").empty().append(html);
                              $.loadingScreen("hide"); // Убираем крутилку
                         }
                    });
                    return true;
               });
              
               if ($("select[name=shop_country_id]").change())
                    $("input[name=shop_delivery_condition_id]").change();
          });
          ';
          echo '</sc'.'ri'.strtolower('PT').'>';
          // Корзина
          $Shop_Cart_Controller_Show
               ->couponText(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'coupon_text'))
               ->xsl(
                    Core_Entity::factory('Xsl')->getByName($xslName)
               )
               ->itemsProperties(TRUE)
               ->show();
         
          // Корзина не пуста


          if (count($aShop_Cart)){
         echo ' <div class="container"><h3><b>Оформление заказа</b></h3><div class="order row">';
         echo '<div id="shop-address-block" class="col-12">';
               // Адрес доставки
               $Shop_Address_Controller_Show = new Shop_Address_Controller_Show($oShop);
               $Shop_Address_Controller_Show->xsl(
                         Core_Entity::factory('Xsl')->getByName(
                              Core_Array::get(Core_Page::instance()->libParams, 'deliveryAddressXsl')
                         )
                    )
                    ->show();
                echo '</div>';


               echo '<div id="shop-delivery-block" class="col-12 col-md-6">';
               // Способ доставки
               $Shop_Delivery_Controller_Show = new Shop_Delivery_Controller_Show($oShop);
               $Shop_Delivery_Controller_Show
                    ->shop_country_id(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'shop_country_id'))
                    ->shop_country_location_id(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'shop_country_location_id'))
                    ->shop_country_location_city_id(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'shop_country_location_city_id'))
                    ->shop_country_location_city_area_id(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'shop_country_location_city_area_id'))
                    ->couponText(Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'coupon_text'))
                    ->setUp()
                    ->xsl(
                         Core_Entity::factory('Xsl')->getByName(
                              Core_Array::get(Core_Page::instance()->libParams, 'deliveryXsl')
                         )
                    )
                    ->show();
               echo '</div>';
              
               echo '<div id="shop-payment-block" class="col-12 col-md-6">';
               // Форма оплаты
               $oShop_Delivery_Condition = Core_Entity::factory('Shop_Delivery_Condition', Core_Array::get(Core_Array::get($_SESSION, 'hostcmsOrder', array()), 'shop_delivery_condition_id'));


               $Shop_Payment_System_Controller_Show = new Shop_Payment_System_Controller_Show($oShop);
               $Shop_Payment_System_Controller_Show
                    ->shop_delivery_id($oShop_Delivery_Condition->shop_delivery_id)
                    ->xsl(
                         Core_Entity::factory('Xsl')->getByName(
                              Core_Array::get(Core_Page::instance()->libParams, 'paymentSystemXsl')
                         )
                    )
                    ->show();
               echo '</div>';
          }


          echo '</div></div></form>';
}


// Блок авторизации пользователя
/*
if (Core::moduleIsActive('siteuser'))
{
     $oSiteuser = Core_Entity::factory('Siteuser')->getCurrent();


     if (is_null($oSiteuser))
     {
          // Авторизация
          $Siteuser_Controller_Show = new Siteuser_Controller_Show(
               Core_Entity::factory('Siteuser')
          );


          $Siteuser_Controller_Show
               ->location(Core::$url['path'])
               ->xsl(
                    Core_Entity::factory('Xsl')->getByName(Core_Array::get(Core_Page::instance()->libParams, 'userAuthorizationXsl'))
               )
               ->show();


          // Регистрация
          $Siteuser_Controller_Show = new Siteuser_Controller_Show(
               Core_Entity::factory('Siteuser')
          );


          $Siteuser_Controller_Show->xsl(
                    Core_Entity::factory('Xsl')->getByName(Core_Array::get(Core_Page::instance()->libParams, 'userRegistrationXsl'))
               )
               ->location(Core::$url['path'])
               ->fastRegistration(TRUE)
               ->itemsProperties(TRUE)
               ->properties(TRUE)
               //->showMaillists(TRUE)
               ->show();
     }
}
*/