Tokenizacja kart

1 Wprowadzenie

Tokenizacja kart opiera się na transparentnej integracji, tj. odbywa się bez przekierowania na formularz PayU. Pomimo tego taka integracja jest bezpieczna i minimalizuje obowiązki wynikające z PCI DSS. Ponadto daje więcej elastyczności i zwiększa konwersję (ilość udanych płatności), ponieważ płatność odbywa się na stronie sklepu.

Proces płatności odbywa się w dwóch krokach - najpierw należy uzyskać dane karty, a następnie obciążyć kartę. Dane karty są zwracane z PayU w postaci tokena wraz maskowanym numerem karty oraz datą ważności - sklep nie otrzymuje i nie musi przetwarzać pełnego numeru karty.

Tokeny zwrócone przez PayU mogą być jednorazowe lub wielorazowe. Tokeny wielorazowe mogą posłużyć do przyszłych płatności. Funkcjonalność ta skierowana jest do sklepów mających dużą ilość powracających klientów – połączenie konta użytkownika w sklepie z tokenem wielorazowym umożliwia dokonywania płatności bez każdorazowego podawania danych karty.

Konfiguracja w PayU

Tokenizacja karty typu SINGLE (token jednorazowy, karta nie zostaje zapisana) jest dostępna bez dodatkowej konfiguracji. Jednak tokenizacja typu MULTI (token wielorazowy i zapisanie karty dla danego użytkownika) wymaga specjalnej konfiguracji po stronie PayU, dlatego przed przystąpieniem do integracji należy skontaktować się z opiekunem handlowym w PayU.

Na środowisku Sandbox punkty płatności typu REST API zostaną skonfigurowane automatycznie pod możliwość testowania tej funkcjonalności w ciągu 90 minut od utworzenia.

Wymogi i zalecenia dot. bezpieczeństwa

Zanim przystąpisz do integracji usługi, zapoznaj się z zaleceniami i wymogami przygotowanymi przez ekspertów ds. bezpieczeństwa w PayU. Ich przestrzeganie pomoże zminimalizować ryzyko związane z transakcjami oszukańczymi.

2 Integracja usługi

Tokenizacja karty bez jej zapisywania:
  • dodaj "Secure Form" do swojej strony,
  • zamień numer karty na token używając tokenizacji typu SINGLE na swojej stronie i przekaż token do back-endu,
  • wyślij żądanie utworzenia zamówienia z tokenem.
Tokenizacja karty wraz z jej zapisem:
  • dodaj "Secure Form" do swojej strony,
  • zamień numer karty na token wielorazowy używając tokenizacji typu MULTI na swojej stronie i przekaż token do back-endu,
  • wyślij żądanie utworzenia zamówienia z tokenem i danymi klienta,
  • pobierz zapisany token przy kolejnej płatności dla tego klienta.

Płatność z tokenem jednorazowym (pierwsza)::

Płatność z tokenem wielorazowym (druga i kolejne):

3 Secure Form

Secure Form jest preferowanym rozwiązaniem dla płatności kartą. Wszystkie dane karty są wprowadzane poprzez iframe w formularzu PayU, co eliminuje potrzebę obsłużenia wrażliwych danych na Twojej stronie.

Pamiętaj, że wykorzystując "Secure Form" należy wyświetlić również niezbędne Przypisy prawne.

3.1 Przykłady

Przykład pojedynczego formularza
<script type="text/javascript" src="https://merch-prod.snd.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">Tokenizuj</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().then(function(result) {
            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;
}
Przykład z rozbiciem poszczególnych pól na osobne formularze
<script type="text/javascript" src="https://merch-prod.snd.payu.com/javascript/sdk"></script>
<section class="container">
    <div class="card-container">
        <aside>Numer Karty</aside>
        <div class="payu-card-form" id="payu-card-number"></div>

        <div class="card-details clearfix">
            <div class="expiration">
                <aside>Ważna do</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">Tokenizuj</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().then(function(result) {
            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;
}

3.2 Dokumentacja SDK

Poniżej znajduje się opis metod oraz obiektów dostępnych w bibliotece JavaScript dla przeglądarki zawartych w JS SDK

Wczytanie JS SDK

Dodaj skrypt JS SDK na każdej stronie, na której chcesz używać SecureForm. Musi być on zawsze ładowany bezpośrednio z serwerów PayU. Nie może być ładowany z własnych serwerów oraz załączany do budowanej paczki.

<script type="text/javascript" src="https://secure.snd.payu.com/javascript/sdk"></script>
<script type="text/javascript" src="https://merch-prod.snd.payu.com/javascript/sdk"></script>

Utworzenie instancji JS SDK

PayU(posId, options?)

Parametrem wymaganym jest identyfikator POS-a, który znajdziesz w swoim Panelu. W przykładzie użyliśmy identyfikatora testowego POS-a na środowisku Sandbox.

Parametery metody

posIdwymaganystring
Identyfikator punktu płatności.
optionsopcjonalnyobject
Opcje instancji.
devboolean
Utworzenie instancji w trybie deweloperskim która umożliwia działania na stronie nie używającej HTTPS.

Zwraca

Instancja PayU.

Wyjątki

posid.is.empty
Występuje przy utworzenie instancji JS SDK gdy nie podano parametru posId lub jest on pusty.
non.https.integration
Występuje przy utworzeniu instancji JS SDK gdy protokołem strony na której jest wczytany JS SDK nie jest https i file oraz nie jest wczytywana z adresów localhost, 127.0.0.1 lub 0.0.0.0.
Podczas prac wrożeniowych można włączyć tryb deweloperskim w parametrze options
var payu = PayU('393823');

Metody instancji JS SDK

secureForms()

Tworzy instancję SecureForms.
Na tak utworzonym obiekcie będzie możliwe dodawanie elementów SecureForm.

Zwraca

Instancja SecureForms.

Wyjątki

secure.forms.already.exists
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.
var secureForms = payu.secureForms();

tokenize(type?)

Żądanie utworzenia tokena kartowego z wykorzystaniem utworzonych pól SecureForm.

Parametery metody

typeopcjonalnystring
Typ utworzonego tokena kartowego.
Możliwe wartości (domyślnie - SINGLE)
SINGLE bez zapisu karty - token o krótkim czasie życia (15 minut)
SINGLE_LONGTERM bez zapisu karty
MULTI karta zapisana - wielorazowy token zostanie zwrócony po obciążeniu tokenu poprzez REST API

Zwraca

Promise, która rozwiązuje się do obiektu zawierającego rezultat.

Pole Opis
status Status tokenizacji:
SUCCESS poprawna tokenizacja, w polu body jest dostępny wynik tokenizacji,
ERROR wystąpił błąd podczas tokenizacji, w polu error znajdują się błędy
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.
{
    "status": "SUCCESS",
    "body": {
        "token": "TOK_1JOQVU5KJNOV4c4O8UbZySwcfBdS",
        "mask": "444433******1111"
    }
}

Wyjątki

incorrect.token.type
Nieprawidłowy typ tokenu. Możliwe wartości znajdują się w opisie parametru type.
tokenize.not.possible
Tokenizacja nie jest możliwa. Wymagany jest formularz typu card lub formularze: number, date i cvv
var secureForms = payu.secureForms();

sendCvv(refReqId)

Wysyła żądanie przesłania CVV. Działa jedynie w przypadku gdy formularz jest typu cvv.

Parametery metody

refReqIdwymaganystring
Gdy podczas próby ociążenia karty PayU odpowie kodem WARNING_CONTINUE_CVV refReqId należy pobrać z pola redirectUri odpowiedzi. 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ładowy adres URL: https://adres.strony/summary/?statusCode=WARNING_CONTINUE_CVV&refReqId=7b09781ee6a3303cc86712fce16fe030

Zwraca

Promise, która rozwiązuje się do obiektu zawierającego rezultat.

Pole Opis
status Status przesłąnia CVV:
SUCCESS poprawne przesłanie CVV - nie jest toższame z poprawnym CVV,
ERROR wystąpił błąd podczas przesłania CVV, w polu error znajdują się błędy
error Tylko dla statusu ERROR. Obiekt zawierający informacje o błędach. Więcej informacji o błędach w rozdziale Błędy
correlationId Tylko dla statusu ERROR.
{
    "status": "SUCCESS",
    "body": {
        "token": "TOK_1JOQVU5KJNOV4c4O8UbZySwcfBdS",
        "mask": "444433******1111"
    }
}

Wyjątki

refReqId.is.empty
Nie podano parametru refReqId lub jest on pusty.
sendCvv.not.possible
Wsytąpił błąd podczas próby wysłania CVV. Tylko formularz typu cvv jest wymagany.
payu.sendCvv('7b09781ee6a3303cc86712fce16fe030');

extractRefReqId(url)

Funkcja pomocnicza służąca do uzyskania refReqId z adresu URL.

Parametery metody

urlwymaganystring
Adres URL.

Zwraca

refReqId.
var refReqId = payu.extractRefReqId('https://secure.payu.com/cpm/threeds/proxy?refReqId=7b09781ee6a3303cc86712fce16fe030"');

Metody instancji SecureForms

add(type?, options?)

Tworzy instancję pojedynczego formularza SecureForm.

Parametery metody

typeopcjonalnystring
Typ formularza.
Możliwe wartości (domyślnie - 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.
optionsopcjonalnyobject
Opcje formularza. Więcej informacji o poszczególnych opcjach w rozdziale Opcje formularza
styleobject
Własne style formularza.
placeholderobject
Własny tekst zastępczy (placeholder) w polach formularza.
langstring
Język.
disabledboolean
Blokuje pola formularza.
cardIconboolean
Czy ikona marki karty ma być wyświetlana przy polu wprowadzania numeru karty.

Zwraca

Instancja Secure Form.

Wyjątki

secure.form.incorrect.type
Nieprawidłowy typ formularza. Możliwe wartości znajdują się w opisie parametru type.
secure.form.exist.type [message]
Występuje przy próbie dodania kolejnego formularza określonego typu. W [message] znajduje się szczegółowa informacja o błędzie.
secure.form.exist.other.type [message]
Występuje przy próbie dodania formularza typu 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. W [message] znajduje się szczegółowa informacja o błędzie.
var cardForm = secureForms.add();

Metody instancji SecureForm

render(selector)

Wyświetla formularz na stronie.

Parametery metody

selectorwymaganystring
Selektor elementu, w którym ma się wyświetlić formularz. Element jest wyszukiwany przy użyciu querySelectorAll.

Zwraca

Własna instancja Secure Form.

Wyjątki

element.selector.empty
Nie podano parametru selector lub jest on pusty.
element.selector.not.string
Parametru selector nie jest typu string.
element.not.exists
Element nie istnieje na stronie.
element.too.many.exists
Na stronie znajduje się wiecej niż jeden element.
element.not.valid
Niepoprawny element (nie ma zaimplementoaje metody appendChild lub jest to element input).
element.contains.children
Element posiada elementy podrzędne.
cardForm.render('#cardForm');

update(options)

Usuwa formularz ze strony.

Parametery metody

optionswymaganyobject
Aktualizuje formularz. Parametr 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.

Zwraca

Własna instancja Secure Form.
cardForm.update({lang: 'en'});

clear()

Usuwa wpisane dane w formularzu.

Zwraca

Własna instancja Secure Form.
cardForm.clear();

remove()

Usuwa formularz ze strony.

Zwraca

Własna instancja Secure Form.
cardForm.remove();

3.3 Opcje formularza

Wszystkie parametry są 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.

Parametr Typ Opis
style object Własne style formularza
placeholder object Własny tekst zastępczy (placeholder) w polach formularza
lang string Dwuznakowy kod języka. Dostępne języki to: pl en cs sk.
W przypadku braku języka pobierany jest on z przeglądarki. W przypadku nieobsługiwanego języka używany jest en.
disabled boolean Gdy true formularz będzie zablokowany w innym wypadku formularz będzie aktywny.
cardIcon boolean Gdy false nie jest wyświetlana ikona marki karty przy polu wprowadzania numeru karty w innym wypadku ikona karty będzie wyświetlana.
{
    style: {
        basic: {
            fontColor: '#0000FF'
            fontSize: '26px'
            fontWeight: '700'
        },
        invalid: {
            fontColor: '#990000'
        },
        placeholder: {
            fontColor: '#aaaaaa'
        }
    },
    placeholder: {
        number: '',
        date: 'MM / YY',
        cvv: ''
    },
    cardIcon: true,
    lang: 'en',
    disabled: false
}

Obiekt style

Grupuje w obiektach style dla różnych zachowań formularza. Każda grupa ma swoje dozwolone style.

Grupa styli Dozwolone style Opis
basic fontColor fontSize fontFamily fontWeight Style dla formularza
invalid fontColor fontWeight Style dla formularza z błędną wartością
focus fontColor fontWeight Style dla formularza z aktywnym focusem
placeholder fontColor fontWeight Style dla elementów zastępczych (placeholder) formularza
disabled fontColor fontWeight Style dla nieaktywnego formularza

Style

Styl Opis Dozwolone wartości
fontColor kolor czcionki #[0-9a-f]{6}
fontSize wielkość czcionki (\d+|\d*\.\d+)(px|em|%)
fontFamily rodzaj czcionki [0-9a-z\-\s]{1,50}
fontWeight grubość czcionki ([1-9]00|normal|bold|lighter|bolder|inherit|initial|unset)

Obiekt placeholder

Pole Typ Opis
number string Tekst zastępczy (placeholder) dla formularza numeru karty
date string Tekst zastępczy (placeholder) dla formularza daty ważności karty
cvv string Tekst zastępczy (placeholder) dla formularza kodu cvv

3.4 Błędy

Obiekt error składa się z tablicy obiektów messages, w których zawarta jest szczegółowa informacja o błędach.

Obiekt messages

Pole Opis
type Rodzaj błędu. Możliwe wartości to validate gdy źródłem błędu jest sprawdzanie poprawności wpisanych wartości pól formularza oraz technical dla pozostałych błędów.
code Kod błędu.
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.

Lista błędów

Kod błędu Opis
Błędy typu validate
error.validation.card.empty Pusty numer karty.
error.validation.card.length Nieprawidłowa długość numeru karty.
error.validation.card.number Nieprawidłowy numer karty.
error.validation.card.unsupported Niewspierany rodzaj karty. Obsługiwane typy karty to Visa, Mastercard i Maestro.
error.validation.expDate.empty Pusta data ważności karty
error.validation.expDate.past Data ważności karty jest z przeszłości
error.validation.expDate.value Data ważności karty jest nieprawidłowa
error.validation.cvv.empty Pusty CVV
error.validation.cvv.value Nieprawidłowy CVV
Błędy typu technical
error.tokenization Wystąpił błąd podczas tokenizacji. W obiekcie parameters w polu error jest informacja o przyczynie błędu.
error.send.cvv Wystąpił błąd podczas wysyłania CVV. W obiekcie parameters w polu error jest informacja o przyczynie błędu.
error.network Wystąpił błąd komunikacji sieciowej. W obiekcie parameters w polu error jest informacja o przyczynie błędu.
{
    "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"
            }
        ]
    }
}

3.5 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.

W przypadku elementów zastępczych przekazujemy je 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świetlamy swój komunikat 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.

Należy przy zmianie wielkości okna preglądarki użyć metody update do aktualizacji opcjach 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]);
    }
});

4 Widget

To rozwiązanie zostało wycofane z użycia, a ten rozdział służy jedynie jako referencja dla istniejących integracji. Nie zalecamy nowych integracji za pomocą tego rozwiązania, należy używać Secure Form.

4.1 Widget pop-up

Ten rodzaj widgeta może przekazać dane za pomocą metody POST albo funkcji callback.
Dane przekazywane przez widget wyglądają następująco:
                    value:"TOK_1IOPVS7EMKVT4GYvs44XPxAOb8yc",
                    maskedCard:"424242******4242",
                    tokenType:"STANDARD",
                    type:"CARD_TOKEN"
                
Nazwa parametru Opis
value token jednorazowy ("TOK_") - wygasa po pierwszym użyciu
maskedCard maskowany numer karty
tokenType stała wartość (zawsze STANDARD)
type stała wartość (zawsze CARD_TOKEN)

Implementacja widgetu

  1. Należy włączyć do strony sklepu formularz z przyciskiem płatności. W tym celu należy podać właściwy parametr:
                                    <form action="http://exampledomain.com/processOrder.php" method="post">
                                        <button id="pay-button">Pay now</button>
                                    </form>
                            
  2. Należy dołączyć skrypt JS wywołujący widget podając odpowiednie parametry i wyliczyć SIG.
    Uwaga: widget może przekazać dane poprzez metodę HTTP POST lub poprzez funkcję callback. Aby jej użyć, należy w skrypcie podać parametr success-callback.
    Dla porównania przykład dot. widgetu inline:
                                <script
                                    src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                                    pay-button="#pay-button"
                                    merchant-pos-id="145227"
                                    shop-name="Nazwa sklepu"
                                    total-amount="9.99"
                                    currency-code="PLN"
                                    customer-language="pl"
                                    store-card="true"
                                    customer-email="email@exampledomain.com"
                                    sig="250f5f53e465777b6fefb04f171a21b598ccceb2899fc9f229604ad529c69532">
                                </script>
                            
  3. Aby wyliczyć SIG, należy użyć następującego algorytmu: Parametry widgeta.
W niektórych przypadkach, PayU może poprosić o kod CVV2/CVC2. W tym przypadku należy wywołać specjalny widget:
                    <script
                        src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                        merchant-pos-id="145227"
                        shop-name="Shop name"
                        total-amount="9.99"
                        currency-code="PLN"
                        customer-language="pl"
                        widget-type="cvv"
                        cvv-url="https://secure.payu.com/api/v2/token/token.json?refReqId=c4b31c492b0a5aaa9eb12d07578286a0"
                        cvv-success-callback="cvvSuccess"
                        sig="e08f617240bac43954bcbb5782a0ce203a23717ba9760be71c9ea8cab127ad12">
                    </script>
                    <script type="text/javascript">
                        function cvvSuccess() {
                            //wyświetla stronę o udanym zainicjowaniu płatności
                        }
                    </script>
                

4.2 Widget inline

Widget inline to modyfikacja widgeta pop-up. Nie zawiera on nagłówka z nazwą sklepu i kwoty zakupu oraz wykorzystuje dodatkowe parametry.
  1. Widget inline jest wlewany w stronę, jeśli zawiera ona następujący element:
                                <div id="payu-widget"></div>
                            
  2. Wlany widget może przekazać dane poprzez metodę HTTP POSTlub poprzez funkcję callback. Aby jej użyć, należy w skrypcie podać parametr success-callback. Funkcja callback może wyglądać jak poniżej (poniższy przykład pozwala wyświetlić dane w konsoli w przeglądarce):
                                <script>
                                function test($data) {
                                    console.log("callback");
                                    console.log($data);
                                }
                                </script>
                            
  3. Aby wyświetlić wlany widget, należy dołączyć do strony skrypt, podając parametry zgodnie ze swoimi preferencjami. Poniższy przykład wyświetli widget z białym tłem, bez znaku PayU, w trybie "Użyj" (zamiast "Płać"). Aby sprawdzić jego działae, wystarczy skopiować i wkleić poniższy skrypt do swojej strony, razem z podanym wyżej elementem div i funkcją callback.
                                 <script
                                     src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                                     merchant-pos-id="145227"
                                     shop-name="TEST"
                                     total-amount="12345"
                                     currency-code="PLN"
                                     customer-language="en"
                                     store-card="true"
                                     payu-brand="false"
                                     success-callback="test"
                                     widget-mode="use"
                                     customer-email="test@test.com"
                                     sig="203ec8c4b9571ce6b4c03058f57264f04d06d00a86da19390d47ba1be4551578">
                                 </script>
                             
  4. Aby wyliczyć SIG, należy użyć następującego algorytmu: Parametry widgeta.

4.3 Parametry

Parametr SIG (służący zabezpieczeniu widgeta przed modyfikacją) należy wyliczyć w następujący sposób:

  1. Posortować alfabetycznie parametry wg nazw potrzebne do wyliczenia SIGa (zob. tab. niżej, np. parametr customer-email powinien być przed parametrem customer-language itd.).
  2. Połączyć (tj. "skonkatenować") wartości parametrów wg kolejności sortowania.
  3. Do tak powstałego ciągu znaków należy dodać wartość klucza prywatnego - widocznego w Panelu PayU jako 'Drugi klucz (MD5)'.
  4. Wykonać funkcję SHA256 na całym ciągu znaków.
  5. Wstawić wynik funkcji jako parametr SIG przy wywołaniu widgeta.

Przykład wyliczenia wartości sig:

Parametry widgeta, które mają zostać użyte należy posortować wg nazwy (klucza) parametru:

  1. currency-code: PLN
  2. customer-email: test@test.com
  3. customer-language: pl
  4. merchant-pos-id: 145227
  5. shop-name: TEST
  6. total-amount: 12345

Następnie należy połączyć wartości parametrów i uzyskać ciąg znaków jak poniżej:

PLNtest@test.compl145227TEST12345

i dodać do niego wartość klucza drugiego (w przykładzie użyty został testowy POS produkcyjny). Uzyskany ciąg znaków, na którym na którym należy użyć funkcji skrótu SHA256 to:

PLNtest@test.compl145227TEST1234513a980d4f851f3d9a1cfc792fb1f5e50

A uzyskana wartość sig, po zastosowaniu funkcji skrótu, to:

cf16a6302c26e6f39b580be859caf1fe396e81366c4d8f56fb765fb374e8ed3a

Parametry skryptu wywołującego widget:

Nazwa parametru Wymagany Wymagany dla SIG Opis
pay-button tak nie Selektor CSS dla przycisku płatności.
merchant-pos-id tak tak Identyfikator POSa użytego do płatności.
shop-name tak tak Nazwa sklepu, która pojawi się na widgecie.
total-amount tak tak Kwota płatności, która pojawi się na widgecie.
currency-code tak tak Waluta płatności. Musi być zgodna z walutą POSa.
customer-language tak tak Język w którym zostanie wyświetlony widget. Dostępne wartości to: pl, bg, cs, de, en, es, fr, hu, it, pt, ro, sk.
customer-email nie tak Email posiadacza karty.
widget-type nie nie Domyślnie widget pokazuje formularz do podania pełnych danych karty. Podanie wartości 'cvv' wywoła widget służący tylko do podania danych karty. Widget 'cvv' wymaga zestawu nieco innych parametrów (zob. tabela poniżej).
store-card nie tak Wartości 'true'/'false'. Wartość 'true' oznacza wyświetlenie widgeta z opcją 'Zapisz kartę'.
recurring-payment nie tak Wartości 'true'/'false'. Podanie wartości 'true' wyświetla widget w wersji dla płatności cyklicznych (wówczas należy zadeklarować 'true' również dla parametru store-card.
payu-brand nie tak Wartości: true/false (domyślnie: "true"). Wyświetla widget bez znaku PayU (tylko dla widgeta w wersji inline).
widget-mode nie tak Wartości: pay/use (domyślnie: "pay"). Konfiguruje przyciski na widgecie. Opcja "Pay" zakłada, że płatność następuje zaraz po użyciu widgeta. Opcja "use" pozwala pobrać dane karty, bez ich natychmiastowego użycia.
success-callback nie nie Nazwa funkcji, która przechwytuje dane przekazane przez widget.
sig tak nie Wartość SIG wyliczona zgodnie z opisem powyżej.
Parametry widgeta pobierającego kod CVV2/CVC2:
Nazwa parametru Wymagany Wymagany dla SIG Opis
merchant-pos-id tak tak Identyfikator POSa użytego do płatności.
shop-name tak tak Nazwa sklepu, która pojawi się na widgecie.
total-amount tak tak Kwota płatności, która pojawi się na widgecie.
currency-code tak tak Waluta płatności. Musi być zgodna z walutą POSa.
customer-language tak tak Język w którym zostanie wyświetlony widget. Dostępne wartości to: pl, en, cs oraz de, es, fr, it, pt.
widget-type tak nie Należy użyć wartości 'cvv'
cvv-url tak tak Musi mieć wartość równą albo 'redirectUri' (zwróconą przez PayU w komunikacie OrderCreateResponse z kodem WARNING_CONTINUE_CVV) albo, w przypadku wywołania widgetu po udanym powrocie ze strony banku-wydawcy karty w procesie 3DS, wartość 'refReqId' dodaną jako query string do parametru 'continueUrl' podanego w OrderCreateRequest.
cvv-success-callback nie nie Funkcja callback wywoływana po tym jak płatnik podał kod CVV2/CVC2 i została dokonana autoryzacja karty.
sig tak nie Wartość SIG wyliczona zgodnie z opisem powyżej.

5 Formularz

To rozwiązanie zostało wycofane z użycia, a ten rozdział służy jedynie jako referencja dla istniejących integracji. Nie zalecamy nowych integracji za pomocą tego rozwiązania, należy używać Secure Form.

5.1 Pobranie danych karty

W przypadku włączenia płatności kartowych jesteś zobowiązany do przestrzegania norm PCI DSS.

Powinieneś co roku wypełnić Self-Assessment Questionnaire (SAQ), a także wykonywać kwartalny skan sieci przeprowadzany przez jednostkę weryfikującą - Approved Scan Vendor (ASV).

Dodatkowo, jeżeli przetwarzasz ponad 6 milionów transakcji rocznie powinieneś wykonać Report on Compliance (ROC), przeprowadzany przez certyfikowanego audytora - Qualified Security Assessor (QSA).

Więcej informacji możesz znaleźć na stronieSecurity Standards Council.
Należy dołączyć skrypty OpenPayU, które umożliwiają bezpieczne przesyłanie danych karty bezpośrednio do PayU:
                    <script src="https://secure.payu.com/res/v2/openpayu-2.1.js"></script>
                    <script src="https://secure.payu.com/res/v2/plugin-token-2.1.js"></script>                

Utwórz formularz pobrania danych karty w sposób, który umożliwi poprawne działanie skryptu. W tym celu umieść elementy typu "input" na swojej stronie, których atrybuty "class" są nazwane tak jak w przykładzie poniżej.

Uwaga: nie jest konieczne umieszczenie elementów "input" w elemencie "form" ponieważ dane karty nie powinny zostać wysłane na Twój serwer.

W przypadku kiedy chcesz wysłać dane karty i spełniać wszystkie wymogi określone przez PCI DSS, zob. rozdz. Dane kartowe w postaci tekstowej.

                         <table>
                            <tr>
                                <td>Numer karty</td>
                                <td><input type="text" class="payu-card-number"></td>
                            </tr>
                            <tr>
                                <td>CVV2/CVC2</td>
                                <td><input type="text" class="payu-card-cvv"></td>
                            </tr>
                            <tr>
                                <td>miesiąc</td>
                                <td><input type="text" class="payu-card-expm"></td>
                            </tr>
                            <tr>
                                <td>rok</td>
                                <td><input type="text" class="payu-card-expy"></td>
                            </tr>
                            <tr>
                                <td>Akceptacja regulaminu Konta PayU i zgoda na zapisanie karty</td>
                                <td><input type="checkbox" value="false" class="payu-agreement"></td>
                            </tr>                            
                            <input type="hidden" class="payu-customer-email" value="...@...">
                                <tr>
                                    <td><input type="submit" id="payu-cc-form-submit"></td>
                                </tr>
                        </table>                                   
                

Skrypty wyszukują następujące nazwy klas:

Nazwa Wymagana Opis
payu-card-cardholder opcjonalna Imię i nazwisko posiadacza karty.
payu-card-number tak Numer karty płatniczej.
payu-card-cvv tak Kod bezpieczeństwa karty (CVV2/CVC2).
payu-card-expm tak Miesiąc daty ważności.
payu-card-expy tak Rok daty ważności.
payu-agreement tak Wartości true/false. Oznacza zgodę posiadacza karty na zapisanie danych i regulamin Konta PayU. Przy wartości false PayU nie zwróci tokena wielorazowego.
payu-customer-email opcjonalna Adres email posiadacza karty.

Należy dodać skrypt, który wysyła dane karty do PayU:
    (function () {
            var button = document.querySelector('#payu-cc-form-submit');
            button.addEventListener('click', function (event) {
                OpenPayU.merchantId = 'your POS ID';
                var result = OpenPayU.Token.create({}, function (data) {
                    // obsłuż rezultat tokenizacji, możliwe kody odpowiedzi są poniżej
                });
                if (result !== true) {
                    // żądanie tokenizacji nie zostało wysłane, 
                    // sprawdź błędy walidacji w obiekcie "result"
                }
            }, false);
        })();           
                
W przypadku udanej tokenizacji, obiekt "result" ma wartość true, a poniższe obiekty są przekazane do funkcji callback. Wartość zmiennej token należy przekazać do backendu i dołączyć do OrderCreateRequest (zob. rozdz. Płatność tokenem).
            
         {
           	data: {
           		mask: "444433******1111",
           		token: "TOK_1JKQSX1FMNTU831B8a6z4LDHbzsv",
           		type: "STANDARD"
           	},
           	status: {
           		statusCode: "SUCCESS",
           		codeLiteral: "SUCCESS",
           		code: "0"
           	}
         }        
W przypadku błędów walidacji, "result" zawierać może następujące dane:
            {
                card.expirationDate: "formatInvalid",
                card.expirationMonth: "formatInvalid",
                card.expirationYear: "formatInvalid",
                card.number: "unsupportedType"
             }           

Kody odpowiedzi na żądanie tokenizacji:

Code Status code Code literal Opis
0 SUCCESS SUCCESS Udana tokenizacja, odp. zawiera obiekt "data".
100 ERROR_INTERNAL GENERAL_ERROR Inny bład.
101 ERROR_UNKNOWN_MERCHANT_POS UNKNOWN_MERCHANT Nieprawidłowa wartość POS ID.
4003 ERROR_VALUE_INVALID CARD_INVALID_CVV Długość CVV2 jest nieprawidłowa (może zawierać tylko 3 lub 4 znaki).
4100 SERVICE_NOT_AVAILABLE CARD_TOKENIZATION_DISABLED Usługa tokenizacji nie została włączona dla danego POS ID.
4101 SERVICE_NOT_AVAILABLE CARD_MERCHANT_INACTIVE Płatność kartą nie została włączona dla danego POS ID.

"Device fingerprint"

Device fingerprint to informacja zebrana o urządzeniu w celu jego identyfikacji.

Wartość "device fingerprint" jest tworzona przez statyczną funkcję Fingerprint2.get, która zastąpiła skrypt new Fingerprint2().get, przez to wynik nie będzie już automatycznie hash'owany.

Potrzebne biblioteki można znaleźć Tutaj.

Użycie:
                    var options = {}
                    Fingerprint2.get(options, function (components) {
                        // components is array of {key: 'foo', value: 'component value'}
                        ...
                    })
                    
                    // or
                    
                    Fingerprint2.getPromise(options).then(function (components) {
                        // components is array of {key: 'foo', value: 'component value'}
                        ...
                    })
                
Aby stworzyć hash fingerprint należy użyć:
                    Fingerprint2.get(options, function (components) {
                        var values = components.map(function (component) { return component.value })
                        var murmur = Fingerprint2.x64hash128(values.join(''), 31)
                    })
                

Uzyskaną wartość należy przesłać do PayU poprzez backend (zob. niżej).

5.2 Pobranie kodu CVV2

Twoja strona powinna również obsłużyć pobranie brakującego kodu CVV2.
Następujący element musi wówczas zostać wyświetlony i wypełniony przez płatnika:
<input type="text" class="payu-card-cvv">

Potrzeba pobrania wyłącznie kodu CVV2 może wystąpić w przypadku konieczności uwierzytelnienia płatności tokenem kartowym.

Wystąpić mogą 2 przypadki:

  1. Obciążenie z pełnym uwierzytelnieniem. Kod CVV2 musi zostać pobrany kiedy płatnik powraca na Twoją stronę po uwierzytelnieniu poprzez 3DS - kod WARNING_CONTINUE_CVV jest podany w zapytaniu (query string) dodanym do adresu strony podanej jako continueUrl w OrderCreateRequest. Przykład zapytania:
                            https://your.shop.com/payment?statusCode=WARNING_CONTINUE_CVV&refReqId=b20399775cbf48a00469280499bdd912
                        
    Przykład skryptu (kod poniżej powinien zostać wywołany kiedy płatnik użyje przycisku do wysłania CVV2):
                                var url = "refReqId=" + 'wartość refReqId podana w zapytaniu (query string)';
                                var options = {url: url};
                                OpenPayU.authorizeCVV(options, function(data) {
                                    if (data.status === 'SUCCESS') {
                                        // CVV2 przesłany poprawnie, można ukryć pole input
                                    } else {
                                        // wystąpił błąd (zob. tabelę powyżej)
                                    }
                                }); 
                            
  2. Obciążenie z częściowym uwierzytelnieniemn (tylko CVV2). Status WARNING_CONTINUE_CVV jest podany w odpowiedzi do OrderCreateRequest. Przykład takiej odpowiedzi znajduje się w rozdz.Płatność tokenem . Przykład skryptu (kod poniżej powinien zostać wywołany kiedy płatnik użyje przycisku do wysłania CVV2):
                           var options = {url: 'wartość redirectUri z OrderCreateResponse'};
                           OpenPayU.authorizeCVV(options, function(data) {
                                if (data.status === 'SUCCESS') {
                                        // CVV2 przesłany poprawnie, można ukryć pole input
                                    } else {
                                        // wystąpił błąd (zob. tabelę powyżej)
                                    }
                           });     
                        

6 Płatność tokenem

Modyfikacja back-end

Token wielorazowy (TOKC_) tworzony jest po pierwszym użyciu tokenu jednorazowego (TOK_).

Komunikat OrderCreateRequest należy rozszerzyć o sekcję Buyer oraz sekcję payMethods podając jako wartość token jednorazowy (TOK_). Tworzenie zamówienia (Order) poprzez REST API jest opisane w rozdziale Tworzenie zamówienia.

W przypadku płatności tokenem wielorazowym (TOKC_) należy pamiętać o ustawieniu parametru cardOnFile, który informuje o stronie inicjującej płatność:
  • FIRST
  • STANDARD_CARDHOLDER
  • STANDARD_MERCHANT
Szczegółowy opis wartości parametru cardOnFile możesz znaleźć w sekcji Parametry JSON.
Odpowiednie ustawienie tego parametru pozwoli na zwiększenie konwersji dla kart płatniczych.

Przykład zamówienia wykorzystującego token jednorazowy (TOK_):

                    curl -v -X POST https://secure.payu.com/api/v2_1/orders \
                    -H "Content-Type: application/json" \
                    -H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
                    -d '{
                          "notifyUrl":"https://your.eshop.com/notify",
                          "customerIp":"127.0.0.1",
                          "merchantPosId":"145227",
                          "description":"Laptop",
                          "currencyCode":"PLN",
                          "totalAmount":"15000",
                          "extOrderId":"[generateExtOrderId]",
                          "products":[
                             {
                                "name":     "Laptop",
                                "unitPrice":"15000",
                                "quantity": "1"
                             }
                          ],
                          "buyer": {
                              "email": "john.doe@example.com",
                              "firstName": "John",
                              "lastName": "Doe",
                              "language": "pl"
                          },
                          "payMethods": {
                              "payMethod": {
                                   "value": "TOK_1IHRPT6HKSSS3H62K0GS8pElP862",
                                   "type":  "CARD_TOKEN"
                              }
                          },
                          "deviceFingerprint": "[generateFingerPrint2]"
                      }'
                

Uwierzytelnienie komunikatu jest opisane w rozdziale Uwierzytelnienie.

Uwaga! POS użyty w przykładzie nie ma włączonej usługi tokenizacji.

Przykład odpowiedzi do komunikatu OrderCreateResponse z kodem SUCCESS:

                    {
                         "orderId": "ORDER_ID",
                         "payMethods": {
                             "payMethod": {
                                 "card": {
                                     "number": "424242******4242",
                                     "expirationMonth": "12",
                                     "expirationYear": "2017"
                                 },
                                 "type": "CARD_TOKEN",
                                 "value": "TOKC_KPNZVSLJUNR4DHF5NPVKDPJGMX7"
                             }
                         },
                         "status": {
                            "statusCode": "SUCCESS",
                            "statusDesc": "Request successful"
                         }
                    }
                

Oznacza to, że zamówienie zostało przyjęte bez potrzeby dodatkowego uwierzytelnienia płacącego (3D Secure lub podanie kodu CVV2) i możesz oczekiwać na status zamówienia na adres podany w parametrze notifyUrl w komunikacie OrderCreateRequest.

Przykład zamówienia zainicjowanego przez merchanta i wykorzystującego token wielorazowy (TOKC_):

                    curl -v -X POST https://secure.payu.com/api/v2_1/orders \
                    -H "Content-Type: application/json" \
                    -H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
                    -d '{
                        "notifyUrl":"https://your.eshop.com/notify",
                        "customerIp":"127.0.0.1",
                        "merchantPosId":"145227",
                        "description":"Laptop",
                        "currencyCode":"PLN",
                        "totalAmount":"15000",
                        "cardOnFile": "STANDARD_MERCHANT",
                        "extOrderId":"9xl0x8nr1wk7m0i3ltqbja",
                        "products":[
                            {
                               "name":     "Laptop",
                               "unitPrice":"15000",
                               "quantity": "1"
                            }
                        ],
                        "buyer": {
                            "email": "john.doe@example.com",
                            "firstName": "John",
                            "lastName": "Doe",
                            "language": "en"
                        },
                        "payMethods": {
                            "payMethod": {
                                "value": "TOKC_2IHRST6HKSST3H62K2GS8pElI862",
                                "type":  "CARD_TOKEN"
                            }
                        },
                        "deviceFingerprint": "0372098a4a90927db053463454491d78"
                    }'
                

6.1 Obsługa 3DS

W przypadku odpowiedzi z kodem WARNING_CONTINUE_3DS, należy przekierować płatnika na stronę (parametr redirectUri) banku, wydawcy karty w celu dodatkowego uwierzytelnienia płatności w procesie 3D Secure.

Przykład odpowiedzi z kodem WARNING_CONTINUE_3DS dla zamówienia wykorzystującego token wielorazowy (TOKC_):

                    {
                        "status": {
                            "statusCode": "WARNING_CONTINUE_3DS",
                            "severity": "WARNING"
                        },
                        "redirectUri": "{redirectUri}",
                        "threeDsProtocolVersion": "3DS1",
                        "orderId": "ORDER_ID"
                    }
                

Przykład odpowiedzi z kodem WARNING_CONTINUE_3DS dla pierwszego zamówienia wykorzystującego token jednorazowy (TOK_):

                    {
                        "status": {
                            "statusCode": "WARNING_CONTINUE_3DS",
                            "severity": "WARNING"
                        },
                        "redirectUri": "{redirectUri}",
                        "threeDsProtocolVersion": "3DS1",
                        "orderId": "ORDER_ID",
                        "payMethods": {
                            "payMethod": {
                                "card": {
                                    "number": "401200******1112",
                                    "expirationMonth": 12,
                                    "expirationYear": 2020
                                },
                                "type": "CARD_TOKEN",
                                "value": "TOKC_H1ZOE5YXLJPKMUUSDSJRARON0WH"
                            }
                        }
                    }
                
Płatnik po uwierzytelnieniu się na stronie wydawcy karty w procesie 3DS jest przekierowany z powrotem na adres strony podanej jako continueUrl w OrderCreateRequest. Przy czym do adresu w zapytaniu (query string) dodawane są dwa parametry:
  • statusCode - wartość SUCCESS lub WARNING_CONTINUE_CVV;
  • refReqId - losowy alfanumeryczny ciąg znaków.
Przykład:
https://your.shop.com/payment?statusCode=SUCCESS&refReqId=5c867936fbb3cc2c373820b4550b4645

W przypadku gdy parametr statusCode przyjął wartość SUCCESS, to oznacza, że zamówienie zostało przyjęte bez potrzeby kolejnego uwierzytelnienia płacącego i możesz oczekiwać na status zamówienia.

Natomiast gdy parametr statusCode przyjął wartość WARNING_CONTINUE_CVV, to wówczas powinieneś wyciągnąć wartość parametru refReqId wraz z nazwą parametru, przykładowo:

refReqId=5c867936fbb3cc2c373820b4550b4645
Następnie w zależności od sposobu integracji:

6.2 Obsługa kodu CVV2

W przypadku odpowiedzi z kodem WARNING_CONTINUE_CVV, należy poprosić płatnika o podanie kodu CVV2/CVC2. W tym celu pobierz wartość parametru redirectUri i i w zależności od sposobu integracji:
Przykład odpowiedzi z kodem WARNING_CONTINUE_CVV:
                    {
                        "orderId": "ORDER_ID",
                        "status": {
                            "statusCode": "WARNING_CONTINUE_CVV",
                            "severity": "WARNING"
                        },
                        "redirectUri": "{redirectUri}"
                    }
                

Przykładowa wartość parametru redirectUri:

https://secure.payu.com/api/v2/token/token.json?refReqId=11ed628ebe88ef6837d90ebb26f1a8b9

Po podaniu przez płacącego kodu CVV2/CVC2 możesz oczekiwać na status zamówienia.

7 Pobieranie tokenów (retrieve)

Pobieranie metod płatności

Zalecamy, aby metody płatności dostępne dla danego użytkownika nie były przechowywane lokalnie przez sklep, ale raczej pobierane od PayU. Pobierane są zarówno zapisane metody płatności (tokeny) oraz standardowe metody płatności. Użycie tej usługi daje następujące korzyści:

- zwracane są wyłącznie metody płatności dostępne w danym momencie dla danego użytkownika,

- zwrócone tokeny są zawsze aktualne i zsynchronizowane z aktywnym Kontem PayU danego użytkownika.

W celu pobrania metod płatności należy najpierw uzyskać token dostępowy OAuth2.

Uzyskiwanie tokena dostępowego OAuth

Aby uzyskać token dostępowy należy wywołać żądanie metodą POST na endpoint /pl/standard/user/oauth/authorize.

Żądanie należy wywołać z grant_type równym trusted_merchant.

apiary

Przykładowe żądanie:

                    
                    curl -X POST https://secure.payu.com/pl/standard/user/oauth/authorize \
                       -H "Cache-Control: no-cache" 
                       -H "Content-Type: application/x-www-form-urlencoded" 
                       -d 'grant_type=trusted_merchant&client_id=[provided by PayU]&client_secret=[provided by PayU]&email=[users email]&ext_customer_id=[Id of the customer used in merchant system]' 
                       
                

ext_customer_id jest identyfikatorem klienta w systemie merchanta, jest on konieczny w celu poprawnego wygenerowania tokena OAuth.

Przykładowa odpowiedź (HTTP 200):
{
    "access_token": "4099c2c3-276f-488a-90e2-32620ac441dc",
    "token_type": "bearer",
    "expires_in": 43199,
    "grant_type": "trusted_merchant"
}
            

Pobieranie metod płatności

Należy wstawić uzyskany token dostępowy do nagłówka i wywołać żądanie metodą GET na endpoint api/v2_1/paymethods .

apiary

Przykładowe żądanie:
curl -X GET https://secure.payu.com/api/v2_1/paymethods \
   -H "Authorization: Bearer 87ad751f-7ea5-4023-a16f-04b6647a07f5" 
   -H "Cache-Control: no-cache" 

                

Przykładowa odpowiedź (HTTP 200). Opis poszczególnych pól jest poniżej.

{  
   "cardTokens":[  
      {  
         "cardExpirationYear":"2017",
         "cardExpirationMonth":"12",
         "cardNumberMasked":"411111******1111",
         "cardBrand":"VISA",
         "value":"TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE",
         "brandImageUrl":"http://static.payu.com/images/mobile/visa.png",
         "preferred":true,
         "status":"ACTIVE"
      },
      {  
         "cardExpirationYear":"2014",
         "cardExpirationMonth":"12",
         "cardNumberMasked":"424242******4242",
         "cardBrand":"VISA",
         "value":"TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE",
         "brandImageUrl":"http://static.avocado.qxlint/images/mobile/visa.png",
         "preferred":false,
         "status":"EXPIRED"
      }
   ],
   "pexTokens":[  
      {  
         "accountNumber":"5311...7744",
         "payType":"mtex",
         "value":"TOKE_XPJ4UKJGHVRPMQPGB6X1JJQCUSS",
         "name":"account name set by the user",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pex_mbank.png",
         "preferred":false,
         "status":"ACTIVE"
      }
   ],
   "payByLinks":[  
      {  
         "value":"c",
         "name":"Płatność online kartą płatniczą",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_c.png",
         "status":"ENABLED",
         "minAmount": 50,
         "maxAmount": 100000
      },
      {  
         "value":"o",
         "name":"Pekao24Przelew",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_o.png",
         "status":"DISABLED",
         "minAmount": 50,
         "maxAmount": 100000
      },
      {  
         "value":"ab",
         "name":"Płacę z Alior Bankiem",
         "brandImageUrl":"http://static.payu.com/images/mobile/logos/pbl_ab.png",
         "status":"TEMPORARY_DISABLED",
         "minAmount": 50,
         "maxAmount": 100000
      }
   ]
}          
            

cardTokens

Ta sekcja zostanie zwrócona jako pusta, jeśli użytkownik nie ma żadnych aktywnych lub wygasłych tokenów.
Parametr Opis
cardExpirationYear Rok ważności karty w formacie RRRR
cardExpirationMonth Miesiąc ważności karty w formacie MM
cardNumberMasked Maskowany numer karty (pierwsze 6 i ostatnie 4 cyfry).
cardBrand Rodzaj karty. Wartości: 'VISA', 'MASTERCARD', 'MAESTRO'. Inne rodzaje nie są wspierane. VISA oznacza różne marki kart Visa, w tym Visa Electron. MASTERCARD oznacza również MasterCard Debit.
value Wartość tokena.
brandImageUrl Odnośnik do grafiki na serwerze PayU reprezentującej logo karty.
preferred Wartości true/false; 'true' oznacza ostatnio użyty token.
status Wartości: 'ACTIVE' i 'EXPIRED'.

'EXPIRED' oznacza tokeny wygasłe, można ich nie prezentować lub prezentować wraz z prośbą o podanie aktywnego numeru karty (tj. ponowne podanie numeru karty wygasłej wraz z nową datą ważności i CVV2/CVC2 lub zupełnie nowego numeru).

Token nie będzie prezentowany, jeśli został anulowany przez użytkownika lub zablokowany ze względów bezpieczeństwa przez PayU.

pexTokens

Ta sekcja będzie pusta jeśli użytkownik nie ma żadnych aktywnych tokenów.

Tokeny PEX oznaczają rachunki bankowe dostępne przez usługę PayU|Express.

Parametr Opis
accountNumber Pierwsze i ostatnie 4 cyfry rachunku bankowego.
payType Represents payType of the token. Oznacza typ platności (bank) powiązany z danym tokenem.
name Nazwa konta nadana przez użytkownika.
value Wartość tokena.
brandImageUrl Odnośnik do grafiki na serwerze PayU reprezentującej bank.
preferred Wartości true/false; 'true' oznacza ostatnio użyty token.
status Wartości: 'ACTIVE'.

Token nie będzie prezentowany, jeśli został anulowany przez użytkownika lub zablokowany ze względów bezpieczeństwa przez PayU.

payByLinks

payByLinks to metody płatności, które zawsze wymagają przekierowania. Oznaczają zarówno szybkie przelewy (pay-by-links), tradycyjny przelew, raty lub standardową płatność kartą bez tokenizacji poprzez formularz serwowany przez PayU.
Parametr Opis
value Wartość metody płatności. Dostępne wartości są tutaj.
name Nazwa typu płatności nadana przez PayU.
brandImageUrl Odnośnik do grafiki na serwerze PayU reprezentującej metodę płatności.
status Możliwe wartości: 'ENABLED' (aktywna), 'DISABLED' (nieaktywna), 'TEMPORARY_DISABLED' (czasowo nieaktywna z uwagi na brak rozliczeń online po stronie banku - wartość wystąpi po dokonaniu dodatkowej konfiguracji przez PayU).

8 Usuwanie tokenów

Usuwanie tokena płatniczego

W przypadku kiedy użytkownik zamyka swoje konto w sklepie internetowym lub chce usunąć zapisaną kartę, token należy skasować.

W tym celu należy wysłać żądanie z metodą DELETE na endpoint https://secure.payu.com/api/v2_1/tokens/{tokenValue}

Nagłówek powinien zawierać token dostępowy OAuth typu trusted.merchant.

Przykład:
curl -X DELETE https://secure.payu.com/api/v2_1/tokens/TOKC_XATB7DF8ACXYTVQIPLWTVPFRKQE \
   -H "Authorization: Bearer cccbbc40-8113-443b-b4ea-c4b266272b22" 
   -H "Cache-Control: no-cache" 
            

9 Dane kartowe w postaci tekstowej

Uwaga! Ten sposób integracji jest przeznaczony tylko dla punktów płatności, które spełniają wymogi określone przez PCI DSS i są uprawnione do przetwarzania danych kartowych po swojej stronie. Wymagają również dodatkowej konfiguracji.. Dlatego przed przystąpieniem do integracji należy skontaktować się z opiekunem handlowym w PayU.

Do standardowego zamówienia OrderCreateRequest należy dodać sekcję payMethods.payMethod zawierającą dane kartowe i parametr cardOnFile z jedną z poniższych wartości:

  • FIRST
  • STANDARD_CARDHOLDER
  • STANDARD_MERCHANT
Szczegółowy opis wartości parametru cardOnFile możesz znaleźć w sekcji Parametry JSON.

Odpowiednie ustawienie tego parametru pozwoli zwiększyć konwersję dla kart płatniczych i zagwarantować odpowiednie bezpieczeństwo transakcji.

Jeżeli jest to płatność jednorazowa kartą, wówczas parametr cardOnFile należy pominąć.

Przykład sekcji payMethods.payMethod uzupełnionej o dane kartowe w postaci tekstowej:

                    "payMethods": {
                        "payMethod": {
                            "card": {
                                "number":"5100052384536818",
                                "expirationMonth":"11",
                                "expirationYear":"2020",
                                "cvv":"123"
                            }
                        }
                    },

                

Przykład sekcji payMethods.payMethod uzupełnionej o dane kartowe w postaci tekstowej oraz identyfikator pierwszej transakcji cyklicznej lub Card-on-File:

                
                "payMethods": {
                    "payMethod": {
                        "card": {
                            "number":"5100052384536818",
                            "expirationMonth":"11",
                            "expirationYear":"2020",
                            "cvv":"123",
                            "firstTransactionId": "MCC0111LL1121"
                        }
                    }
                },
                
            

Również dla płatności z podaniem danych kartowych w postaci tekstowej należy być przygotowanym na obsługę odpowiedzi z kodem WARNING_CONTINUE_3DS lub WARNING_CONTINUE_CVV.

10 Zewnętrzne parametry 3D Secure

W przypadku gdy jesteś zintegrowany z własnym dostawcą usługi 3D Secure (zwany dalej w skrócie 3DS) masz możliwość przekazania parametrów będących wynikiem procesu obsługi 3DS w komunikacie OrderCreateRequest. Standardowy komunikat OrderCreateRequest należy rozszerzyć o sekcję payMethods.threeDsData zawierającą dane wynikowe procesu 3DS.

Jeżeli wynik obsługi 3DS zostanie dostarczony wraz z zamówieniem, to kod odpowiedzi WARNING_CONTINUE_3DS nigdy nie zostanie zwrócony.

Przykład uzupełnionej sekcji threeDsData dla uwierzytelnienia 3DS zakończonego sukcesem

                    
                    "payMethods": {
                        "payMethod": {
                            ...
                            },
                            "threeDsData": {
                                "status3Ds": "AY",
                                "status3DsDescription": "3ds successfull",
                                "xid": "PL345346456",
                                "eciCode": 5,
                                "cavv": "AAABBBEAUAAAABgICABQAAAAAAA="
                            }
                        }
                    }
                    
                

Przykład uzupełnionej sekcji threeDsData dla uwierzytelnienia 3DS2.x zakończonego sukcesem

                
                "payMethods": {
                    "payMethod": {
                        ...
                        },
                        "threeDsData": {
                            "status3Ds": "Y",
                            "status3DsDescription": "3ds2.x successfull",
                            "dsTransactionId": "3b31b19d-1c06-4ea4-a85a-00af10c66588",
                            "eciCode": 5,
                            "cavv": "AAABBBEAUAAAABgICABQAAAAAAA="
                        }
                    }
                }
                
            

Przykład uzupełnionej sekcji threeDsData dla karty, której wydawca nie wspiera 3DS

                    
                    "payMethods": {
                        "payMethod": {
                            ...
                            },
                            "threeDsData": {
                                "status3Ds": "VN",
                                "status3DsDescription": "Card is not participating in 3DS",
                                "xid": "PL345346456"
                            }
                        }
                    }
                    
                

Przykład uzupełnionej sekcji threeDsData dla próby uwierzytelnienia 3DS

                    
                    "payMethods": {
                        "payMethod": {
                            ...
                            },
                            "threeDsData": {
                                "status3Ds": "AA",
                                "status3DsDescription": "3DS authentication attempt",
                                "xid": "PL345346456",
                                "eciCode": 6,
                                "cavv": "BwABCJQnYgAAACdENCdiAAAAAAA="
                            }
                        }
                    }
                    
                

Parametry użyte w sekcji threeDsData

Parametr Opis
status3Ds Status 3DS. Pole informujące w którym momencie i jakim statusem został zakończony proces 3DS.

Jeżeli proces 3DS został zakończony na etapie weryfikacji czy karta wspiera 3DS, to wówczas oryginalna odpowiedź MPI (finalne statusy N lub U) powinna być poprzedzona literą „V”.

Natomiast jeżeli proces 3DS został zakończony na etapie uwierzytelnienia wyniku 3DS (PARes) otrzymanego od wydawcy karty, to oryginalna odpowiedź MPI (finalne statusy Y, N, A lub U) powinna być poprzedzona literą „A”.

Stąd wynika dziedzina dozwolonych wartości tego pola:
  • VN – karta nie wspiera 3DS,
  • VU – organizacja płatnicza / wydawca karty nie był w stanie potwierdzić czy karta wspiera 3DS,
  • AY – uwierzytelnienie 3DS zakończone sukcesem,
  • AU – brak możliwości uwierzytelnienia wyniku 3DS otrzymanego od wydawcy karty,
  • AA – próba uwierzytelnienia wyniku 3DS otrzymanego od wydawcy karty.
W przypadku gdy korzystasz z usługi w wersji 3DS2.x dozwolona dziedzina wartości w tym polu jest następująca:
  • Y - uwierzytelnienie 3DS2.x zakończone sukcesem,
  • A - próba uwierzytelnienia 3DS2.x.
status3DsDescription Opis związany z wynikiem 3DS.

Pole opcjonalne. Zachęcamy jednak do przekazywania, jeżeli używany MPI przekazuje również dodatkowy opis – pozwoli to usprawnić potencjalną obsługę klienta przez BOK.
xid XID, czyli unikalny identyfikator transakcji 3DS nadawany przez sklep.

Pole wymagane w ramach sekcji dla 3DS w wersji 1. Pole nie powinno być wysyłane dla 3DS2.x.
dsTransactionId Pole wymagane w ramach sekcji dla 3DS2.x. Pole nie powinno być wysyłane dla 3DS w wersji 1.
eciCode E-commerce Indicator / UCAF.

Dozwolone wartości:
  • 5
  • 6
  • 7
  • 2
  • 1
  • 0
Pole opcjonalne. Powinno być zawsze przekazywane, jeżeli MPI przekazał tę informację.
cavv Kryptogram 3DS.

Pole opcjonalne. Powinno być zawsze przekazywane, jeżeli MPI przekazał tę informację.

11 Scenariusze płatności

Poniżej znajduje się omówienie scenariuszy płatności, które należy zaimplementować.

11.1 Pierwsze obciążenie

  1. Pobierz token dostępowy OAuth. Endpoint: /pl/standard/user/oauth/authorize. Metoda: POST
  2. Pobierz dostępne metody płatności. Endpoint: /api/v2_1/paymethods. Metoda: GET
  3. Pobierz dane karty (numer /PAN/, data ważności, kod CVV2/CVC2) przez Secure Form lub formularz. Tokenizuj kartę.
  4. Utwórz OrderCreateRequest, uzupełnij o jednorazowy token kartowy i wyślij żądanie. Endpoint: /api/v2_1/orders. Metoda POST.
  5. Obsłuż status WARNING_CONTINUE_3DS zwrócony przez OrderCreateResponse poprzez przekierowanie na adres podany w parametrze redirectUri.
  6. Opcjonalnie, tylko jeśli uwierzytelnienie 3DS trwało zbyt długo i kodu CVV2/CVC2 nie ma w cache po stronie PayU: obsłuż status WARNING_CONTINUE_CVV dodany do adresu continueUrl.
  7. Odbierz notyfikację o statusie zamówienia przesłaną na adres podany parametrem notifyUrl.
  8. Opcjonalnie, tylko jeśli auto-odbiór dla danej metody płatności jest wyłączony: odbierz zamówienie. Endpoint: /api/v2_1/orders/{orderId}/status. Metoda: PUT.

11.2 Kolejne obciążenie bez uwierzytelnienia

  1. Pobierz token dostępowy OAuth. Endpoint: /pl/standard/user/oauth/authorize. Metoda: POST
  2. Pobierz dostępne metody płatności. Endpoint: /api/v2_1/paymethods. Metoda: GET
  3. Utwórz OrderCreateRequest, uzupełnij o wielorazowy token kartowy i wyślij żądanie. Endpoint: /api/v2_1/orders. Metoda POST.
  4. Odbierz notyfikację o statusie zamówienia przesłaną na adres podany parametrem notifyUrl.
  5. Opcjonalnie, tylko jeśli auto-odbiór dla danej metody płatności jest wyłączony: odbierz zamówienie. Endpoint: /api/v2_1/orders/{orderId}/status. Metoda: PUT.

11.3 Kolejne obciążenie z pełnym uwierzytelnieniem

  1. Pobierz token dostępowy OAuth. Endpoint: /pl/standard/user/oauth/authorize. Metoda: POST
  2. Pobierz dostępne metody płatności. Endpoint: /api/v2_1/paymethods. Metoda: GET
  3. Utwórz OrderCreateRequest, uzupełnij o wielorazowy token kartowy i wyślij żądanie. Endpoint: /api/v2_1/orders. Metoda POST.
  4. Obsłuż status WARNING_CONTINUE_3DS zwrócony przez OrderCreateResponse poprzez przekierowanie na adres podany w parametrze redirectUri.
  5. Obsłuż status WARNING_CONTINUE_CVV dodany do continueUrl.
  6. Odbierz notyfikację o statusie zamówienia przesłaną na adres podany parametrem notifyUrl.
  7. Opcjonalnie, tylko jeśli auto-odbiór dla danej metody płatności jest wyłączony: odbierz zamówienie. Endpoint: /api/v2_1/orders/{orderId}/status. Metoda: PUT.

11.4 Kolejne obciążenie z częściowym uwierzytelnieniem

  1. Pobierz token dostępowy OAuth. Endpoint: /pl/standard/user/oauth/authorize. Metoda: POST
  2. Pobierz dostępne metody płatności. Endpoint: /api/v2_1/paymethods. Metoda: GET
  3. Utwórz OrderCreateRequest, uzupełnij o wielorazowy token kartowy i wyślij żądanie. Endpoint: /api/v2_1/orders. Metoda POST.
  4. Obsłuż status WARNING_CONTINUE_3DS lub WARNING_CONTINUE_CVV zwrócony przez OrderCreateResponse.
  5. Odbierz notyfikację o statusie zamówienia przesłaną na adres podany parametrem notifyUrl.
  6. Opcjonalnie, tylko jeśli auto-odbiór dla danej metody płatności jest wyłączony: odbierz zamówienie. Endpoint: /api/v2_1/orders/{orderId}/status. Metoda: PUT.