Card Tokenization

1 Introduction

Card tokenization service is based on a transparent integration type which allows to accept card payments without redirecting users to a page hosted by the payment service provider. This integration type retains the security level and minimizes the PCI DSS compliance effort. It is also meant to give you more flexibility and increase conversion rates through better control over the payment process.

A payment flow is based on two steps - capturing card credentials in a secure way (front-end process) and then using them to create a payment transaction (back-end process). Card credentials are returned in the form of a token and a masked card number, therefore the Merchant never receives full card details.

Tokens received from PayU can be either single-use or multi-use. Multi-use tokens can be stored and used for future payments. Typically such functionality can be used by e.g. a merchant who has an extensive database of returning users – linking a user account with a multi-use token improves user experience, because the user no longer needs to enter card data each time.

PayU configuration

Single-use card tokens do not require additional configuration, however to enable multi-use tokens please contact PayU via your Account Manager.

Security requirements and recommendations

Before integrating the service, please take a look at the requirements and recommendations prepared by our security experts. It will help you protect yourself against frauds.

2 Integration overview

Tokenization without card storing:
  • implement the Secure Forms feature in your front-end
  • tokenize the card using SINGLE type in your front-end and pass it to your back-end
  • send Order request with the token from your back-end
Card storing process overview:
  • implement the Secure Forms feature in your front-end
  • tokenize the card using MULTI type in your front-end and pass it to your back-end
  • send Order request with the token and necessary customer details from your back-end
  • retrieve stored token(s) during subsequent checkout of this customer

Transparent payment with a single-use token (first payment):

Transparent payment with a multi-use token (second and next payments):

3 Secure Form

The Secure Form is the preferred solution as it eliminates the need to handle the sensitive card data on your website - all the data are inputted in an iframe with PayU hosted form.

Note: when using Secure Form you should display text provided in the Information Requirements section.

3.1 Examples

Single-use form example.
<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">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;
};

//initialize the SDK by providing your POS ID and create secureForms object
var payuSdkForms = PayU('393823');
var secureForms = payuSdkForms.secureForms();

//create the form by providing type and options
var card = secureForms.add('card', optionsForms);

//render the form in selected element
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) { //example for SINGLE type token
            result.status === 'SUCCESS'
                ? renderSuccess(responseElement, result.body.token) //pass the token to your back-end and charge it
                : renderError(responseElement, result.error.messages); //check the business error type and messages and display appropriate information to the user
        });
    } catch(e) {
        console.log(e); // technical errors
    }
});
.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;
}
Example of individual fields as a separate forms.
<script type="text/javascript" src="https://merch-prod.snd.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;
};

//initialize the SDK by providing your POS ID and create secureForms object
var payuSdkForms = PayU('393823');
var secureForms = payuSdkForms.secureForms();

//create the forms by providing type and options
var cardNumber = secureForms.add('number', optionsForms);
var cardDate = secureForms.add('date', optionsForms);
var cardCvv = secureForms.add('cvv', optionsForms);

//render the form in selected element
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 {
        ////tokenize the card (communicate with PayU server)
        payuSdkForms.tokenize(SINGLE).then(function(result) { // example for SINGLE type token
            result.status === 'SUCCESS'
                ? renderSuccess(responseElement, result.body.token) //pass the token to your back-end and charge it
                : renderError(responseElement, result.error.messages); //check the business error type and messages and display appropriate information to the user
        });
    } catch(e) {
        console.log(e); // technical errors
    }
});
.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 SDK documentation

The following description refers to methods and objects available in browser-side JavaScript library, contained in JS SDK.

Loading JS SDK

Add JS SDK script to every page you want to use Secure Form on. It should always be loaded from the PayU server. You mustn't load it from your own server and then attach it to the package that is being built at the moment.

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

JS SDK instance creation

PayU(posId, options?)

You will need posId parameter, which can be found in your management panel. In the following example we used test POS identifier from the Sandbox environment.

Method parameters

posIdrequiredstring
Point of Sale identifier.
optionsoptionalobject
Instance options.
devboolean
Enables instance creation in the developer mode which allows you to operate on a site without HTTPS protocol.

Return

PayU instance.

Exceptions

posid.is.empty
Occurs when a JS SDK instance is created and posId parameter is not specified or empty.
non.https.integration
Occurs on JS SDK instance creation when the protocol of the page, on which SDK is loaded, is not https and file, and the page is not loaded from localhost: 127.0.0.1 or 0.0.0.0.
During the implementation process you can enable developer mode in the options parameter.
var payu = PayU('393823');

JS SDK instance methods

secureForms()

Creates SecureForms instance.
It will be possible to add SecureForm elements on an object created this way.

Return

SecureForms instance.

Exceptions

secure.forms.already.exists
Occurs when trying to create another SecureForms instance.
If you want to append more than one card form to your page, create a separate instance of JS SDK for each one of them.
var secureForms = payu.secureForms();

tokenize(type?)

Request for card token creation with use of created SecureForm fields.

Method parameters

typeoptionalstring
Type of the created card token.
Possible values (default - SINGLE)
SINGLE Card not saved - token with short lifespan (15 minutes).
SINGLE_LONGTERM Card not saved.
MULTI Card saved - multi-use token will be returned after the it is charged via REST API.

Return

Promise, which resolves to the object containing the result.

Field Description
status Tokenization status:
  • SUCCESS - successful tokenization, result is available in body field;
  • ERROR - tokenization attempt ended in an error. The errors that occurred can be found in error field.
body Only for SUCCESS status. Object contains tokenization information.
error Only for ERROR status. Object with messages array which contains error information. Details can be found in Errors section.
correlationId Only for ERROR status.
{
    "status": "SUCCESS",
    "body": {
        "token": "TOK_1JOQVU5KJNOV4c4O8UbZySwcfBdS",
        "mask": "444433******1111"
    }
}

Exceptions

incorrect.token.type
Incorrect token type. Possible values can be found in type parameter description.
tokenize.not.possible
Tokenization not possible. Required type card form or number, date and cvv type forms.
var secureForms = payu.secureForms();

sendCvv(refReqId)

Sends a request for CVV. Works only when the form type is cvv.

Method parameters

refReqIdrequiredstring
If during card charging process PayU responds with WARNING_CONTINUE_CVV, you should retrieve refReqId parameter from redirectUri field, from the response. You can use extractRefReqId method to get refReqId from the URL.
If you are redirected to the page after 3DS is executed, you can retrieve refRedId parameter from URL.
URL example:
https://address.page/summary/?statusCode=WARNING_CONTINUE_CVV&refReqId=7b09781ee6a3303cc86712fce16fe030

Return

Promise, which resolves to the object containing the result.

Field Description
status CVV sending status:
  • SUCCESS - CVV was sent successfully - it does not mean that CVV is correct,
  • ERROR - sending CVV attempt ended in an error. The errors that occurred can be found in the error field.
error Only for ERROR status. Object containing error information. Details can be found in Errors section.
correlationId Only for ERROR status.
{
    "status": "SUCCESS",
    "body": {
        "token": "TOK_1JOQVU5KJNOV4c4O8UbZySwcfBdS",
        "mask": "444433******1111"
    }
}

Exceptions

refReqId.is.empty
refReqId was not specified or is empty.
sendCvv.not.possible
Error has occurred while trying to send CVV. Only cvv form is required.
payu.sendCvv('7b09781ee6a3303cc86712fce16fe030');

extractRefReqId(url)

Auxiliary function used for retrieving refReqId parameter from the URL.

Method parameters

urlrequiredstring
URL address.

Return

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

SecureForms instance methods

add(type?, options?)

Creates single-use instance of SecureForm form.

Method parameters

typeoptionalstring
Form type.
Possible values (default - card)
card Complete card data form (card number, expiration date, CVV).
number Card number form.
date Card expiration date form.
cvv CVV form.
optionsoptionalobject
Form options. For more information about individual options see Form options section.
styleobject
Your own form style.
placeholderobject
Your own placeholder text in fields of the form.
langstring
Language.
disabledboolean
Blocks a field.
cardIconboolean
Should card icon be displayed next to the card number input field.

Return

SecureForm Instance.

Exceptions

secure.form.incorrect.type
Invalid form type. Possible values can be found in type parameter description.
secure.form.exist.type [message]
Occurs when trying to add another form of specified type. [message] array contains details about errors.
secure.form.exist.other.type [message]
Occurs when trying to add form with type card when another number, date or cvv form was already added. It also occurs in the opposite situation while trying to add number, date or cvv form when card form was already added. [message] array contains details about errors.
var cardNumberForm = secureForms.add('number');

SecureForm instance methods

render(selector)

Displays the form on the page.

Method parameters

selectorrequiredstring
Selector of the element in which the form will be displayed. Searching for element is done by querySelectorAll.

Return

Its own Secure Form instance.

Exceptions

element.selector.empty
selector parameter was no specified or is empty.
element.selector.not.string
selector parameter is not of the string type.
element.not.exists
Element do not exists on the page.
element.too.many.exists
There is more than one element on the page.
element.not.valid
Invalid element (appendChild method is not implemented or it is an input element).
element.contains.children
Element contains secondary items.
cardNumberForm.render('#cardNumberForm');

update(options)

Updates form options.

Method parameters

optionsrequiredobject
options parameter is the same as options parameter in the add method

New options are overriding the existing ones, lack of an option does not remove existing one.

Return

Its own SecureForm instance.
cardNumberForm.update({lang: 'en'});

on(event, callback)

Attaching your own callback to the event emitted by the form. You can find more information about the events in the event section.

Method parameters

eventrequiredstring
Event type
Possible values
ready Emitted when the form is displayed.
focus Emitted when the form gains focus.
blur Emitted when the form loses focus.
change Emitted when the value of the form is changed.
callbackrequiredfunction
Funkcja zwrotna wywoływana po wyemitowaniu zdarzenia. Callback called after event is emitted.

Return

SecureForm instance

Exceptions

event.unknown
Unknown event type in event parameter.
event.callback.not.function
callback parameter is not a function.
cardNumberForm
    .on('ready', function() {
        // form ready
    })
    .on('focus', function() {
        // form activated
    })
    .on('blur', function() {
        // form deactivated
    })
    .on('change', function(body) {
        // value of the form has changed
    });

clear()

Removes data entered in the form.

Return

Its own SecureForm instance.
cardForm.clear();

focus()

Focuses the form.

Return

Its own SecureForm instance.
cardForm.clear();

remove()

Removes form from the page.

Return

Its own SecureForm instance.
cardForm.remove();

3.3 Form options

All parameters are checked for their type and values correctness. Unknown and invalid parameters are ignored without information about error.

Parameter Type Description
style object Your own form style.
placeholder object Your own placeholder text in the form input fields.
lang string Two-character language code. Available languages are: pl en cs sk.
If language is not specified, it is retrieved from the browser. For languages that are not supported, en is used.
disabled boolean When set to true form will be blocked, otherwise it will be active.
cardIcon boolean When set to false, card icon, next to card number input field, is not displayed, otherwise it is displayed.
{
    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
}

Style object

Groups styles for different form behaviours in objects. Each group has its permitted styles.

Styles group Permitted styles Description
basic fontColor fontSize fontFamily fontWeight Form styles
invalid fontColor fontWeight Styles for the form with invalid values.
focus fontColor fontWeight Style for the form with active focus.
placeholder fontColor fontWeight Styles for the form placeholders.
disabled fontColor fontWeight Styles for the disabled form.

Style

Style Descritpion Permitted values
fontColor font color #[0-9a-f]{6}
fontSize font size (\d+|\d*\.\d+)(px|em|%)
fontFamily font family [0-9a-z\-\s]{1,50}
fontWeight font weight ([1-9]00|normal|bold|lighter|bolder|inherit|initial|unset)

Placeholder object

Field Type Description
number string Placeholder text for the card number form.
date string Placeholder for the card expiration date form.
cvv string Placeholderfor the card CVV form.

3.4 Events

Forms emit events to which you can attach your own callback using the on method.

Event ready

This event is emitted after calling render method after the form is displayed.

Event focus

This event is emitted when the form is activated.

Event blur

This event is emitted when the form is deactivated.

Event change

This event is emitted when the value of the form is changed.
Callback is called with one object parameter with the following structure:

Field Description
empty Indicates if the form is empty.
Possible values: true or false.
error Indicates if the data entered in the form is correct.
Possible values: false when the form contains correct data or array of objects with errors.
Possible error type is validation. Details can be found in Errors section.
brand Only for type number form.
Contains information about the brand of the card. Possible values: visa, mastercard lub maestro .

3.5 Errors

error object contains an array of objects (messages), which contain detailed information about the errors.

Error object in messages array

Field Description
type Error type. Possible values:
  • validate - when the source of the error is the validation of the form fields values,
  • technical - for other errors.
code Error code.
message Error description in the languageof the form. In case of the technical type errors, description in always in english.
parameters Object containing changeable error fragments.

Error list

Error code Description
validate type errors
error.validation.card.empty Empty card number.
error.validation.card.length Invalid card number length.
error.validation.card.number Invalid card number.
error.validation.card.unsupported Card type is not supported. Supported card types: Visa, Mastercard and Maestro.
error.validation.expDate.empty Empty expiration date.
error.validation.expDate.past Expiration date is in the past.
error.validation.expDate.value Incorrect expiration date.
error.validation.cvv.empty Empty CVV.
error.validation.cvv.value Invalid CVV.
technical type errors
error.tokenization Error has occured while trying to tokenize the card. Error information can be found in the parameters object in the error field.
error.send.cvv Error has occured while sending CVV. Error information can be found in the parameters object in the error field.
error.network A network communication error has occured. Error information can be found in the parameters object in the error field.
{
    "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.6 FAQ

I need translation into xx language.
Elements that are translated are placeholder texts and error messages. Both elements you can translate freely on your own.

In case of placeholder elements we passed them in the placeholder parameter in the form options e.g.

{
    placeholder: {
        number: 'Kartennummer',
        date: 'MM / JJ',
        cvv: 'CVV'
    }
}

In case of errors, we display message based on the error codes e.g.

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]); // show error message
    });
};
Someone has resized the browser window or flipped the phone. I want to change the font size and disable the card brand icon, so that the form fits completely on the page.

While resizing the browser window you should use the update method to update form options e.g.

// initializing code of JS SDK and SecureForms has been omitted
var cardNumber = secureForms.add('number');
var options = {
    current: 'gt500',
    profiles: {
        gt500: {
            style: {
                basic: {
                    fontSize: '18px'
                }
            },
            cardIcon: true
        },
        lt500: {
            style: {
                basic: {
                    fontSize: '14px'
                }
            },
            cardIcon: false
        }
    }
};

// window size change
window.addEventListener('resize', function() {
    var newProfile = window.innerWidth > 500 ? 'gt500' : 'lt500';
    if (newProfile !== options.current) {
        options.current = newProfile;
        // form options update
        cardNumber.update(options.profiles[options.current]);
    }
});

4 Widget

This solution is deprecated and this section should be used only as a reference for existing integrations. We strongly discourage you from starting a new integration using this feature! Please use the Secure Form instead.

4.1 Pop-up widget

This section provides information on the pop-up widget. It may either use POST method or a callback function to provide output.

Output example:

   value:"TOK_1IOPVS7EMKVT4GYvs44XPxAOb8yc",
   maskedCard:"424242******4242",
   tokenType:"STANDARD",
   type:"CARD_TOKEN"
Parameter name Description
value one-time token ("TOK_") - expires after first usage
maskedCard masked card number
tokenType fixed value (always STANDARD)
type fixed value (always CARD_TOKEN)

Widget implementation has 3 steps:

1. Include the payment form presenting a payment button that defines a payment handling action. To do this, define a correct action parameter.
                    <form action="http://exampledomain.payu.com/processOrder.php" method="post">
                        <button id="pay-button">Pay now</button>
                    </form>
                

2. Include the PayU widget bootstrap JS script. Define all the parameters according to your needs and POS configuration.

Note: the widget can pass the data via POST method or through a callback function provided in success-callback parameter. Compare the inline widget example below.

                    <script
                        src="https://secure.payu.com/front/widget/js/payu-bootstrap.js"
                        pay-button="#pay-button"
                        merchant-pos-id="145227"
                        shop-name="Shop name"
                        total-amount="9.99"
                        currency-code="PLN"
                        customer-language="en"
                        store-card="true"
                        customer-email="email@exampledomain.com"
                        sig="6c9bb18db84165f53b5918380833723bc5fbb95ec5a9b73a4cb02dd60c11c64e">
                    </script>
                

3. Calculate the SIG parameter necessary to secure communication. Widget parameters and SIG algorithm: Widget parameters.

In some cases, even for multi-use token transations, PayU may ask for CVV. Then CVV Widget should be displayed:
                    <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() {
                        //display "payment successfully initiated" page
                        }
                    </script>
                

4.2 Inline widget

Inline widget is a modification of the pop-up widget. It does not contain the header with shop name and purchase amount and uses some additional parameters.

1. The widget is displayed inline if the page includes the following element:

<div id="payu-widget"></div>

2. Inline widget can either HTTP POST the output or provide it via a callback function. To use the callback instead of POST, simply add success-callback parameter. The callback function may look like below (it will allow you to see widget's output in your browser's console):

<script>
      function test($data) {
           console.log("callback");
           console.log($data);
      }
</script>
        

3. To display the widget, include the PayU widget bootstrap JS script. Define all the parameters according to your needs. Below example will display a white-background widget without PayU branding and "Use" button (instead of "Pay"). To check what it displays simply copy&paste the below script into the body of your page along with div element and callback function provided above.

                    <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. Calculate the SIG parameter necessary to secure communication. Widget parameters and SIG algorithm: Widget parameters.

4.3 Parameters

Calculate the SIG parameter necessary to secure communication. SIG is calculated in the following way:

  1. Sort the parameters required to calculate the SIG alphabetically.
  2. Concatenate the values of parameters taken to the SIG calculation respecting the alphabetical order of the parameters.
  3. Add the value of a private key - visible in POS configuration in the Merchant Control Panel as "Second key (MD5)".
  4. Perform SHA256 function on the whole sequence.
  5. Use the output of the SHA256 function as the "sig" parameter and send it together with other widget parameters.

Example

Parameters need to be sorted alphabetically:

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

Then you need to concatenate the values to get a string like below:

EURtest@test.comen145227TEST12345

and add to it the second private key (the example uses a production test POS key value). The final concatenation is:

EURtest@test.comen145227TEST1234513a980d4f851f3d9a1cfc792fb1f5e50

After SHA256 function is performed, we get the sig value:

6dc0247030fa2da54754517586ce02a905e1ff2a21181105174dccec5e291789

Widget script parameters:

Parameter name Required Required for SIG Description
pay-button yes no CSS selector of the payment button
merchant-pos-id yes yes Id of a POS which will be used to create a payment
shop-name yes yes Name of a shop displayed to the Payer inside the widget
total-amount yes yes Total amount of payment displayed to the Payer
currency-code yes yes Payment currency displayed to the Payer, must match the POS currency
customer-language yes yes Language in which the widget will be displayed to the Payer. If the language parameter is missing or is incorrect, the default one - obtained from the Payer's browser configuration - will be used. Available parameters: bg, cs, de, en, es, fr, hu, it, pl, pt, ro, sk.
customer-email no yes Payer's email
widget-type no no Optional value used for selecting type of widget. By default, the widget presents a card form. Provide a cvv value if you want to show the CVV widget.
store-card no yes Values: true/false (default: "false"). Enables multi-use tokens. Required for storing a token.
recurring-payment no yes Values: true/false (default: "false"). Displays a recurring version of the Widget. Requires the storecard parameter set to "true".
payu-brand no yes Values: true/false (default: "true"). Displays widget without PayU branding (only for inline widget).
widget-mode no yes Values: pay/use (default: "pay"). Configures widget buttons. "Pay" mode assumes payment to happen immediately after the widget is used. "Use" mode allows to capture card data without immediate payment.
success-callback no no Name of the callback function which will handle widget's output.
sig yes no Value of a signature providing secure communication.
CVV widget parameters:
Parameter name Required Required for SIG Description
merchant-pos-id yes yes Id of a POS which will be used to create a payment.
shop-name yes yes Name of a shop displayed to the Payer inside the widget.
total-amount yes yes Total amount of payment displayed to the Payer
currency-code yes yes Payment currency displayed to the Payer, must match the POS currency.
customer-language yes yes Language in which the widget will be displayed to the Payer. If the language parameter is missing or is incorrect, the default one - obtained from the Payer's browser configuration - will be used.
widget-type yes no Optional value used for selecting type of widget. By default, the widget presents a card form. Provide a cvv value if you want to show the CVV widget.
cvv-url yes yes CVV URL taken from redirectUri from OrderCreateResponse (when statusCode == WARNING_CONTINUE_CVV) or the query string parameter (refReqId=...) taken from continueUrl after a successful response from the bank (when 3DS was required).
cvv-success-callback no no Callback function executed on successful authorization after the Payer has provided a CVV.
sig yes no Value of a signature providing secure communication.

5 Your own form

This solution is deprecated and this section should be used only as a reference for existing integrations. We strongly discourage you from starting a new integration using this feature! Please use the Secure Form instead.

5.1 Card data form

If you have enabled payments via credit cards, you are obliged to be PCI DSS compliant.

You should annually complete a Self-Assessment Questionnaire (SAQ) and conduct on a quarterly basis network scan by an Approved Scan Vendor (ASV).

Additionally if you process over 6 million card transactions annually you should complete Report on Compliance (ROC) by Qualified Security Assessor (QSA).

You can find more information at Security Standards Council.
Include the OpenPayU scripts that enable the secure card data transfer to the PayU system:
                    <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>
                

Create the credit card payment form in a way that the scripts are able to retrieve the correct information. To achieve the desired result, add "input" elements to your page with "class" attributes named as in the example below.

Note: it is unnecessary to embed the "input" elements in a "form" element as the card data should not be sent to your server.

In case you want to send the data and fall under the full scope of PCI DSS compliance, please check Card on file section.

    
                            <table>
                                <tr>
                                    <td>card number</td>
                                    <td><input type="text" class="payu-card-number"></td>
                                </tr>
                                <tr>
                                    <td>card cvv</td>
                                    <td><input type="text" class="payu-card-cvv"></td>
                                </tr>
                                <tr>
                                    <td>exp month</td>
                                    <td><input type="text" class="payu-card-expm"></td>
                                </tr>
                                <tr>
                                    <td>exp year</td>
                                    <td><input type="text" class="payu-card-expy"></td>
                                </tr>
                                <tr>
                                    <td>PayU terms of condition and acceptance to save credit card</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>                          
               

The scripts searches the page for the following class names:

Class name Required Description
payu-card-cardholder optional cardholder name
payu-card-number yes card number (PAN)
payu-card-cvv yes CVV2/CVC2 code of the card
payu-card-expm yes card expiration month
payu-card-expy yes card expiration year
payu-agreement yes value true/false. Means that the cardholder agreed to save credit card and accepted PayU Account Terms and Conditions. If the value is false PayU will not return multi-use token.
payu-customer-email optional cardholder email address

Add a script handling card tokenization:
    (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) {
                    // handle tokenization response, see status code table below
                });
                if (result !== true) {
                    // tokenization request has not been submitted, 
                    // check "result" object for validation errors
                }
            }, false);
        })();           
On successful tokenization, the "result" object has value of true and the below objects are passed to callback function. The token property should be passed to your back-end and included in the OrderCreateRequest (see Charging tokens section).
            
             {
               	data: {
               		mask: "444433******1111",
               		token: "TOK_1JKQSX1FMNTU831B8a6z4LDHbzsv",
               		type: "STANDARD"
               	},
               	status: {
               		statusCode: "SUCCESS",
               		codeLiteral: "SUCCESS",
               		code: "0"
               	}
             }        
In case of validation errors, the "result" contains all or one of the following:
            {
                   card.expirationDate: "formatInvalid",
                   card.expirationMonth: "formatInvalid",
                   card.expirationYear: "formatInvalid",
                   card.number: "unsupportedType"
                }           

Status codes returned in response to tokenization request are outlined below:

Code Status code Code literal Description
0 SUCCESS SUCCESS Successful tokenization, "data" object returned.
100 ERROR_INTERNAL GENERAL_ERROR Other error.
101 ERROR_UNKNOWN_MERCHANT_POS UNKNOWN_MERCHANT Incorrect POS ID.
4003 ERROR_VALUE_INVALID CARD_INVALID_CVV CVV length is incorrect (only 3 or 4 digits allowed).
4100 SERVICE_NOT_AVAILABLE CARD_TOKENIZATION_DISABLED Tokenization is not enabled for your POS ID.
4101 SERVICE_NOT_AVAILABLE CARD_MERCHANT_INACTIVE Card payments not enabled for your POS ID.

Device fingerprint

A device fingerprint is information collected about a remote computing device for the purpose of identification. Fingerprints can fully or partially identify devices or individual users

Fingerprint value is generated by static function Fingerprint2.get, which replaced new Fingerprint2().get. Beacuse of this the result will not be hashed anymore.

Needed libiraries can be found Here.

Usage:
                    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'}
                        ...
                    })
                
For creating hash fingerprint you can use murmur hash function:
                    Fingerprint2.get(options, function (components) {
                        var values = components.map(function (component) { return component.value })
                        var murmur = Fingerprint2.x64hash128(values.join(''), 31)
                    })
                

The hash value should be passed to PayU in OrderCreateRequest body, see example below.

5.2 CVV only form

Your front-end should be also able to handle CVV2-only submission.
The following input element should be displayed and filled by the payer:
<input type="text" class="payu-card-cvv">

CVV2 may need to be collected in case it is needed to authenticate payment with a previously tokenized card.

There are 2 cases to handle:

  1. Subsequent charge of a saved card token with full authentication. CVV2 needs to be collected when the payer returns to your page after 3DS authentication - status code WARNING_CONTINUE_CVV is provided in query string added to continueUrl provided in OrderCreateRequest. Query string example:
    https://your.shop.com/payment?statusCode=WARNING_CONTINUE_CVV&refReqId=b20399775cbf48a00469280499bdd912
    Script example to handle this scenario (the below code should be triggered after the payer clicked a button to submit the CVV2):
                                var url = "refReqId=" + 'refReqId value from query string';
                                var options = {url: url};
                                OpenPayU.authorizeCVV(options, function(data) {
                                    if (data.status === 'SUCCESS') {
                                        // CVV2 submitted correctly, hide input field
                                    } else {
                                        // handle error (see table above)
                                    }
                                }); 
                            
  2. Subsequent charge of a saved card token with partial (CVV2 only) authentication. Status code WARNING_CONTINUE_CVV is provided in response to OrderCreateRequest. To see response example Charging tokens section. Script example to handle this scenario (the below code should be triggered after the payer clicked a button to submit the CVV2):
                           var options = {url: 'redirectUri value from OrderCreateResponse'};
                           OpenPayU.authorizeCVV(options, function(data) {
                                if (data.status === 'SUCCESS') {
                                        // CVV2 submitted correctly, hide input field
                                    } else {
                                        // handle error (see table above)
                                }
                           });     
                        

6 Charging tokens

Modifying back-end

Multi-use token (TOKC_) is created after first use of single-use token (TOK_).

OrderCreateRequest should be extended by buyer and payMethod sections where single-use token (TOK_) is used as a value parameter. Order involving REST API is described in: Creating a new order.

In case of payment with multi-use token (TOKC_) its possible to set cardOnFile parameter, which informs about party initializing payment:
  • FIRST
  • STANDARD_CARDHOLDER
  • STANDARD_MERCHANT
Detailed descriptions of cardOnFile parameter values can be found in JSON properties section.
Setting this parameter in the correct way can increase conversion for payment cards.

Sample order with single-use token (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",
                          "cardOnFile": "FIRST",
                          "extOrderId":"[generateExtOrderId]",
                          "products":[
                             {
                                "name":     "Laptop",
                                "unitPrice":"15000",
                                "quantity": "1"
                             }
                          ],
                          "buyer": {
                              "email": "john.doe@example.com",
                              "firstName": "John",
                              "lastName": "Doe",
                              "language": "en"
                          },
                          "payMethods": {
                              "payMethod": {
                                   "value": "TOK_1IHRPT6HKSSS3H62K0GS8pElP862",
                                   "type":  "CARD_TOKEN"
                              }
                          },
                          "deviceFingerprint": "[generateFingerPrint2]"
                      }'
                

Authentication methods are described in: Signing API calls parameters.

Warning! POS used in the example does not have tokenization switched on.

Example for SUCCESS response

                    {
                        "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"
                        }
                    }
                

This response means that there is no need for additional payer authentication (3D Secure or passing CVV2 code).

PayU informs Shop about the payment by submitting a notification to the address provided in the orders notifyUrl parameter. To learn more about notifications, please read Notifications.

Sample order with multi-use token (TOKC_) initiated by merchant:

                    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 Handling 3DS

In case of WARNING_CONTINUE_3DS response, payer should be redirected to card issuer page (redirectUri parameter) for additional payment authentication in 3D Secure process.

The 3DS authentication may be performed either via 3DS1 or 3DS2 protocol, indicated by the value of threeDsProtocolVersion field.

To learn how to tackle 3DS2, please refer to 3DS 2 page.

Example of WARNING_CONTINUE_3DS response:

                    {
                        "orderId": "ORDER_ID",
                        "status": {
                            "statusCode": "WARNING_CONTINUE_3DS",
                            "severity": "WARNING"
                        },
                        "redirectUri": "{redirectUri}",
                        "iframeAllowed": true,
                        "threeDsProtocolVersion": "3DS1"
                    }
                
After 3DS authentication on card issuer page, payer is redirected back to page address that was passed as continueUrl in OrderCreateRequest. Additionally address in query string is extended by two parameters:
  • statusCode - values SUCCESS or WARNING_CONTINUE_CVV;
  • refReqId - random alfanumeric string of characters.
Example:
https://your.shop.com/payment?statusCode=SUCCESS&refReqId=5c867936fbb3cc2c373820b4550b4645

When the statusCode parameter adopts SUCCES value it means that order has been accepted without need for another authentication of the payer and you can wait for order status.

On the other hand whenstatusCode parameter adopts WARNING_CONTINUE_CVV value, then refReqId parameter should be taken:

refReqId=5c867936fbb3cc2c373820b4550b4645
And then passed depending on the integration type:
  • widget - as cvv-url parameter forwidget-type="cvv";
  • form - as a options - url parameter value.

6.2 Handling CVV2

In case of WARNING_CONTINUE_CVV payer should be asked to provide CVV2/CVC2 code. To do this, value of redirectUri parameter should be passed depending on the integration type:
  • widget - as cvv-url parameter for widget-type="cvv";
  • form - as a value ofoptions - url parameter.

Example of WARNING_CONTINUE_CVV response:

                    {
                        "orderId": "ORDER_ID",
                        "status": {
                            "statusCode": "WARNING_CONTINUE_CVV",
                            "severity": "WARNING"
                        },
                        "redirectUri": "{redirectUri}"
                    }
                

Sample value of redirectUri parameter:

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

Order status will be sent after CVV2/CVC2 code has been provided by the payer.

7 Retrieving tokens

Payment methods retrieve service description

Payment methods available for a given user should not be stored locally on merchant's server, but rather retrieved from PayU system for each payment. Retrieved are both the stored (tokenized) payments methods and generic payment methods. Using the retrieve service gives the following benefits:

- only payment methods available at the moment for the user are provided,

- payment methods stored for the user are always up to date and synchronized with user's active PayU Account.

In order to retrieve the payment methods, you need first to obtain OAuth access token.

Obtaining OAuth access token

To obtain OAuth access token, use the POST method to send request to endpoint /pl/standard/user/oauth/authorize.

apiary

Sample request:

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 is unique customer identifier given by merchant, it is necessary in order to correctly generate the OAuth token.

Sample positive response (HTTP 200):
{
    "access_token": "4099c2c3-276f-488a-90e2-32620ac441dc",
    "token_type": "bearer",
    "expires_in": 43199,
    "grant_type": "trusted_merchant"
}
            

Retrieving payment methods

Insert the access token into header and use the GET method to send request to endpoint api/v2_1/paymethods .

apiary

Sample request:
curl -X GET https://secure.payu.com/api/v2_1/paymethods \
   -H "Authorization: Bearer 87ad751f-7ea5-4023-a16f-04b6647a07f5" 
   -H "Cache-Control: no-cache" 

                

Sample postive response (HTTP 200). Description of fields are below the sample:

{  
   "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.payu.com/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

This section will be returned empty if the user does not have any active or expired card tokens.
Parameter Description
cardExpirationYear YYYY
cardExpirationMonth MM
cardNumberMasked First 6 and last 4 digits of the PAN (card number).
cardBrand Possible values: 'VISA', 'MASTERCARD', 'MAESTRO'. Other card types are not supported, moreover 'MAESTRO' is not supported in recurring payments. VISA describes various Visa card brands, incl. Visa Electron. MASTERCARD also includes MasterCard Debit.
value Card token value.
brandImageUrl Link to card brand graphic on PayU server.
preferred true/false; it is set to 'true' for a cardToken or bankToken used most recently by the user.
status Possible values: 'ACTIVE' and 'EXPIRED'.

'EXPIRED' tokens may be skipped or presented to the user with a prompt to update or add a new card.

If a token has been closed by the user or blocked for security reasons by PayU, it will not be provided in retrieve response.

pexTokens

This section will be returned empty if the user does not have any active pexTokens.

pexTokens relate to bank accounts tokenized through PayU|Express service.

Parameter Description
accountNumber First and last 4 digits of the bank account in the IBAN format.
payType Represents payType of the token.
name Name of the bank account set by the user.
value Bank token value.
brandImageUrl Link to bank logo graphic on PayU server.
preferred true/false; it is set to 'true' for a cardToken or bankToken used most recently by the user.
status Possible value: 'ACTIVE'.

If a token has been closed by the user or blocked for security reasons by PayU, it will not be provided in retrieve response.

If payType of the token is not configured on merchant's POS, the token will not be provided.

payByLinks

payByLinks are payment methods which always require redirection of the user. Therefore this section includes online bank transfers (pay-by-links), traditional bank transfer, installments and non-tokenized cards.
Parameter Description
value payType value. Available values are here.
name Name of payType set by PayU
brandImageUrl Link to payType logo graphic on PayU server.
status Possible values: 'ENABLED', 'DISABLED', 'TEMPORARY_DISABLED'.

8 Deleting tokens

Deleting a payment token

In case the buyer terminates the user account in your shop or chooses to remove the stored card from the user account, you need to delete the token.

In order to do it, simply send a DELETE message to https://secure.payu.com/api/v2_1/tokens/{tokenValue}

The header should contain a trusted.merchant OAuth token.

For example:
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 Card data in text form

Warning! This integration type is available only for POSes meeting PCI DSS requirements and requires additional configuration. Therefore, please contact your sales representative in PayU before the integration.

Standard OrderCreateRequest should be extended by payMethods.payMethod section containing plain card data and cardOnFile parameter:

  • FIRST
  • STANDARD_CARDHOLDER
  • STANDARD_MERCHANT
Detailed descriptions of cardOnFile parameter values can be found in JSON properties section.

Only in case of one-time card payment this cardOnFile parameter can be skipped.

Setting this parameter in the correct way can increase conversion for payment cards and can guarantee transaction security.

Sample payMethods.payMethod section supplemented with plain card data


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

                

Sample payMethods.payMethod section supplemented with plain card data and first transaction identifier


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

            

Also for plain card data payments you should be prepared for handling responses with: WARNING_CONTINUE_3DS or WARNING_CONTINUE_CVV.

10 External 3D Secure parameters

In case of already existing integration with provider of 3D Secure service (later called 3DS) you can pass parameters that have been returned from 3DS handling process in OrderCreateRequest. Standard OrderCreateRequest should be extended by payMethods.threeDsData section containing result data from 3DS process.

WARNING_CONTINUE_3DS will never be returned if the result of 3DS handling process will be delivered with Order.

Sample threeDsData section for successful 3DS authentication

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

Sample threeDsData section for successful 3DS2.x authentication

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

Sample threeDsData section for card which issuer does not support 3DS

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

Sample threeDsData section for 3DS authentication attempt

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

Parameters used in the threeDsData section

Parameter Parameter type Description
status3Ds ENUM 3DS status. This field informs with what status and in which moment 3DS process has ended.

If the 3DS process has ended at card 3DS verification stage then MPI response (final statuses - N or U) should be preceded by the letter "V".

If the 3DS process was completed at the stage of authentication of the 3DS (PARes) result received from the card issuer, then the original MPI response (final statuses - Y, N, A or U) should be preceded by the letter "A".

Hence the allowed values of this field:
  • VN – card does not support 3DS,
  • VU – payment organization / card issuer was not able to confirm if card support 3DS,
  • AY – successful 3DS authentication,
  • AU – it is not possible to authenticate 3DS result received from the card issuer,
  • AA – authentication attempt of 3DS result provided by card issuer.
Following values are allowed to be used while using 3DS2.x version of the service:
  • Y - successful 3DS2.x authentication,
  • A - 3DS2.x authentication attempt.
status3DsDescription string {1, 1024} Description related to 3DS result.

Optional field. However passing additional description with the MPI will allow better potential customer support from BOK.
xid string {1, 20} - for value in plain text,
string {28} - for Base64encoded value,
string {40} - for HEXencoded value.
XID - unique identifier of 3DS transaction given by the shop.

Field required within 3DS version 1 section. This field should not be sent when attempting 3DS2.x authentication.
dsTransactionId string {1, 36} Field required within 3DS2.x section. This field should not be sent when attempting 3DS version 1 authentication.
eciCode ENUM E-commerce Indicator / UCAF.

Permitted values (below values can also be passed with "0" e.g. "05", "04", etc.):
  • 5
  • 6
  • 7
  • 2
  • 1
  • 0
Optional field. It should be passed always if the MPI provided this information.
cavv string {1, 200} 3DS cryptogram.

Optional field.It should be passed always if the MPI provided this information.

11 Payment flows

Below you can find a handy reference of all card tokenization flow types.

11.1 First charge

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Collect full card data (PAN, expiry date, CVV2/CVC2) via widget or form. Retrieve card token.
  4. Prepare OrderCreateRequest (with cardOnFile or recurring param if required), insert one-time card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  5. Handle the WARNING_CONTINUE_3DS status provided in OrderCreateResponse by redirecting the user to redirectUri provided in the response.
  6. Optionally, only when 3DS authentication took too long and CVV2/CVC2 is no longer cached by PayU: handle the WARNING_CONTINUE_CVV status added to continueUrl.
  7. Receive notification with order status sent to address specfied by you in notifyUrl.
  8. Optionally, only when you do not have auto-receive enabled for the given payment method: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

11.2 Subsequent charge without card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Receive notification with order status sent to address specfied by you in notifyUrl.
  5. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

11.3 Subsequent charge with full card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Handle the WARNING_CONTINUE_3DS status provided in OrderCreateResponse by redirecting the user to redirectUri provided in the response.
  5. Handle the WARNING_CONTINUE_CVV status added to continueUrl.
  6. Receive notification with order status sent to address specfied by you in notifyUrl.
  7. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.

11.4 Subsequent charge with partial card authentication

  1. Obtain OAuth access token. Endpoint: /pl/standard/user/oauth/authorize. Method: POST
  2. Retrieve available payment methods, including multi-use card token. Endpoint: /api/v2_1/paymethods. Method: GET
  3. Prepare OrderCreateRequest, insert multi-use card token and submit the request. Endpoint: /api/v2_1/orders. Method POST.
  4. Handle the WARNING_CONTINUE_3DS or WARNING_CONTINUE_CVV status provided in OrderCreateResponse.
  5. Receive notification with order status sent to address specfied by you in notifyUrl.
  6. Optionally, only when you do not have auto-receive enabled on your POS: capture the order. Endpoint: /api/v2_1/orders/{orderId}/status. Method: PUT.