...
...
...
...
Требования к реализации: https://drive.google.com/drive/folders/1-5jVX72qmAzMWxW1bU5UJTbTmVI0F0BX?usp=sharing
Требование к значению аттрибута name для форм ( Required )
Платформа "понимает" только определенные значения аттрибутов элементов формы. Поэтому, требование №1 - правильные значения аттрибута name на форме.
Эквайринговая или дебетовая форма
...
Наименование
...
Значение аттрибута name
...
Обязательное поле
...
Пример
...
Номер карты
...
card_num или card_num1, card_num2, card_num3, card_num4
...
Да
...
<input type="text" name="card_num" value="" />
...
Срок действия, месяц
...
card_exp_month
...
Да
...
<select name="card_exp_month">
<option value=""
selected="selected">Select</option>
<option value="01">01</option>
........
<option value="12">12</option>
</select>
...
Срок действия, год
...
card_exp_year
...
Да
...
<select name="card_exp_year">
<option value=""
selected="selected">Select</option>
<option
value="2018">2018</option>
.........
<option
value="2028">2028</option>
</select>
...
Код проверки подлинности
...
cvv2
...
Да
...
<input type="password" name="cvv2"
value="" maxlength="3" />
...
Имя владельца карты
...
first_name
...
Нет
...
<input type="text" name="first_name"
value="" />
...
Фамилия владельца карты
...
last_name
...
Нет
...
<input type="text" name="last_name"
value="" />
...
Адрес
...
address
...
Нет
...
<input type="text" name="address"
value="" />
...
Город
...
city
...
Нет
...
<input type="text" name="city"
value="" />
...
Почтовый код
...
zip
...
Нет
...
<input type="text" name="zip"
value="" />
...
Страна
...
country
...
Нет
...
<select name="country">
<option value="">Select
please</option>
<option value="UA"
selected="selected">Ukraine</option>
......................
<option value="GB">United
Kingdom</option>
<option value="US">United States
of America</option>
</select>
...
Штат
...
state
...
Нет
...
<select name="state">
<option value="">Select
please</option>
<option value="NA"
selected="selected">Non
US/Canada/Australia</option>
<optgroup label="US States">
<option
value="WA">Washington</option>
</optgroup>
</select>
...
Телефон
...
phone
...
Нет
...
<input type="text" name="phone"
value="" />
...
...
...
Нет
...
<input type="text" name="email"
value="" />
Форма для оплаты в 1 клик
...
Наименование
...
Значение аттрибута name
...
Обязательное поле
...
Пример
...
Код проверки подлинности
...
cvv2
...
Да
...
<input type="password"
name="cvv2" value=""
maxlength="3" />
2. Валидация данных ( Required )
Необходимо иметь валидатор для проверки данных на форме. Необходимо выполнять, проверку номера карты по Алгоритму Луна https://ru.wikipedia.org/wiki/Алгоритм_Луна#:~:text=Алгоритм Лу́на (англ.,со стандартом ISO%2FIEC 7812.&text=Позволяет лишь с некоторой степенью,нахождения и исправления обнаруженной неточности. . Свой валидатор должен быть корректный и логичный, например, чтобы срок действия карты можно было указать не ранее сегодняшнего месяца и года. Или показывать ошибку, если пользователь ввел не весь номер карты а лишь частично.
Правильно:
...
После сабмита формы отображаются сообщения о неверных карточных данных. Или, при вводе карточных данных js валидатор проверяет их на правильность.
Неправильно:
...
После сабмита формы не отображаюся сообщения о ошибках: Expiration date меньше текущей даты, код проверки подлинности неверной длины, номер карты неверной длины.
3. Сабмит формы ( Required )
Если данные провалидированы и верны - форма должна сабмититься.
4. Место для отображения причины деклайна ( Required )
Необходим выделенный блок со стилем, где в случае деклайна, будет отображаться
причина отказа.
Правильно:
<div class="row">
<div class="span8 offset2">
<div class="alert alert-error msg-error">ALERT MESSAGE HERE</div>
</div>
</div>
5. Ресурсы формы ( Required )
Необходимо чтобы все ресурсы ( картинки, сss, js ) указанные на форме
присутствовали в архиве при создании задачи.
Неправильно:
<link type="text/css" rel="stylesheet" href="../resources/css/validator.css"
/>
...
6. Ссылки на внешние ресурсы( Optional ) На рассмотрении
По желанию заказчика использованиев внешних ресурсов, например, блок с
курсом валют на форме, js скрипт или другая информация могут быть размещены после
расмотрения.
Желательно:
<link type="text/css" rel="stylesheet" href="../resources/css/base.css" />
<script type="text/javascript" src="../resources/js/jquery.js"></script>
Нежелательно:
<link type="text/css" rel="stylesheet"
href="http://mysite.com/resources/css/base.css" />
<script type="text/javascript"
src="http://mysite.com/resources/js/myscript.js"></script>
7. Отображение информации на форме
На эквайринговой форме возможно отобразить следующую информацию:
Description - описание продукта
Amount - сумма операции
Currency - валюта операции
Order - клиентский идентификатор операции
Ext1.... Ext10 - дополнительные поля клиента
Company - Client:Personal information:Company name (заполняется призаведении
клиента)
На рекаринговой форме возможно отобразить следующую информацию:
Description - описание продукта
Amount - сумма операции
Currency - валюта операции
Order - клиентский идентификатор операции
Ext1.... ext10 -
Company - Client:Personal information:Company name (заполняется призаведении
клиента)
First Name - Имя владельца карты
Last Name - Фамилия владельца карты
Email - Email
Card - PAN в формате 6+4
Currency - Валюта операции
Пример исходного кода эквайринговой формы:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Payment Page</title>
<link type="text/css" rel="stylesheet"
href="../resources/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="../resources/css/bootstrapresponsive.min.css" />
<link type="text/css" rel="stylesheet" href="../resources/css/base.css"
/>
</head>
<body>
<!-- header -->
<div class="container" >
<div class="row">
<div class="span3 offset2">
<h1>Payment Form</h1>
</div>
<div class="span5">
<div class="language">
<ul class="inline">
<li><img id="en" lang="en_EN"
src="../resources/img/en.png" title="English" /></li>
<li><img id="de" lang="de_DE"
src="../resources/img/de.png" title="Deutsch" /></li>
<li><img id="fr" lang="fr_FR"
src="../resources/img/fr.png" title="Francais" /></li>
<li><img id="it" lang="it_IT"
src="../resources/img/it.png" title="Italiana" /></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="span8 offset2">
<hr>
</div>
</div>
</div>
<!-- form -->
<div class="container" >
<div class="row"><div class="span8 offset2"><div class="alert alerterror msg-error">Declined by processing</div></div></div>
<form action="" method="post" name="process" id="process">
<div class="row">
<div class="span8 offset2">
<div class="form-inline product">
</div>
</div>
</div>
<div class="row">
<div class="span8 offset2">
<legend>Enter your personal details</legend>
<div class="row">
<div class="span4">
<div class="form-horizontal form">
<label class="control-label"
for="first_name">First name</label>
<div class="controls"><input type="text"
name="first_name" value="John" /></div>
</div>
</div>
<div class="span4">
<div class="form-horizontal form">
<label class="control-label" for="last_name">Last
name</label>
<div class="controls"><input type="text"
name="last_name" value="Joe" /></div>
</div>
</div>
</div>
<div class="row">
<div class="span8">
<div class="form-horizontal form">
<label class="control-label"
for="address">Address</label>
<div class="controls" style="padding-right:
24px;"><input type="text" name="address" value="Str. Prermohi 12"
style="width: 100%;" /></div>
</div>
</div>
</div>
<div class="row">
<div class="span4">
<div class="form-horizontal form">
<label class="control-label"
for="city">City</label>
<div class="controls"><input type="text"
name="city" value="Gotham" /></div>
</div>
</div>
<div class="span4">
<div class="form-horizontal form">
<label class="control-label" for="zip">ZIP/Postal
code</label>
<div class="controls"><input type="text"
name="zip" value="24958" /></div>
</div>
</div>
</div>
<div class="row">
<div class="span4">
<div class="form-horizontal form">
<label class="control-label"
for="country">Country</label>
<div class="controls"><select name="country">
<option value="">Select please</option>
<option value="UA" selected="selected">Ukraine</option>
<option value="GB">United Kingdom</option>
<option value="US">United States of America</option>
</select></div>
</div>
</div>
<div class="span4">
<div class="form-horizontal form">
<label class="control-label"
for="state">State</label>
<div class="controls"><select name="state">
<option value="">Select please</option>
<option value="NA" selected="selected">Non US/Canada/Australia</option>
<optgroup label="US States">
<option value="WA">Washington</option>
</optgroup>
<optgroup label="Canadian Provinces">
<option value="BC">British Columbia</option>
</optgroup>
<optgroup label="Australian Territories">
<option value="VIC">Victoria</option>
</optgroup>
</select></div>
</div>
</div>
</div>
<div class="row">
<div class="span4">
<div class="form-horizontal form">
for="phone">Phone</label>
<label class="control-label"
<div class="controls"><input type="text"
name="phone" value="+380654124958" /></div>
</div>
</div>
<div class="span4">
<div class="form-horizontal form">
<label class="control-label" for="email">Email</label>
<div class="controls"><input type="text"
name="email" value="john_doe@mm.tt" /></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="span8 offset2">
<legend>Enter your card information</legend>
<div class="row">
<div class="span4">
<div class="form-horizontal form">
<div class="control-group">
<label class="control-label"
for="card_num">Card number</label>
<div class="controls"><input type="text"
name="card_num" value="" id="card_num" /></div>
</div>
<div class="control-group">
<label class="control-label"
for="card_exp_month">Expiration date</label>
<div class="controls">
<select name="card_exp_month"
id="card_exp_month" style="width: auto;">
<option value="" selected="selected">Select</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
<select name="card_exp_year"
id="card_exp_year" style="width: auto;">
<option value="" selected="selected">Select</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
<option value="2028">2028</option>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label"
for="email">CVC2/CVV2</label>
relative;">
<div class="controls" style="position:
<img class="info" id="info"
src="../resources/img/info.png" />
<input type="password" name="cvv2"
value="" maxlength="4" autocomplete="off" style="width: 30px;" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="span8 offset2">
<div class="form-actions submit">
<button id="sbmt" type="submit" class="btn btn-large btnprimary">PROCESS TRANSACTION</button>
</div>
</div>
</div>
</form> </div>
<!-- modal -->
<div id="info-modal" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close">?</button>
<h4>How to find the CVV / CVC on your credit card</h4>
</div>
<div class="modal-body">
<p>The CVV / CVC is used to help validate that a genuine card is
being used during a transaction. The credit card company uses those codes to
verify that the person making this purchase actually has the credit card in
their possession. It is required for online transactions starting on January
1st, 2003.</p>
<p>With a Visa or Master Card the CVV/CVC is a three-digit
security code printed on the back side of the card.</p>
<p style="text-align: center;"><img
src="../resources/img/card.jpg" /></p>
</div>
</div>
<!-- footer -->
<div class="clear"></div>
<div class="container"></div>
<script type="text/javascript" src="../resources/js/jquery.js"></script>
<script type="text/javascript" src="../resources/js/validator.js"></script>
<script type="text/javascript"
src="../resources/js/jquery.cookie.js"></script>
<script type="text/javascript"
src="../resources/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#en, #fr, #de, #ru, #ja, #nl, #it, #pt, #es, #da,
#tr').click(function() {
$.cookie('lang', $(this).attr('lang'), { path: '/' });
location.reload();
});
$('#info').click(function() {
$('#info-modal').modal('show');
});
$('#info-modal').find('.close').click(function() {
$('#info-modal').modal('hide');
});
$.validator.addMethod('phone', function(phone_number, element) {
phone_number = phone_number.replace(/\s+/g, '');
return this.optional(element) || phone_number.length > 9 &&
phone_number.match(/^\+?[0-9 ()-]{7,}$/);
}, "Please specify a valid phone number");
$().ready(function() {
$("#process").validate({
submitHandler: function(form) {
$("#sbmt").attr('disabled', 'disabled');
form.submit();
},
success: function(label) {
label.addClass("valid").append("<span></span>");
},
groups: {
username: "card_exp_month card_exp_year"
},
errorPlacement: function(error, element) {
if (element.attr("name") == "card_exp_month" ||
element.attr("name") == "card_exp_year")
error.insertAfter("#card_exp_year");
else
error.insertAfter(element);
},
rules: {
first_name: {
required: true,
minlength: 2
},
last_name: {
required: true,
minlength: 2
},
address: {
required: true,
minlength: 5
},
city: {
required: true,
minlength: 2
},
state: {
required: true
},
zip: {
required: true,
minlength: 2
},
country: {
required: true
},
phone: {
required: true,
phone: true
},
email: {
required: true,
email: true
},
card_num: {
required: true,
creditcard: true,
},
card_exp_month: {
required: true,
digits: true
},
card_exp_year: {
required: true,
digits: true
},
cvv2: {
required: true,
minlength: 3,
digits: true
}
},
characters"
messages: {
first_name: {
required: "Please enter valid first name",
minlength: "Your first name must consist of at least 2
characters"
},
last_name: {
required: "Please enter valid last name",
minlength: "Your last name must consist of at least 2
characters"
},
address: {
required: "Please enter your address",
minlength: "Your address must consist of at least 5
characters"
},
city: {
required: "Please enter your city",
minlength: "Your city must consist of at least 2
},
state: {
required: "Please select your state"
characters"
},
zip: {
required: "Please enter your zip/post-code",
minlength: "Your zip/post-code must consist of at least 2
},
country: {
required: "Please select your country"
},
phone: {
required: "Please enter your phone"
},
email: {
required: "Please enter your email address"
},
card_num: {
required: "Please enter your credit cadr number"
},
card_exp_month: {
required: "Please enter correct expiration date"
},
card_exp_year: {
required: "Please enter correct expiration date"
characters",
},
cvv2: {
required: "Please enter a valid card security code",
minlength: "Security code must consist of at least 3
number: "Please enter a valid number"
});
});
}
}
});
</script>
</body>
</html>
Пример исходного кода рекаринговой формы
Code Block |
---|
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Recurring page</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=0" />
<link rel="stylesheet" href="../resources/css/style.css">
</head>
<body>
<form action="" class="payment" method="post">
<div class="line">
<span class="name">Оплата</span>
<span class="price">1.01 USD</span>
</div>
<div class="error_payment"></div>
<div class="payment field">
<div class="payment control">
<div class="field_wrap">
<div class="namber_card">499999******0011</div>
</div>
<div class="error"></div>
</div>
</div>
<div class="payment field">
<div class="payment columns_rec">
<label class="payment label">Код CVV</label>
<div class="payment control">
<div class="field_wrap">
<input id="cvv" name="cvv2" autocomplete="off" class="payment input" type="tel" placeholder="XXX" maxlength="3" required>
</div>
<div class="error"></div>
</div>
</div>
</div>
<div class="payment action">
<button type="submit" class="btn" formnovalidate>Купити</button>
</div>
</form>
<script src="../resources/js/jquery-3.2.1.min.js"></script>
<script src="../resources/js/jquery.mask.min.js"></script>
<script src="../resources/js/jquery.creditCardValidator.js"></script>
<script src="../resources/js/js/main.js"></script>
</body>
</html> |
Пример исходного кода OTP формы
Code Block | ||
---|---|---|
| ||
<!DOCTYPE html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>Головна</title>
<link type="text/css" rel="stylesheet" href="../resources/css/style.css"/>
</head>
<body id="load" class="no-js">
<div class="remodal">
<div class="remodal-header">
<img src="../resources/img/modal-logo.png" class="modal-logo" />
<div class="remodal-header-right">
<img src="../resources/img/remodal_MC.png" />
<img src="../resources/img/remodal_visa.png" />
</div>
</div>
<form action="" method="post" name="remodal-transaction1" id="process" class="remodal-form">
<div>
<div id="modal1Title">Для завершення покупки введіть одноразовий пароль, який надійшов на номер Вашого мобільного телефону</div>
<p id="modal1Desc">Якщо пароль не надійшов в найближчі 5 хвилин зателефонуйте до Інформаційного центру Банку за телефонами: ---- (Безкоштовно з мобільних у межах України); Телефон для дзвінків із-за кордону--------------</p>
<div class="remodal-left">Торговець</div>
<div class="remodal-right" style="width: 250px;"></div>
<div class="remodal-left">Сума</div>
<div class="remodal-right">UAH 1.00</div>
<div class="remodal-left">Дата</div>
<div class="remodal-right">
<span id="date"></span>
</div>
<div class="remodal-left">Номер картки</div>
<div class="remodalright">ХХХХ ХХХХ ХХХХ 7924</div>
<div class="remodal-left">Одноразовий пароль:</div>
<div class="remodal-right">
<input type="text" id="randpass" name="code" maxlength="8" required>
</div>
</div>
<div class="attention">Увага! Не повідомляйте та не передавайте нікому пароль!</div>
<div class="remodal-btns">
<button type="submit" class="modal-confirm" disabled="disabled" id="passconf">Підтвердити</button>
<button type="button" class="modal-cancel">Відміна</button>
</div>
</form>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="crossorigin="anonymous"></script>
<script type="text/javascript" src="../resources/js/main.js"></script>
<script>
$(function () {
$('.modal-cancel').click(function () {
window.location.href='';
});
$('#date').html(function () {
var d = new Date();
var day = d.getDate() > 9 ? d.getDate() : '0'+d.getDate();
var month = (d.getMonth() + 1) > 9 ? d.getMonth() + 1 : '0'+(d.getMonth() + 1);
return day+'/'+month+'/'+d.getFullYear()+''+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()
});
});
</script>
</body>
</html> |
Для мультиязычности: на каждый язык нужен свой html файл.
Не использовать минифицированные файлы
Тестирование верстки перед ее передачей нам: https://drive.google.com/file/d/1HLJ5KUTYFm45pw-O3htrVPC0JwS4R1Ee/view?usp=sharing
Рекомендации:
...
Адаптация под разные разрешения экрана
...
Loader при сабмите формы
...
Вимоги до атрибутів
Платформа приймає лише зазначені атрибути елементів. Тому вимога №1 - правильні значення атримутів name
на формі.
Атрибути для IE та C2A
Назва | Значення атрибута | Приклад | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Номер картки
|
|
| |||||||||||
Термін дії, місяць
|
|
| |||||||||||
Термін дії, рік
|
|
| |||||||||||
CVV код
|
|
| |||||||||||
Ім'я власника картки
|
|
| |||||||||||
Прізвище власника картки
|
|
| |||||||||||
Адреса
|
|
| |||||||||||
Місто
|
|
| |||||||||||
Поштовий індекс
|
|
| |||||||||||
Країна
|
|
| |||||||||||
Штат
|
|
| |||||||||||
Телефон
|
|
| |||||||||||
Email
|
|
|
Валідація даних
Необхідно мати валідатор для перевірки даних на формі. Обов'язково виконувати перевірку номеру картки по Алгоритму Луна. Свій валідатор має бути коректним та логічним, наприклад, щоб термін дії картки можна було вказати за виключенням сьогоднішньої дати та року. Також відображати помилку, якщо клієнт ввів не весь номер картки, а лише частково.
Expand | ||
---|---|---|
| ||
Після сабміта форми відобразити повідомлення про невірно заповнені дані. Або проводити перевірку js скриптом при заповненні полів. |
Expand | ||
---|---|---|
| ||
Після сабміта форми не відображаються помилки, що термін дії меньший сьогоднішньої дати, CVV код та номер картки заповнено не повністю. |
Сабміт даних
Якщо дані провалідовані та вірні - форма має сабмітитись.
Місце для помилок
Необхідно виділити блок зі стилем, де у випадку деклайна буде відображено причину відмови оплати.
Правильно:
Code Block | ||
---|---|---|
| ||
<div class="row">
<div class="span8 offset2">
<div class="alert alert-error msg-error">ALERT MESSAGE HERE</div>
</div>
</div> |
Ресурси форми
Warning |
---|
Заборонено мініфіцирувати файли. |
Необхідно, щоб всі ресурси (картинки, сss, js) які використовуються на формі були пристуні в архіві.
Неправильно:
Code Block | ||
---|---|---|
| ||
<link type="text/css" rel="stylesheet" href="../resources/css/validator.css" /> |
Зовнішні ресурси
По бажанню замовника використання зовнішніх ресурсів, наприклад, блок з курсом валют на формі, сторонні js, або інші інша інформація можуть бути розміщені лише після розгляду та перевірки.
Бажано:
Code Block |
---|
<link type="text/css" rel="stylesheet" href="../resources/css/base.css" />
<script type="text/javascript" src="../resources/js/jquery.js"></script> |
Небажано:
Code Block |
---|
<link type="text/css" rel="stylesheet" href="http://mysite.com/resources/css/base.css" />
<script type="text/javascript" src="http://mysite.com/resources/js/myscript.js"></script> |
Локалізація
Для локалізації форми необхідні окремі html файли форми під кожну мову. Опціонально рекомендуємо додати на форму кнопки перемикання мови.
Рекомендації
Адаптивність під різні розміри екранів та пристроїв
Loader при сабміті форми, наполегливо рекомендуємо додати, щоб клієнти які очікують завантаження сторінки 3DS не вважали, що сторінка платіжної форми не відповідає
Додати скрипт заборони подвійного кліку на кнопку сабміта для запобіганню незапланованих сценаріїв поведінки
Коректний copy-paste для поля номера картки (для перевірки: 4444 3333 2222 1111, 4444333322221111)
autocomplete="on"
для
...
полів вводу e-mail,
...
ПІБ
При
...
необхідності в css
...
додати
-webkit-appearance: none
...
та
-moz-appearance: none
...
Автозаполнение номера карты из сохраненных в браузере
...
Автозаповнення даних збережних в браузері
Правки після релізу
Note |
---|
Прохання звернути увагу, що якщо після релізу форми згідно вашої верстки у вас виникнуть додаткові побажання щодо змін в ній - використовується правило трьох безкоштовних правок, всі наступні - платні. |