3DS 2

New standard of authentication.

1 Introduction

Below you will find a short description of 3DS 2 and SCA.

If your are already familiar with these concepts, you may proceed directly to check Impact on existing integrations or API enhancements.

1.1 What is 3DS 2

3DS 2 is an enhanced version of the original "Three Domain Secure" (3-D Secure or 3DS) authentication implemented by card issuers and acquirers under the umbrella of specific card schemes like MasterCard (MasterCard SecureCode) and Visa (Verified by Visa).

3DS 1 required the cardholder to be redirected to issuer's website before actual card authorization took place. On the website, the cardholder was required to perform some kind of authentication, e.g. by providing a one-time-password (OTP) sent via SMS or, more recently, by confirming the payment in the bank's mobile app.

At its simplest, the 3DS 2 (or EMVCo 3-D Secure, named after the organization which governs the new standard) enhances the original standard by enabling the mechant and PSP to send more data to perform better authentication and by making the process more friendly for mobile devices and even completely frictionless (no redirection, no OTPs) in some cases.

This change is also reflected in rebranding of the services offered by Visa and MasterCard, to Visa Secure and MasterCard Identity Check, respectively.

1.2 What is PSD 2/ SCA

The Revised Payment Services Directive (PSD 2) is a legal act coming into force in the European Union on 14th September 2019. Among other things, it introduces the requirement for Strong Customer Authentication (SCA) for online payments. This "strong authentication" must be made by using at least two of the three factors: "something you know" (e.g. password), "something you are" (e.g. finger print), "something you own" (e.g. a mobile device). Basically it would mean that all card payments require 3DS. Thus payments with a stored cards could not be processed as "one-click transactions" and the recurring payments (initiated by merchant with our prior consent but without our presence on merchant's website) not be possible at all. Luckily, there are exemptions.

1.3 Exemptions

Recurring and merchant initiated transactions

Only the initial transaction, starting the subscription or recurring cycle will require SCA. Subsequent charges will be exempt.

A transaction is deemed "recurring" if it is for a fixed amount.

In case the amount changes over time (such as in case of some utility bills based on usage, like electricity, telecom services etc.), such transaction will be called MIT (merchant intiated transaction) and will be also exempt.

Of course in both cases, the merchant must obtain cardholder's consent for charging the card.

Low Value and Low Risk Transactions

Payment transactions under 30 EUR or equivalent in local currency will be exempt from SCA. However, if the total amount attempted on the card without strong authentication per 24 hours is higher than 100 EUR, or every 5 transactions, SCA will be required (it is up to the issuing bank to keep track of the attempts and require the authentication).

Low risk transactions are also exempt from SCA. The ability for a payment to be considered low risk is based on the average fraud levels of the card issuer and acquirer processing the transaction. The acquirer sending authorization request to the issuer may flag the transaction as low risk, however the issuer may deny this claim and require strong authentication.

Soft declines

The card issuer always decides whether to honor the exemption in case of Low Value or Low Risk Transacions.

If strong customer authentication is deemed necessary by the issuer, the authorization will be declined using a specific reason code.

Such authorization maybe retried, but only if it is enhanced with the result of prior authentication of the payer by means of 3DS. More details are available in Handling soft declines section.

2 Impact on existing integrations

3DS 2 distinguishes between “browser” flow and “sdk” flow.

The latter can be used in case you have a mobile app (Android/iOS) with a certified 3DS 2 SDK. PayU will provide such a certified SDK wrapped into the existing mobile SDK.

The browser flow is for all other integrations (website displayed in a desktop or mobile device or a mobile app which uses web-view for authentication and payment instead of an SDK).

It may consist of two parts: the 3DS Method (fingerprinting done by the issuer by means of a hidden iframe displayed in payer's browser) and the Challenge (authentication requring the payer to perform some action, e.g. entering a one-time password).

The authentication may require only one or both of the above.

2.1 PayU payment page

3DS 2 will be natively supported on PayU hosted payment page. Therefore if your are using it, you are not required to do anything. The required strong cutomer authentication will be performed after the payer is redirected to PayU.

However in order to increase the probability of a "frictionless" 3DS 2 authentication, you may consider to pass some additional data to PayU (applies only to REST API integrations).

2.2 Card tokenization

Website

If you are using card tokenization (either via your own form or via PayU widget), you have two options to consider:

  • do nothing (users will be redirected to PayU's authentication page just like they are redirected for 3DS 1),
  • utilize PayU's authentication page by displaying it in an iframe on your website.

However in order to increase the probability of a "frictionless" 3DS 2 authentication, you may consider to pass some additional data to PayU (applies only to REST API integrations).

Mobile apps

If you are handling card payments natively within your Android or iOS apps, you may consider integrating a certified 3DS SDK to natively handle 3DS 2 authentication (without using web-view to display PayU's authentication page).

Such 3DS SDK would be available from PayU.

2.3 Testing

You can test a couple of 3DS 2 scenarios using PayU sandbox.

Below is a list of test cards and the 3DS 2 scenarios they simulate. For all cards please use any valid expiration date (i.e. future date) and any 3 digits as CVV.

Number Behavior
4245757666349685 Challenge required
5150030090350186 3DS Method required
4012001037141120 3DS Method and Challenge required
5100052384536834 returns Challenge params if sdk object sent in OrderCreateRequest

3 API enhancements

Only REST API has been enhanced with new data fields related to 3DS 2.

3.1 3DS 2 specific Order Create Request parameters.

To support 3DS 2, we have added new, optional fields to Order Create Request which are all contained in the threeDsAuthenticationobject.

OrderCreateRequest - threeDsAuthentication object

All below information are DRAFT only. These API enhancements are currently under development and some slight changes may occur.
Parameter Description Required
challengeRequested Merchant's preference regarding 3DS 2 challenge. Maybe overridden by PayU. Possible values: YES, NO, MANDATE. No
browser Browser data required for 3DS 2 browser flow. If not provided, these data will be collected by PayU. It is strongly recommended to include it when charging a stored card (multi-use token), because in some cases it will spare you redirection to PayU's authentication page. For a list of parameters, see browser. No, recommended
sdk Required if 3DS 2 is to be natively supported in your mobile app. Content needs to be generated by a certified 3DS 2 SDK. This information is not required, but it is strongly recommended to include it when charging a stored card (multi-use token). For a list of parameters, see sdk. Yes (if 3DS 2 SDK used)
merchantRiskIndicator Set of fields helping to assess risk connected with the order itself (type of goods purchased, shipping method etc.). For a list of parameters, see merchantRiskIndicator. No
recurring Additional information in case of a recurring payment. For a list of parameters, see recurring. No
cardholder Describes cardholder's account data in merchant's possession, including details of account run for the cardholder in merchant's system. For a list of parameters, see cardholder. No, recommended

Embedded objects

browser fields description.

Parameters Description Required
acceptHeaders Exact content of the HTTP accept headers as sent from the payer's browser. Yes
requestIP IP address of the browser as returned by the HTTP headers. Yes
screenWidth Total width of the payer's screen in pixels. Obtained from the screen.width HTML DOM property. Yes
javaEnabled Obtained from the navigator HTML DOM object. Yes
timezoneOffset Obtained from the getTimezoneOffset() method applied to Date object. Yes
screenHeight Obtained from the navigator HTML DOM object. Yes
userAgent Exact content of the HTTP user-agent header. Yes
colorDepth Obtained from payer's browser using the screen.colorDepth HTML DOM property. Yes
language Obtained from payer's browser using the navigator.language HTML DOM property. Yes

sdk fields description. All below fields are generated by a certified 3DS SDK.

Parameters Description Required
sdkReferenceNumber Example: DS_LOA_SDK_ADBV_739485_94783 Yes
sdkMaxTimeout Indicates the maximum amount of time (in minutes) for all exchanges. The field shall have value greater or equal to 05. Yes
sdkAppID Example: 9063b12c-fcde-43c7-b28e-8d0af5520e8a Yes
sdkEncData Data encrypted by the 3DS SDK. Yes
sdkTransID Example: b60c9879-ac77-4918-a317-7b01c4317053/8Q==.. Yes
sdkEphemPubKey Public key component of the ephemeral key pair generated by the 3DS SDK and used to establish session keys between the 3DS SDK and the issuer. Yes

merchantRiskIndicator fields description.

Parameters Description Required
orderType Possible values: PURCHASE, ACC_FUNDING, QUASI-CASH, LOAN. No
shipIndicator Indicates shipping method chosen for the order. Possible values: BILLING_ADDRESS, VERIFIED_ADDRESS, OTHER_ADDRESS, SHIP_TO_STORE, DIGITAL_GOODS, TICKETS, NOT_SHIPPED. No
preOrdered Indicates order for merchandise with a future availability or release date. Boolean. No
preOrderDate Example: "2019-03-27T10:57:59+00:00". No
deliveryTimeFrame Possible values: ELECTRONIC, SAME_DAY, OVERNIGHT, TWO_OR_MORE_DAYS. No
reordered Indicates if the same purchase has been ordered again. Boolean. No
merchantFunds Indicates whether merchant's own funding (e.g. a gift card) has been used to partially pay for the order. Sum of amounts provided here and of "totalAmount" field denote the real value of order in merchant's system. Object consisting of two fields: "amount" (in pennies) and "currency" (ISO code). No

recurring fields description.

Parameters Description Required
frequencyDays Minimum number of days between payments. No
expiryDate Date after no further recurring payments will be performed (if applicable). No

cardholder fields description.

Parameters Description Required
name Cardholder name and surname. No
accountInformation Object. For a list of parameters, see accountInformation. No
billingAddress Object. For a list of parameters, see billingAddress. No

accountInformation fields description.

Parameters Description Required
createDate Date when the account has been created for the cardholder. No
suspiciousActivity Indicates whether merchant has experienced suspicious/fraudulent activity for this account. Boolean. No
deliveryAddressFirstUsedDate Date when the shipping address used for this order was first used. No
deliveryAddressUsageIndicator Indicates when this shipping address was first used. Possible values: THIS_TRANSACTION, LESS_THAN_30_DAYS, THIRTY_TO_60_DAYS, MORE_THAN_60_DAYS. No
pastOrdersYear Orders created in merchant's system for this account in the past 12 months. No
pastOrdersDay Orders created in merchant's system for this account in the last 24 hours. No
purchasesLastSixMonths DFulfilled (successful) orders created in merchant's system for this account in the past 6 months. No
changeDate Date when account details were last changed. No
changeIndicator Indicates time when account information was last changed. Possible values: THIS_TRANSACTION, LESS_THAN_30_DAYS, THIRTY_TO_60_DAYS, MORE_THAN_60_DAYS. No
passwordChanged Date when account password was last changed in "2019-03-27T10:57:59+00:00" format. No
passwordChangeIndicator Indicates whether and when the password was last changed. Possible values: NO_CHANGE,THIS_TRANSACTION,LESS_THAN_30_DAYS, THIRTY_TO_60_DAYS, MORE_THAN_60_DAYS. No
nameToRecipientMatch Indicates whether cardholder's name matches recipient's name. Boolean. No
addCardAttemptsDay Indicates attempts to add a card to cardholder's account in merchant's system within last 24 hours. No
authMethod Authentication method used to recognize cardholder. Possible values: GUEST, LOGIN, FEDERATED_ID, THIRD_PARTY, ISSUER, FIDO. No
authDateTime Date and time when authentication was performed in "2019-03-27T10:57:59+00:00" format. No
cardAddedDate Date when card account has been stored with merchant in "2019-03-27T10:57:59+00:00" format. No
cardAddedIndicator Indicates if and when the card was stored with merchant. Possible values: GUEST, THIS_TRANSACTION, LESS_THAN_30_DAYS, THIRTY_TO_60_DAYS, MORE_THAN_60_DAYS. No

billingAddress fields description.

Parameters Description Required
street Full street address, incl. apartment number. No
postalCode Postal/ZIP code. No
city City name. No
state State or province, if applicable. No
country Two-letter ISO country code, e.g. "CZ", "PL" or "US". No

3.2 Order Create Response

Below changes in response apply only to requests with card data (tokenized by PayU, tokenized by Google Pay or in plain text) passed in payMethod object.

Browser flow

Existing response with WARNING_CONTINUE_3DS status will be enhanced with iframeAllowed field. It will indicate that the redirectUri may be displayed in an iframe. If you are intereted in utilizing the iframe instead of full redirection, see Authentication page section.

Sample response:

{
  "orderId": "FMHJ6HZF3T190518GUEST000P01",
  "status": {
    "statusCode": "WARNING_CONTINUE_3DS",
    "severity": "WARNING"
  },
  "redirectUri": "https://secure.payu.com/front/threeds?token=averylongjsonwebtokenwillbehere",
  "iframeAllowed": true
}         

SDK flow

The redirectUri will not be be applicable in case of 3DS 2 authentication handled natively in mobile apps.

Instead challengeParameters object will be returned and should be passed to the app.

Sample response:

{
 "challengeParameters": {
    "threeDsServerTransactionId": "12345678-1234-5678-abcd-eFABCDEF0123",
    "acsTransID": "d7c1ee99-9478-44a6-b1f2-391e29c6b340",
    "acsReferenceNumber": "3DS_LOA_ACS_201_13579",
    "acsSignedContent": "eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cDovL3d3dy4zZHMuY29tL25vdGlmaWNhdGlvbi11cmwiLCJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjhhODgwZGMwLWQyZDItN9"
  }
}             

4 Handling soft declines

To keep the current "one-click" experience for stored cards, PayU system will try to utilize one of the available exemptions on your behalf in order to avoid SCA.

However if a soft decline occurs, the way it would be handled depends on the applicable flow.

In case of the browser flow (payments initiated from a website in a desktop or mobile-view environment), the payer will be prompted to authenticate on PayU's Authentication page.

To enable handling of soft declines in case of the SDK flow, the decline reason code must be checked for each CANCELED order by retrieving transaction details. If a soft decline occurred (with cardResponseCode set to SSD), the payment may be retried by creating a new order with challengeRequested param set to MANDATE.

5 Authentication page

All the heavy logic required by 3DS 2 for the browser flow has been implemented on PayU's authentication page.

The authentication page may be displayed to the payer by means of a full redirection or in an iframe.

In the latter case, it may remain hidden until the issuer requests the user to authenticate - for details see Handling iframe.

5.1 Process overview

After the page is displayed to the user, they first see some initial information.

The language version of the information is based on navigator.language property. If this language is not supported, English version is used.

Note: you may set the language version directly by adding lang=[language] (two-letter ISO language code) param to the query string of authentication page URL address. For a list of supported languages see "Auth page" column in the Languages section.

Under the hood, depending on the applied rules, PayU system will either:

  1. Directly perform authorization using one of the possible SCA exemptions.
  2. Proceed with 3DS Method (device fingerprinting) in case the card issuer requested it. This process includes posting a HTML form from a hidden iframe and may take maximum 10 seconds.
  3. Display challenge window in an iframe to fully authenticate the user by means of whatever two-factor authentication the issuer has implemented.

Note: if the authorization without authentication (option 1 above) fails due to a soft decline, PayU will start the challenge and re-submit the authorization if the authentication is successful.

In case of a subsequent charge of a saved card token with full authentication, there is no need to handle the WARNING_CONTINUE_CVV status added to continueUrl provided in the order create request.

CVV will be collected by a form displayed on the authentication page.

Note: you may skip the form and capture the CVV on your website by applying cvv=false param to the query string of authentication page URL address.

Regardless of the result, after the authentication process is finished, the user will be redirected back to your website (in case of redirection) or you will need to close the iframe after it sends a message to its parent window.

5.2 Options

You may use the below options by adding them to the query string of authentication page URL address:

If you have provided language property in the buyer object of Order Create Request, it will be automatically appended to the URL query by PayU.

5.3 Handling iframe

Below example describes the possible way to display the authentication page within iframe in a modal.

It assumes the following three HTML elements:

               <div class="modal">
                    <div class="modal-content">
                        <iframe src="redirectUri">
                            <!-- authentication page document will go here -->
                        </iframe>
                    </div>
               </div>
            
It is best not to set "sandbox" attribute for the iframe, as we cannot guarantee that the authentication performed by the issuers will always work.

However, if you decide to use a sandboxed iframe, this is the necessary minimum you need to allow:

                        <iframe sandbox="allow-forms allow-scripts allow-same-origin" src="redirectUri">
                            <!-- authentication page document will go here -->
                        </iframe>
            

Make the iframe centered for desktop

Here are CSS declarations to be applied to appropriate elements when displayed on a desktop screen:

            .modal {
                display: none; /* Hidden by default */
                position: fixed; /* Stay in place */
                z-index: 1; /* Sit on top */
                left: 0;
                top: 0;
                width: 100%; /* Full width */
                height: 100%; /* Full height */
                background-color: rgb(0,0,0); /* Fallback color */
                background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
                }
            .modal-content {
                background-color: #fefefe;
                margin: auto; /* Center the content */
                border: 1px solid #888;
                height: 520px; /* Max height of authentication page content, incl. header */
                width: 600px; /* Max width of authentication page content */
            }
            iframe {
                border-style: hidden;
                height: 100%;
                width: 600px; /* Max width of authentication page content, incl. header */
                margin: auto;
             }
            

Make the iframe responsive for mobile devices

Enable the iframe content to be responsive by adding the below tag in the <head> of your HTML document:

                <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
            

The above CSS declarations should be overriden for smaller screens:

            @media (max-width: 599px)  {
                .modal-content {
                    width: 100%;
                    margin: 0;
                    /* Center vertically */
                    position: absolute;
                    top: 50%;
                    -ms-transform: translateY(-50%);
                    transform: translateY(-50%);
                }
                iframe {
                    width: 100%; /* Display in full available width */
                }
            }
            

Listen to messages from the iframe

The iframe may post messages to its parent window with the following values in message.data property :

  • DISPLAY_FRAME - reveal the iframe if it was hidden.
  • AUTHENTICATION_SUCCESSFUL - challenge was successful, close the iframe.
  • AUTHENTICATION_CANCELED - challenge was canceled and the payment declined, close the iframe.
  • AUTHENTICATION_NOT_REQUIRED - no authentication was required, close the iframe.
The DISPLAY_FRAME message may occur twice in case of 3DS 2 Challenge followed by CVV form.
In case of AUTHENTICATION_SUCCESSFUL and AUTHENTICATION_NOT_REQUIRED you should wait for authorization result before showing any information about payment status. To obtain the result, wait for notification or retrieve order details.

There are several ways to handle the above cases in detail. You may e.g. close the iframe only, but not the modal and display some message in it. You may also close both the modal and iframe and reload the page to show some neutral information or show a preloader and await the authorization result and display it immediately after it is known.

Below is an example of how to listen to and handle the messages:

            window.addEventListener('message', handleMessage, false);
            function handleMessage(msg) {
                if (msg.origin === 'https://secure.payu.com') {
                switch (msg.data) {
                    case ('DISPLAY_FRAME'):
                        // reveal the iframe if it is hidden
                        break;
                    case ('AUTHENTICATION_NOT_REQUIRED'):
                        // close the iframe, do other specific stuff
                        break;
                    case ('AUTHENTICATION_SUCCESSFUL'):
                        // close the iframe, do other specific stuff
                        break;
                    case ('AUTHENTICATION_CANCELED'):
                        // close the iframe, do other specific stuff
                        break;
                }
            }