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 EMV 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 perform card tokenization using Secure Form, 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).

2.3 Testing

You can test 3DS 2 scenarios using PayU sandbox.

Check table with test card data on the sandbox page for more details.

3 API enhancements

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

3.1 Fields required by 3DS 2 standard.

To cover data requirements of the 3DS 2 standard, REST API has been enhanced with new fields. In order not to break existing integrations, new fields are not mandatory. However, since some fields are mandatory according to 3DS 2 standard, they will be defaulted by PayU in case they are not sent by you.

Below table contains fields required by the 3DS 2 standard. In other words - this is the minimum data expected to be provided by you for a card payment subject to 3DS 2 authentication. If these fields are not provided, PayU will send default (dummy) values.

You should consider sending below fields for all orders which may be subject to 3DS 2 authentication, which are:

  • orders with payMethods.payMethod.value set to any card-based payment: c, ap, jp, ma, vc,
  • orders with payMethods.payMethod.type set to CARD_TOKEN,
  • orders with payMethods.card object,
  • orders without payMethods object (in case you have any card payment configured on your POS).

For a detailed description of all new fields introduced to comply with 3DS 2 protocol, please refer to threeDsAuthentication object description.

Parameter Comment
buyer.email -
buyer.phone Please use +[country code] [number] format, e.g. +48 225108001
buyer.delivery Sent as "shipping address" during 3DS 2 authentication. Please note that "state" field within buyer.delivery object is required and must be a valid ISO 3166-2 code (e.g. "UT" for Utah in the USA or "30" for "Wielkopolskie" in Poland).
threeDsAuthentication.cardholder.name Represents name and surname printed on the card. If not provided will be created from buyer.firstName and buyer.lastName. In case neither of these fields are provided, default dummy value will be sent.
threeDsAuthentication.cardholder.billingAddress Please note that "state" field within billingAddress object is required and must be a valid ISO 3166-2 code (e.g. "UT" for Utah in the USA or "30" for "Wielkopolskie" in Poland).
threeDsAuthentication.browser If not sent and there is no sdk object present, default one will be created (browser.requestIp will be mapped from customerIp)
threeDsAuthentication.sdk Must be sent if authentication is to be performed using the app (SDK) flow. This object is not defaulted, if not present, browser flow is assumed.

3.2 Request example

Below is an order create request example with minimum data required by PayU, but including also data required by 3DS 2 standard, but not made obligatory by PayU.
curl -X POST https://secure.payu.com/api/v2_1/orders \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
    -d '{
    "continueUrl": "http://www.payu.pl",
    "customerIp": "216.72.35.5",
    "merchantPosId": "145227",
    "description": "Order with 3DS 2 required fields",
    "currencyCode": "PLN",
    "totalAmount": 300,
    "products": [
        {
            "name": "a product",
            "unitPrice": 300,
            "quantity": 1
        }
    ],
    "buyer": {
        "firstName": "John",
        "lastName": "Doe",
        "phone": "+48 555555555",
        "email": "john@doe.pl",
        "delivery": {
            "street": "Delivery St. 1",
            "postalCode": "55-033",
            "city": "Delivery Town",
            "state": "30",
            "countryCode": "PL"
        }
    },
    "threeDsAuthentication": {
        "cardholder": {
            "name": "Joe Doe",
            "billingAddress": {
                "street": "Billing St. 1",
                "postalCode": "33-055",
                "city": "Billington",
                "state": "30",
                "countryCode": "PL"
            }
        },
        "browser": {
            "acceptHeaders": "*/*",
            "screenWidth": "1536",
            "javaEnabled": false,
            "timezoneOffset": "-120",
            "screenHeight": "864",
            "requestIP": "216.72.35.5",
            "language": "en",
            "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0",
            "colorDepth": "24"
        }
    }
}'
curl -X POST https://secure.snd.payu.com/api/v2_1/orders \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer d9a4536e-62ba-4f60-8017-6053211d3f47" \
    -d '{
    "continueUrl": "http://www.payu.pl",
    "customerIp": "216.72.35.5",
    "merchantPosId": "300746",
    "description": "Order with 3DS 2 required fields",
    "currencyCode": "PLN",
    "totalAmount": 300,
    "products": [
        {
            "name": "a product",
            "unitPrice": 300,
            "quantity": 1
        }
    ],
    "buyer": {
        "firstName": "John",
        "lastName": "Doe",
        "phone": "+48 555555555",
        "email": "john@doe.pl",
        "delivery": {
            "street": "Delivery St. 1",
            "postalCode": "55033",
            "city": "Delivery Town",
            "state": "30",
            "countryCode": "PL"
        }
    },
    "threeDsAuthentication": {
        "cardholder": {
            "name": "Joe Doe",
            "billingAddress": {
                "street": "Billing St. 1",
                "postalCode": "33055",
                "city": "Billington",
                "state": "30",
                "countryCode": "PL"
            }
        },
        "browser": {
            "acceptHeaders": "*/*",
            "screenWidth": "1536",
            "javaEnabled": false,
            "timezoneOffset": "-120",
            "screenHeight": "864",
            "requestIP": "216.72.35.5",
            "language": "en",
            "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0",
            "colorDepth": "24"
        }
    }
}'

3.3 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

Response with WARNING_CONTINUE_3DS status has been enhanced with threeDsProtocolVersion (currently always 3DS2) and iframeAllowed field. It will indicate that the redirectUri may be displayed in an iframe. If you are interested in utilizing the iframe instead of full redirection, see Authentication page section.

Sample response:

            {
                "status": {
                    "statusCode": "WARNING_CONTINUE_3DS",
                    "severity": "WARNING"
                },
                "redirectUri": "{redirectUri}",
                "iframeAllowed": true,
                "threeDsProtocolVersion": "3DS2",
                "orderId": "QK52JR2VCR201023GUEST000P01"
            }

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:

            {
                "status": {
                    "statusCode": "SUCCESS",
                    "statusDesc": "Request successful"
                },
                "threeDsProtocolVersion": "3DS2",
                "challengeParameters": {
                    "threeDsServerTransactionId": "0016f22b-f988-4358-b2c6-8917bba22037",
                    "acsTransID": "d7c1ee99-9478-44a6-b1f2-391e29c6b340",
                    "acsReferenceNumber": "3DS_LOA_ACS_201_13579",
                    "acsSignedContent": "someBase64encodedString"
                },
                "orderId": "JQC8TR8L4J201023GUEST000P01"
            }

3.4 3DS details in transaction data

As described in transaction data retrieve chapter, you may pull transaction data after the order is completed or canceled. Details of each field is described in this section, here we focus on explaining the 3DS result details. To properly understand the 3DS result, we need to check the following fields:

  • cardEciCode
  • card3DsStatus
  • card3DsFrictionlessIndicator
  • card3DsStatusDescription

3.4.1 ECI

ECI stands for Electronic Commerce Indicator and indicates the authentication level of the transaction. In practice, it informs about fraudulent chargebacks liability. For full authentication and attempted authentication, the liability is with the card issuer. In other cases the merchant is liable.

Note:

  • "full authentication" does not indicate whether the transaction was authenticated via challenge (cardholder needed to perform some action, usually compliant with "strong customer authentication" requirement) or was the authentication frictionless (no input or action by the cardholder)
  • "attempted authentication" means that PayU tried to authenticate, but the card issuer was not able to authenticate (in most cases because a particular card was not enrolled in 3DS service).
  • There is a special case for Mastercard where an unauthenticated transaction is subject to 3DS processing known as "data-only" (officially: Digital Transaction Insights). Sending data-only enriches the insights (hints) which Mastercard provides to the issuer. This however does not make the transaction to be treated as authenticated.

Values vary depending on card scheme. Available values are:

Stopień uwierzytelnienia Visa Mastercard
Full authentication 5 2
Attempted authentication 6 1
No authentication 7 0
No authentication, 3DS data sent to card scheme 4
Full authentication, recurring transaction 7
This is not a full list of available ECI codes, it only covers values you may receive in transaction data.

3.4.2 3DS status

  • Y - authentication successful
  • N - not authenticated (usually due to unsuccessful challenge)
  • U - unable to authenticate (technical problem, card not enrolled or data-only authentication)
  • A - attempt processed (not authenticated, but proof of attempted authentication was provided)
  • R - rejected (stronger version of N, issuer rejects without trying to challenge the cardholder)

Note: this is not a full list of statuses in 3DS 2 standard, it only covers the statuses that you may receive in transaction data.

3.4.3 Frictionless indicator

As mentioned above, ECI does not indicate whether the transaction was authenticated via challenge or not.

To help you understand whether the cardholder was challenged by the issuer and needed to perform some action, we are providing an additional field which is not a part of 3DS 2 standard. The challenge may take form of, for example, confirming the transaction in a mobile app ("out of bound authentication"), entering some one-time password (OTP, usually obtained via SMS text message, "dynamic authentication") or a entering a static password ("static authentication").

It is important to note that "challenge" does not necessarily mean strong customer authentication (SCA, as required in the European Economic Area countries). This is because SCA requires 2FA (two-factor authentication) and the issuer may only apply one factor. For issuers based in the EEA, it can be assumed that challenge equals SCA, however this may not apply to issuers from other regions.

Possible values of frictionless indicator:

  • YES
  • NO
  • UNKNOWN

3.4.4 3DS status description

3DS status description represents details of 3DS result and is a comma-separated array of several 3DS 2 data fields. Element values are descriptive representations of 3DS 2 codes specific for a given field.

Array elements are described in the table below. Please note that due to large number of possible values they are not enumerated (however most common combinations are explained in the Examples section below). The values themselves are most of the time descriptions of codes specified in 3DS 2 standard and taken "as is" from the specification. The standard itself explains the meaning of a particular field, but does not explain in details the values it can take. Therefore using particular values is up to specific implementation. For example, confirming transaction in the mobile app may be flagged by one issuer as "dynamic authentication" and by other as "out of bound".

Position Source Comment
0 3DS 2 version Specifies message version number (currently 2.1.0 or 2.2.0).
1 Device Channel Specifies whether the authentication took place in the browser or natively in a mobile app. Currently always "browser flow".
2 3DS Method Completion Indicator Specifies whether the issuer notified completion of fingerprinting by means of a hidden iframe displayed in the browser.
3 Authentication Type Applicable to authentications with challenge. Most common values are "dynamic authentication" and "out of boud". See Frictionless indicator for more details regarding challenge.
4 Challenge Cancel Applicable to authentications with challenge. Specifies whether the challenge was canceled and why.
5 Transaction Status Reason Provides information on why the Transaction Status field has the specified value.

3.4.5 Examples

Most common examples of 3DS status descriptions are below.

//Successful authentication of a Mastercard cardholder using 2.1.0 version.
//3DS method was not applied, cardholder was challenged.
"cardEciCode": "2",
"card3DsStatus": "Y",
"card3DsFrictionlessIndicator": "NO",
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,no cancel indicator,no status reason"
//Successful authentication of a Visa cardholder using 2.2.0 version. 
//3DS method was applied and no challenge was performed.
"cardEciCode": "5",
"card3DsStatus": "Y",
"card3DsFrictionlessIndicator": "YES",
"card3DsStatusDescription": "MessageVersion=2.2.0,browser flow,3DS method completed,frictionless authentication,no challenge,no status reason"
//Unauthenticated transaction for which 3DS data was provided to Mastercard. 
"cardEciCode": "4",
"card3DsStatus": "U",
"card3DsFrictionlessIndicator": "YES",
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,frictionless authentication,no challenge,data-only"
//Unsuccessful authentication of a Mastercard cardholder.
//Cardholder did not complete the challenge and transaction was timed out by the issuer.  
"cardEciCode": "0",
"card3DsStatus": "N",
"card3DsFrictionlessIndicator": "NO",
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,out of band authentication,challenge displayed - ACS timeout,timed out at ACS"
//Unsuccessful authentication of a Visa cardholder.
//Cardholder canceled the challenge.  
"cardEciCode": "7",
"card3DsStatus": "N",
"card3DsFrictionlessIndicator": "NO",
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,challenge canceled by cardholder,authentication failed"
//Unsuccessful authentication of a Visa cardholder.
//Challenge was not displayed and transaction was timed out by the issuer.
//Usually challenge is not displayed because there is no redirection to the URL of the authentication page returned from PayU.
"cardEciCode": "7",
"card3DsStatus": "N",
"card3DsFrictionlessIndicator": "NO",
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,challenge not displayed,timed out at ACS"

4 Handling soft declines

On markets subject to the SCA regulation, the card issuers have the right to soft decline authorization which has not been fully authenticated.

In case you do not redirect to PayU hosted payment page and use card tokenization, there are two possible ways to deal with soft declines for browser flow:

Resubmit authorization

Apply the following logic:

  1. Check response code for each failed card payment using transaction data retrieval.
  2. If cardResponseCode is SSD (soft decline), send a new order create request with threeDsAuthentication.challengeRequested set to MANDATE.

In the above case, the MANDATE value forces the card issuer to perform full authentication by means of a challenge.

IMPORTANT: after you develop this solution, please notify Customer Support to become excluded from the solution based on the PayU authentication page described below.

Use PayU authentication page

This solution does not require integration change related to handling WARNING_CONTINUE_3DS value returned in order create response, however it will cause the redirection link to be returned by PayU for EVERY non-authenticated (one-click) card payment (not flagged as RECURRING or STANDARD_MERCHANT).

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.

SDK flow

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.

4.1 Testing

Below instruction regards testing when your sandbox account has been excluded from default configuration (soft declines not handled by PayU). To exclude your account from default config please contact us and provide the shop id you are using.

To test a soft decline for any type of card payment:

  • use card data: 5100052384536818 with expiry date 02/2032 with any CVV value,
  • card data should be either entered on PayU hosted payment page, tokenized via Secure Form (tokenization type SINGLE) or submitted to PayU in plain text (without tokenization),
  • send an OrderCreateRequest with totalAmount equal or less than 300 pennies (regardless of currency) to exclude your payment from being authenticated via 3DS.

After performing the above, you will get OrderCreateResponse with SUCCESS status and a notification with CANCELED status. You can check that SSD status was the cancel reason by retrieving transaction details.

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=[two-letter ISO language code] (supported languages are: cs, en, es, pl, pt, ro, ru, sk, uk) param to the query string of authentication page URL address.

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

According to 3DS 2 standard "Cardholder information text" can be provided by the card issuer to the cardholder after a frictionless authentication.

Its display is mandated by 3DS 2 standard and card scheme rules.

In case it is provided by the issuer, it will be shown on the authentication page.

Note: This information comes directly from the issuer and its meaning can be only explained by the issuer.

Most of the times, the text contains explanation of why the authentication failed or instructs the cardholder to activate 3DS.

The language version of the text may sometimes not match the authentication page language version (usually issuers use the native language of their country of origin).

In case authentication page is framed (see Handling iframe), DISPLAY_FRAME message will be sent to the parent window.

5.3 Options

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

  • &cvv=false - disables the CVV form (in case the CVV is required, your website must handle it).
  • &lang=[two-letter ISO language code] - disables language auto-discovery and sets the language directly (only if it is supported).
  • &sendCreq=[true/false; default is true] - authentication page does not send CReq (challenge request) to initiate 3DS challenge. This parameter is useful when the authentication page is loaded twice (once as hidden iframe, then in visible iframe or full redirection). In such a case value false must be used during the first load to prevent CReq from being sent, because it can only be sent once.

5.4 Handling iframe

The below solution can be used only when iframeAllowed param returned in order create response is set to true.

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 - authentication has been finished, close the iframe. Note: term SUCCESSFUL has technical sense (no errors occurred), it does not indicate the business outcome (i.e. whether the cardholder has been authenticated).
  • AUTHENTICATION_CANCELED - errors occurred, 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 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_SUCCESSFUL'):
                        // close the iframe, do other specific stuff
                        break;
                    case ('AUTHENTICATION_CANCELED'):
                        // close the iframe, do other specific stuff
                        break;
                }
            }