Odbieranie danych karty
Formularz płatności PayU prezentuje płatność kartą jako jedną z dostępnych opcji, dzięki której kupujący mogą sfinalizować transakcję. Jeśli jednak chcesz zapisać dane karty do późniejszego użycia, musisz skorzystać z formularza Secure Form.
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 Obowiązki 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, dodaj definicje typów do swojego projektu:
npm install --save @types/payu-emea-sdk
Dokumentacja SDK
Poniższy opis dotyczy metod i obiektów dostępnych w bibliotece JavaScript działającej po stronie przeglądarki, zawartej w JS SDK.
Dodaj skrypt JS SDK na każdej stronie, na której chcesz używać Secure Form. Zawsze wczytuj go z serwera PayU; nie hostuj go na własnym serwerze ani nie dołączaj do budowanego pakietu aplikacji.
- 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 znajdziesz w panelu menedżerskim. W poniższym przykładzie użyto testowego identyfikatora POS ze środowiska Sandbox.posId lub jest on pusty.PayU, gdy protokołem strony, na której wczytywane jest JS SDK, nie jest ani https, ani file, a strona nie jest ładowana z localhost, 127.0.0.1 ani 0.0.0.0. Podczas prac wdroż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 formularzy kartowych na jednej stronie, utwórz dla każdego z nich osobną instancję 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
payu.tokenize()
cvv.refReqId z pola redirectUri. Możesz użyć metody extractRefReqId, aby 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.- 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 formularz 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) {
// zawartość formularza uległa zmianie
})
- 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 poprawności typu i wartości. Nieznane lub niepoprawne parametry są ignorowane bez komunikatu 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("woff")',
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 i są sprawdzane pod kątem poprawności typu i wartości. Nieznane lub niepoprawne parametry są ignorowane bez komunikatu 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. Parametr jest używany, gdy język nie został określony w opcjach 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 jest zablokowany.false ikona nie jest 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.
Dozwolone style: fontColor
fontSize fontFamily
fontWeight letterSpacing
Style formularza.
Dozwolone style: fontColor
fontWeight
Style formularza z błędną wartością.
Dozwolone style: fontColor
fontWeight
Style formularza z aktywnym focusem.
Dozwolone style: fontColor
fontWeight
Style elementów zastępczych (placeholder) formularza.
Dozwolone style: 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, gdy formularz zostanie aktywowany.
Zdarzenie to jest emitowane, gdy 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. |
brand | Tylko dla formularza typu number. Zawiera informację o marce karty. Możliwe wartości:
|
length | Tylko dla formularza typu number, gdy pole error przyjmuje wartość false. Zawiera informację o długości numeru karty. |
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łędu. |
source | Element, którego dotyczy błąd (tylko dla błędów typu validation). 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 | validation | Pusty numer karty. |
error.validation.card.length | validation | Nieprawidłowa długość numeru karty. |
error.validation.card.number | validation | Nieprawidłowy numer karty. |
error.validation.card.unsupported | validation | Nieobsługiwany rodzaj karty. Obsługiwane typy kart to Visa, Mastercard i Maestro. |
error.validation.expDate.empty | validation | Pusta data ważności karty. |
error.validation.expDate.past | validation | Data ważności karty jest z przeszłości. |
error.validation.expDate.value | validation | Data ważności karty jest nieprawidłowa. |
error.validation.cvv.empty | validation | Pusty CVV. |
error.validation.cvv.value | validation | 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 przesyłania CVV. Informacje o błędzie znajdziesz w obiekcie parameters w polu error. |
error.network | technical | Wystąpił błąd komunikacji sieciowej. Informacje o błędzie znajdziesz w obiekcie parameters w polu error. |
FAQ
Jak przetłumaczyć formularz na inny język?
Tłumaczeniu podlegają teksty zastępcze (placeholdery) oraz komunikaty błędów. Oba te elementy możesz przetłumaczyć samodzielnie.
Teksty zastępcze (placeholdery) są przekazywane w parametrze placeholder w opcjach formularza, np.:
{
"placeholder": {
"number": "Kartennummer",
"date": "MM / JJ",
"cvv": "CVV"
}
}
W przypadku błędów komunikat wyświetlany jest na podstawie kodu błędu, 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
})
}
Okno przeglądarki zostało pomniejszone lub telefon został obrócony. Jak zmienić rozmiar czcionki i wyłączyć ikonę marki karty, aby formularz zmieścił się w całości na stronie?
Przy zmianie wielkości okna przeglądarki użyj metody update, aby zaktualizować opcje 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])
}
})