Odbieranie danych karty
Formularz Secure Form pozwala na odbieranie i tokenizację danych kartowych w celu ich zapisania i przyszłego użycia.
Secure Form to konfigurowalny formularz hostowany przez PayU, który możesz zintegrować ze swoją witryną przy użyciu ramki iframe. Gdy klient wprowadza dane swojej karty w Secure Form, informacje te są bezpiecznie przesyłane do PayU, gdzie poddawane są tokenizacji, zanim zostaną zwrócone w postaci unikalnego tokena. Wykorzystanie tego podejścia zapewnia optymalną ochronę danych kart klientów i pomaga zachować zgodność z wymaganiami PCI DSS.
Podczas korzystania z formularza Secure Form należy wyświetlić tekst podany w sekcji Wymagania informacyjne.
Więcej szczegółów na temat procesu tokenizacji i efektywnego wykorzystania tokenów znajdziesz w sekcji Tokenizacja kart.
Przykłady Secure Form
- Podgląd
- HTML
- Javascript
- CSS
Przykład formularza Secure Form z połączonymi polami danych
<script
type="text/javascript"
src="https://secure.payu.com/javascript/sdk"
></script>
<section class="container">
<div class="card-container">
<div class="payu-card-form" id="payu-card"></div>
</div>
<button id="tokenizeButton">Tokenize</button>
<div id="responseTokenize"></div>
</section>
var optionsForms = {
style: {
basic: {
fontSize: "18px",
},
},
lang: "pl",
};
var renderError = function (element, errors) {
element.className = "response-error";
var messages = [];
errors.forEach(function (error) {
messages.push(error.message);
});
element.innerText = messages.join(", ");
};
var renderSuccess = function (element, msg) {
element.className = "response-success";
element.innerText = msg;
};
//inicjalizacja SDK poprzez podanie POS ID oraz utworzenie obiektu secureForms
var payuSdkForms = PayU("393823");
var secureForms = payuSdkForms.secureForms();
//utworzenie formularza podając typ oraz opcje
var card = secureForms.add("card", optionsForms);
//renderowanie formularza
card.render("#payu-card");
var tokenizeButton = document.getElementById("tokenizeButton");
var responseElement = document.getElementById("responseTokenize");
tokenizeButton.addEventListener("click", function () {
responseElement.innerText = "";
try {
payuSdkForms.tokenize("SINGLE").then(function (result) {
// przykład dla tokenu typu SINGLE
result.status === "SUCCESS"
? renderSuccess(responseElement, result.body.token) //tutaj wstaw przekazanie tokena do back-endu
: renderError(responseElement, result.error.messages); //sprawdź typ błędu oraz komunikaty i wyświetl odpowiednią informację użytkownikowi
});
} catch (e) {
console.log(e); // błędy techniczne
}
});
.container * {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #ffffff;
}
.container {
text-align: center;
width: 420px;
margin: 20px auto 10px;
display: block;
border-radius: 5px;
box-sizing: border-box;
}
.card-container {
width: 100%;
margin: 0 auto;
border-radius: 6px;
padding: 10px;
background: rgb(2, 0, 60);
text-align: left;
box-sizing: border-box;
}
.payu-card-form {
background-color: #ffffff;
padding: 5px;
border-radius: 4px;
}
button {
border: none;
background: #438f29;
padding: 8px 15px;
margin: 10px auto;
cursor: pointer;
}
.response-success {
color: #438f29;
}
.response-error {
color: #990000;
}
- Podgląd
- HTML
- Javascript
- CSS
Przykład formularza Secure Form z rozbiciem na indywidualne pola danych
<script
type="text/javascript"
src="https://secure.payu.com/javascript/sdk"
></script>
<section class="container">
<div class="card-container">
<aside>Card Number</aside>
<div class="payu-card-form" id="payu-card-number"></div>
<div class="card-details clearfix">
<div class="expiration">
<aside>Valid Thru</aside>
<div class="payu-card-form" id="payu-card-date"></div>
</div>
<div class="cvv">
<aside>CVV</aside>
<div class="payu-card-form" id="payu-card-cvv"></div>
</div>
</div>
</div>
<button id="tokenizeButton">Tokenize</button>
<div id="responseTokenize"></div>
</section>
var optionsForms = {
cardIcon: true,
style: {
basic: {
fontSize: "24px",
},
},
placeholder: {
number: "",
date: "MM/YY",
cvv: "",
},
lang: "pl",
};
var renderError = function (element, errors) {
element.className = "response-error";
var messages = [];
errors.forEach(function (error) {
messages.push(error.message);
});
element.innerText = messages.join(", ");
};
var renderSuccess = function (element, msg) {
element.className = "response-success";
element.innerText = msg;
};
//inicjalizacja SDK poprzez podanie POS ID oraz utworzenie obiektu secureForms
var payuSdkForms = PayU("393823");
var secureForms = payuSdkForms.secureForms();
//utworzenie formularzy podając ich typ oraz opcje
var cardNumber = secureForms.add("number", optionsForms);
var cardDate = secureForms.add("date", optionsForms);
var cardCvv = secureForms.add("cvv", optionsForms);
//renderowanie formularzy
cardNumber.render("#payu-card-number");
cardDate.render("#payu-card-date");
cardCvv.render("#payu-card-cvv");
var tokenizeButton = document.getElementById("tokenizeButton");
var responseElement = document.getElementById("responseTokenize");
tokenizeButton.addEventListener("click", function () {
responseElement.innerText = "";
try {
//tokenizacja karty (komunikacja z serwerem PayU)
payuSdkForms.tokenize("SINGLE").then(function (result) {
// przykład dla tokenu typu SINGLE
result.status === "SUCCESS"
? renderSuccess(responseElement, result.body.token) //tutaj wstaw przekazanie tokena do back-endu
: renderError(responseElement, result.error.messages); //sprawdź typ błędu oraz komunikaty i wyświetl odpowiednią informację użytkownikowi
});
} catch (e) {
console.log(e); // błędy techniczne
}
});
.container * {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #ffffff;
}
.container {
text-align: center;
width: 420px;
margin: 20px auto 10px;
display: block;
border-radius: 5px;
box-sizing: border-box;
}
.card-container {
width: 100%;
margin: 0 auto;
border-radius: 6px;
padding: 10px;
background: rgb(2, 0, 60);
text-align: left;
box-sizing: border-box;
}
.card-container aside {
padding-bottom: 6px;
}
.payu-card-form {
background-color: #ffffff;
padding: 5px;
border-radius: 4px;
}
.card-details {
clear: both;
overflow: auto;
margin-top: 10px;
}
.card-details .expiration {
width: 50%;
float: left;
padding-right: 5%;
}
.card-details .cvv {
width: 45%;
float: left;
}
button {
border: none;
background: #438f29;
padding: 8px 15px;
margin: 10px auto;
cursor: pointer;
}
.response-success {
color: #438f29;
}
.response-error {
color: #990000;
}
Typescript
Jeżeli używasz Typescript
po prostu dodaj definicję typów w swoim projekcie.
npm install --save @types/payu-emea-sdk
Dokumentacja SDK
PayU udostępnia JS SDK z biblioteką JavaScript działającą po stronie przeglądarki. Biblioteka ta zawiera metody i obiekty, które mogą pomóc w integracji niektórych rozwiązań oferowanych przez PayU, np. Secure Form.
JS SDK należy zawsze wczytywać z serwera PayU. Nie możesz wczytać go z własnego serwera, a następnie dołączać do pakietu, który jest aktualnie budowany.
- Produkcja
- Sandbox
<script type="text/javascript" src="https://secure.payu.com/javascript/sdk"></script>
<script type="text/javascript" src="https://secure.snd.payu.com/javascript/sdk"></script>
posId
, który można znaleźć w panelu menedżerskim. W poniższym przykładzie użyto testowego identyfikatora POS ze środowiska Sandbox.posId
lub jest on pusty.MarketplaceVerification
, gdy protokołem strony, na której wczytywane jest JS SDK nie jest https i file, a strona nie jest ładowana z localhost: 127.0.0.1 lub 0.0.0.0. Podczas prac wrożeniowych można włączyć tryb deweloperski w parametrze options
.- Przykład
var payu = PayU("393823");
Tworzy instancję SecureForms. Na tak utworzonym obiekcie będzie możliwe dodawanie elementów SecureForm.
Opcje instancji SecureForms. Więcej informacji o poszczególnych opcjach w sekcji Opcje instancji Secure Forms.
Występuje przy próbie utworzenia kolejnej instancji SecureForms. Jeżeli potrzebujesz umieścić wiele różnych formularzy kartowych na jednej stronie to dla każdego z nich utwórz osobną instancje JS SDK.
- Przykład
var secureForms = payu.secureForms();
Żądanie utworzenia tokena kartowego z wykorzystaniem utworzonych pól SecureForm.
Możliwe Wartości (domyślna wartość - SINGLE) | |
---|---|
SINGLE | Bez zapisu karty - token o krótkim czasie życia (11 minut). |
SINGLE_LONGTERM | Bez zapisu karty. |
MULTI | Karta zapisana - wielorazowy token zostanie zwrócony po obciążeniu tokenu poprzez REST API. |
Pole | Opis |
---|---|
status | Status tokenizacji:
|
body | Tylko dla statusu SUCCESS . Obiekt zawierający informacje o tokenizacji. |
error | Tylko dla statusu ERROR . Obiekt z tablicą messages zawierającą informacje o błędach. Szczegółowe informacje znajdują się w rozdziale Błędy. |
correlationId | Tylko dla statusu ERROR . |
- Przykład
{
"status": "SUCCESS",
"body": {
"token": "TOK_1JOQVU5KJNOV4c4O8UbZySwcfBdS",
"mask": "444433******1111"
}
}
card
lub formularze: number
, date
i cvv
.- Przykład
var secureForms = payu.secureForms();
cvv
.refReqId
z pola redirectUri
. Można użyć metody extractRefReqId żeby uzyskać refReqId
z adresu URL. W przypadku gdy nastąpi przekierowanie na stronę po wykonanym 3DS,
refReqId
należy pobrać z parametru adresu URL. Przykład adresu URL:
https://address.page/summary/?statusCode=WARNING_CONTINUE_CVV&refReqId=7b09781ee6a3303cc86712fce16fe030
Pole | Opis |
---|---|
status | Status przesłania CVV:
|
error | Tylko dla statusu ERROR . Obiekt zawierający informacje o błędach. Więcej informacji o błędach w sekcji Błędy. |
correlationId | Tylko dla statusu ERROR . |
- Przykład
{
"status": "SUCCESS"
}
cvv
jest wymagany.- Przykład
payu.sendCvv("7b09781ee6a3303cc86712fce16fe030");
refReqId
z adresu URL.refReqId
- Przykład
var refReqId = payu.extractRefReqId(
'https://secure.payu.com/cpm/threeds/proxy?refReqId=7b09781ee6a3303cc86712fce16fe030"'
);
Możliwe Wartości (domyślna wartość - card) | |
---|---|
card | Pełen formularz danych karty (numer karty, data ważności, CVV). |
number | Formularz z numerem karty. |
date | Formularz z datą ważności karty. |
cvv | Formularz z CVV. |
aria-label
) w polach formularza.message
.card
gdy wcześniej został dodany formularz typu number
, date
lub cvv
oraz przy próbie dodania formularza typu number
, date
lub cvv
gdy wcześniej został dodany formularz typu card
. Szczegółową informację o błędzie znajdziesz w tablicy message
.- Przykład
var cardNumberForm = secureForms.add("number");
querySelectorAll
.appendChild
lub jest to element typu input).- Przykład
cardNumberForm.render("#cardNumberForm");
options
jest taki sam jak parametr options
w metodzie add. Brak nowych opcji nie usuwa wcześniej podanych, natomiast ich obecność nadpisuje już istniejące opcje.- Przykład
cardNumberForm.update({ lang: "en" });
Możliwe Wartości | |
---|---|
ready | Wyemitowane gdy formularz zostanie wyświetlony. |
focus | Wyemitowane gdy formularz został aktywowany (otrzymał fokus). |
blur | Wyemitowane gdy formularzu został dezaktywowany (stracił fokus). |
change | Wyemitowane gdy zawartość formularza została zmieniona. |
- Przykład
cardNumberForm
.on("ready", function () {
// formularz gotowy
})
.on("focus", function () {
// formularz aktywowany
})
.on("blur", function () {
// formularz dezaktywowany
})
.on("change", function (body) {
// zmieniała się zawartość
});
- Przykład
cardForm.clear();
- Przykład
cardForm.focus();
- Przykład
cardForm.remove();
Opcje formularza
Opcje instancji Secure Forms
Wszystkie parametry są sprawdzane pod kątem odpowiedniego typu oraz czy zawierają poprawne wartości. W przypadku nieznanego lub nieporawnego parametru jest on ignorowany bez informacji o błędzie.
Parametr | Typ | Opis |
---|---|---|
fonts | array | Niestandardowe czcionki do formularzy. |
lang | string | Dwuznakowy kod języka. Dostępne języki to: bg , cs , da , de , el , en , es , et , fi , fr , hr , hu , it , lt , lv , nl , pl , pt , ro , ru , sk , sl , sr , sv , tr , uk . W przypadku braku języka pobierany jest on z przeglądarki. W przypadku nieobsługiwanego języka używany jest en . |
Zawiera listę obiektów definiującą dodatkowe czcionki, które zostaną dodane do każdego formularza przy użyciu @font-face
.
Dozwolone wartości: [-_a-zA-Z0-9 ]+
Dozwolone wartości: url(URL) format([collection|embedded-opentype|opentype|svg|truetype|woff|woff2])
Może zawierać wiele takich wpisów oddzielonych przecinkiem.
Dozwolone wartości:
(auto|block|swap|fallback|optional)
Dozwolone wartości: (normal|italic|oblique)
Dozwolone wartości: ([1-9]00|normal|bold)
- Przykład
{
fonts: [
{
family: "Own Font",
src: 'url(https://ownulr.com/own_font_normal.woff2) format("woff2"), url(https://ownulr.com/own_font_normal.woff) format("woff2)',
style: "normal",
weight: 400,
},
{
family: "Own Font",
src: 'url(https://ownulr.com/own_font_bold.woff2) format("woff2")',
style: "normal",
weight: "bold",
},
];
}
Opcje formularza
Wszystkie parametry są opcjonalne oraz sprawdzane pod kątem odpowiedniego typu oraz czy zawieraja poprawne wartości. W przypadku nieznanego lub nieporawnego parametru jest on ignorowany bez informacji o błędzie.
Własny tekst dostępności (aria-label
) w polach formularza. W przypadku braku parametru dodawany jest tekst dostępności zgodny z aktualnym językiem.
Własny tekst zastępczy (placeholder) w polach formularza. W przypadku braku parametru dodawany jest tekst zastępczy zgodny z aktualnym językiem.
bg
, cs
, da
, de
, el
, en
, es
, et
, fi
, fr
, hr
, hu
, it
, lt
, lv
, nl
, pl
, pt
, ro
, ru
, sk
, sl
, sr
, sv
, tr
, uk
. Instancji Secure Forms. W przypadku braku języka pobierany jest on z przeglądarki. W przypadku nieobsługiwanego języka używany jest en
.true
formularz będzie zablokowany.false
ikona nie będzie wyświetlana.- Przykład
{
style: {
basic: {
fontColor: '#0000FF'
fontSize: '26px'
fontWeight: '700'
},
invalid: {
fontColor: '#990000'
},
placeholder: {
fontColor: '#aaaaaa'
}
},
placeholder: {
number: '',
date: 'MM / YY',
cvv: ''
},
label: {
number: 'Numer karty',
date: 'Data ważności karty',
cvv: 'Kod CVV/CVC karty'
},
cardIcon: true,
lang: 'en',
disabled: false
}
Grupuje w obiektach style dla różnych zachowań formularza. Każda grupa ma swoje dozwolone style.
Permitted styles: fontColor
fontSize
fontFamily
fontWeight
letterSpacing
Style formularza.
Permitted styles: fontColor
fontWeight
Style formularza z błędną wartością.
Permitted styles: fontColor
fontWeight
Style formularza z aktywnym focusem.
Permitted styles: fontColor
fontWeight
Style elementów zastępczych (placeholder) formularza.
Permitted styles: fontColor
fontWeight
Style nieaktywnego formularza.
Dozwolone wartości:
#[0-9a-f]{6}
kolor czcionki
Dozwolone wartości: (\d+|\d*.\d+)(px|em|%)
wielkość czcionki
Dozwolone wartości: [0-9a-z-\s,"']{1, 150}
rodzaj czcionki
Dozwolone wartości:
([1-9]00|normal|bold|lighter|bolder|inherit|initial|unset)
grubość czcionki
Dozwolone wartości:
normal|(-?)(\d+|\d*.\d+)(px|em|%)
odstęp pomiędzy znakami
Tekst zastępczy (placeholder) dla formularza numeru karty.
Tekst zastępczy (placeholder) dla formularza daty ważności karty.
Tekst dostępności (aria-label
) dla formularza numeru karty.
Tekst dostępności (aria-label
) dla formularza daty ważności karty.
aria-label
) dla formularza kodu cvv.Zdarzenia
Formularze emitują zdarzenia do których można dołączyć własną funkcję zwrotną za pomocą metody on.
Zdarzenie to jest emitowane po wywołaniu metody render gdy formularz zostanie wyświetlony.
Zdarzenie to jest emitowane formularz zostanie aktywowany.
Zdarzenie to jest emitowane formularz zostanie dezaktywowany.
Zdarzenie to jest emitowane gdy zawartość formularza ulegnie zmianie. Funkcja zwrotna wywoływana jest z jednym parametrem będącym obiektem o następującej strukturze:
Pole | Opis |
---|---|
empty | Informuje czy formularz ma pustą zawartość. Możliwe wartości to:
|
error | Informuje czy dane wprowadzone w formularzu są poprawne. Możliwe wartości to:
validation . Szczegółowe informacje znajdują się w sekcji Błędy section. |
brand | Tylko dla formularzu typu number . Zawiera informację o marce karty. Możliwe wartości:
|
Dynamiczne klasy
Do elementu, w którym wyświetlany jest formularz dodawane są dynamicznie klasy:
Klasa | Opis |
---|---|
payu-secure-form-empty | Ustawiana gdy formularz ma pustą zawartość. |
payu-secure-form-focus | Ustawiana gdy formularz jest aktywny (ma fokus). |
payu-secure-form-invalid | Ustawiana gdy dane wprowadzone do formularza są niepoprawne. |
Błędy
W obiekcie error
znajduje się tablica messages
zawierająca obiekty, w których znajdują się informacje o poszczególnych błędach.
- Przykład wiadomości o błędzie
{
"status": "ERROR",
"correlationId": "",
"error": {
"messages": [
{
"type": "validation",
"code": "error.validation.expDate.value",
"parameters": {},
"message": "Card expiration date is invalid"
},
{
"type": "validation",
"code": "error.validation.cvv.empty",
"parameters": {},
"message": "Empty CVV"
}
]
}
}
Wyróżniony powyżej jest jeden z obiektów wewnątrz tablicy messages
ze szczegółami błędu.
Pole | Opis |
---|---|
type | Rodzaj błędu. Możliwe wartości to:
|
code | Kod błedu. |
source | Element którego dotyczy błąd (tylko dla błędów typu validate ). Możliwe wartości to: card , number , date , cvv . |
message | Opis błędu w języku formularza. W przypadku błędów typu technical opis jest zawsze w języku angielskim. |
parameters | Obiekt ze zmiennymi fragmentami błędu. |
Kod błędu | Rodzaj | Opis |
---|---|---|
error.validation.card.empty | validate | Pusty numer karty. |
error.validation.card.length | validate | Nieprawidłowa długość numeru karty. |
error.validation.card.number | validate | Nieprawidłowy numer karty. |
error.validation.card.unsupported | validate | Niewspierany rodzaj karty. Obsługiwane typy karty to Visa, Mastercard i Maestro. |
error.validation.expDate.empty | validate | Pusta data ważności karty. |
error.validation.expDate.past | validate | Data ważności karty jest z przeszłości. |
error.validation.expDate.value | validate | Data ważności karty jest nieprawidłowa. |
error.validation.cvv.empty | validate | Pusty CVV. |
error.validation.cvv.value | validate | Nieprawidłowy CVV. |
error.tokenization | technical | Wystąpił błąd podczas tokenizacji. Informacje o błędzie znajdziesz w obiekcie parameters w polu error . |
error.send.cvv | technical | Wystąpił błąd podczas tokenizacji. Informacje o błędzie znajdziesz w obiekcie parameters w polu error . |
error.network | technical | Wystąpił błąd podczas tokenizacji. Informacje o błędzie znajdziesz w obiekcie parameters w polu error . |
FAQ
Potrzebuję tłumaczenia na język xx.
Elementy, które są tłumaczone to teksty zastępcze (placeholder) oraz komunikaty błędów. Obie rzeczy można przetłumaczyć we własnym zakresie.
Elementów zastępcze (placeholders) są przekazywane w parametrze placeholder
w opcjach formularza np.
{
"placeholder": {
"number": "Kartennummer",
"date": "MM / JJ",
"cvv": "CVV"
}
}
W przypadku błędów na podstawie kodów błędów wyświetlany jest komunikat PayU np.
var errors = {
messages: [
{
type: "validation",
code: "error.validation.card.number",
parameters: {},
message: "Nieprawidłowy numer karty",
},
],
};
var translations = {
"error.validation.card.number": "Ungültige Kartennummer",
};
var showError = function () {
errors.messages.forEach(function (message) {
console.log(translations[message.code]); // pokazanie komunikatu błędu
});
};
Ktoś pomniejszył okno przeglądarki lub obrócił telefon i chcę zmienić rozmiar czcionki oraz wyłączyć ikonę marki karty żeby formularz zmieścił się w całości na stronie.
Powinieneś, przy zmianie wielkości okna przeglądarki, użyć metody update do aktualizacji opcji formularza np.
// kod inicjujący JS SDK i SecureForms został pominięty
var cardNumber = secureForms.add("number");
var options = {
current: "gt500",
profiles: {
gt500: {
style: {
basic: {
fontSize: "18px",
},
},
cardIcon: true,
},
lt500: {
style: {
basic: {
fontSize: "14px",
},
},
cardIcon: false,
},
},
};
// zmiana wielkości okna
window.addEventListener("resize", function () {
var newProfile = window.innerWidth > 500 ? "gt500" : "lt500";
if (newProfile !== options.current) {
options.current = newProfile;
// aktualizacja opcji formularza
cardNumber.update(options.profiles[options.current]);
}
});