New standard of authentication.
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.
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.
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.
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.
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.
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.
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.
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).
If you are perform card tokenization using Secure Form, your own form or via PayU widget, you have two options to consider:
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).
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).
You can test 3DS 2 scenarios using PayU sandbox.
Check table with test card data on the sandbox page for more details.
Only REST API has been enhanced with new data fields related to 3DS 2.
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:
payMethods.payMethod.value
set to any card-based payment: c, ap, jp, ma, vc,payMethods.payMethod.type
set to CARD_TOKEN,payMethods.card
object,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. |
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"
}
}
}'
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.
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" }
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" }
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:
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:
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.
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.
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:
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. |
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"
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:
Apply the following logic:
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.
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.
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.
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:
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.
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.
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:
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.
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.
You may use the below options by adding them to the query string of authentication page URL address:
false
must be used during the first load to prevent CReq from being sent, because it can
only be sent once.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>
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; }
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 */ } }
The iframe may post messages to its parent window with the following values in message.data property :
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; } }