Browser-based flow for 3DS 2.0

Introduction

This page aims to describe the browser-based flow of 3DS 2.0 to merchants with a backend-to-backend integration to the PXP Financial Payment Service.

In general, taking advantage of 3DS 2.0 requires sending additional information for risk assessment by Issuers. The more information is sent, the higher the chance for frictionless authentication, without further user interaction, to complete authentication.

PXP Financial has designed the 3DS 2.0 integration to be as easy as possible to integrate for both new and existing merchants.

Process Overview

A full browser-based 3DS 2.0 flow will be initiated from a merchant front-end, via a backend-to-backend call to PXP Financial.

When the payment is received and 3DS authentication is initiated, the user experience - and hence the required merchant actions - will vary depending on either a frictionless or a challenge flow being applied.

The diagram below illustrates the sequence of steps for each stage of the authentication:

912

Pre-requisites

  1. You must have a test account set up for use with PXP Financial
  2. If you are an existing merchant you should already have a fully integrated backend-to-backend integration in place
  3. If you are a new merchant please refer to the Initiate New Payment (Backend2Backend) section
  4. Ensure you have reviewed the 3DS Authorisation Policies information and selected a policy if the default policy behaviour is not desired

Integration Steps

Step 1: Create a new payment

Submit initiatePaymentRequest

The initiatePaymentRequest has been extended with new fields applicable to 3DS 2.0. Existing merchants will need to extend their existing integration and send these fields in addition to those that they usually send.

🚧

Sending 3DS 1.0 and 3DS 2.0 fields

To ensure a smooth transition from 3DS 1.0 to 3DS 2.0 merchants must send in the initiatePaymentRequest the required fields for both protocol versions.

3DS 1.0 will still be an active protocol and in cases where Issuers do not support 3DS 2.0, the authentication process will default to 3DS 1.0.

The table below lists the 3DS 1.0 and 3DS 2.0 fields that can be sent in initiatePaymentRequest (API documentation about initiatePaymentRequest can be located here). All these fields will be provided in initiatePaymentRequest.specificPaymentData.

FieldDescriptionRequired
SuccessPageUrlThe page to which the cardholder is directed if the payment is successful.
Note: This field is not applicable for authentication-only payments.
Y (required for fallback to 3DS 1.0)
ErrorPageUrlThe page to which the cardholder is directed if the payment is successful.
Note: This field is not applicable for authentication-only payments.
Y (required for fallback to 3DS 1.0)
BrowserHeaderAcceptThe exact content of the HTTP accept header as sent to the merchant from the cardholder's user agent. This field is required only if the cardholder's user agent supplied a value.
Example: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng
Y
BrowserHeaderUserAgentThe exact content of the HTTP User-Agent header.
Example: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0
Y
BrowserVerificationNotificationURLThe URL to which the result of fingerprinting will be postedY
UserVerificationNotificationURLThe notification URL to which the challenge response is sentY
BrowserJavaScriptEnabledAbility of the cardholder's browser to execute JavaScriptNote: If JavaScript is disabled, then you don't need to send us the below 6 Browser-related fields
BrowserLanguageThe cardholder's browser language as defined in IETF BCP 47.
The field should be taken from the 'navigator.language' property.
Y
BrowserScreenHeightTotal height of the cardholder's screen in pixels.
The field should be taken from the 'screen.height' property.
Y
BrowserScreenWidthTotal width of the cardholder's screen in pixels.
The field should be taken from the 'screen.width' property.
Y
BrowserTimeZoneDifference between UTC time and the cardholder's browser local time in minutes.
This is the value returned from the getTimezoneOffset() method.
Y
BrowserJavaEnabledAbility of the cardholder's browser to execute Java.
BrowserScreenColorDepthContains a value representing the bit depth of the colour palette, in bits per pixel, for displaying images
CardholderEmailEmail address of the cardholder
CardholderHomePhoneHome phone number provided by the cardholder.
Expected format:
<country_code>-<telephone_number>. <country_code> must be up to 3 digits. <telephone_number> is up to 15 digits.
Example:
359-453921233
CardholderMobilePhoneMobile phone number provided by the cardholder
CardholderWorkPhoneWork phone number provided by the cardholder
UserVerificationWindowSizeChallenge window size.
This field is relevant if a Challenge flow is triggered and indicates the dimensions of the challenge window that has been displayed to the cardholder. This information will be used by the ACS, which will reply to the browser with content that is formatted to appropriately render in this window to provide the best possible user experience.
Preconfigured sizes are width x height in pixels of the window displayed in the cardholder browser. Possible values are:
1: 250 x 400 (default, if not populated)
2: 390 x 400
3: 500 x 600
4: 600 x 400
5: Full screen

Note: If an invalid field is sent or a required field is missing in initiatePaymentRequest, the payment is stopped and initiatePaymentResponse with payment state 225 (ValidationFailed) is returned. More information about the specific error(s) with a payment can be found in Payment Service Admin.

📘

Additional Information means a greater chance for a Frictionless flow

The more data points are submitted the better chances the cardholder has for a frictionless authentication. Information about other data points can be found in the example below.

🚧

Use of IsThreeDSecureRequired field

The IsThreeDSecureRequired field is not used anymore but there are some exceptions. The field still has to be sent in the initiatePayment request when:

  • PSD2 is activated for the merchant and there are Card Verifications* used for initial storage of card details or for standard verification (without storage)
  • PSD2 is not activated for the merchant, and the merchant operates outside EEA but the merchant wants to authenticate payments (including non-Card Verifications)

*Payment methods: 202 - VisaCardVerification, 203 - ECMCCardVerification, 215 - MaestroCardVerification

Example initiatePaymentRequest:

<initiatePaymentRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cqrpayments.com/PaymentProcessing">
    <merchantID>3DSv2_TestMerchant</merchantID>
    <shopID>3DSv2_TestShop</shopID>
    <merchantTransactionID>TestCase3DSS-102-1001</merchantTransactionID>
    <paymentMethodID>2</paymentMethodID>
    <amount currencyCode="USD">10</amount>
    <userID>82937a69-ff7e-4ec3-8985-56f221659e87</userID>
        <userData>
                <username>V3DSv2TesUser</username>
                <firstname>John</firstname>
                <lastname>Doe</lastname>
                <currencyCode>USD</currencyCode>
                <languageCode>EN</languageCode>
                <email>[email protected]</email>
                <address>
                        <street>Marxergasse</street>
                        <houseNumber>1b</houseNumber>
                        <postalCode>1030</postalCode>
                        <city>Vienna</city>
                        <countryCode2>AT</countryCode2>
                        <telephoneNumber>044-52186</telephoneNumber>
                </address>                
                <gender>Male</gender>        
        </userData>
    <userIP>127.0.0.1</userIP>
    <userSessionID>96f4bca1-5e2b-4fc2-9d2d-540feaef1609</userSessionID>
    <creationTypeID>3</creationTypeID>
    <shippingDetails>
        <name>John Doe</name>
        <address>
            <street>Bruges str 1</street>
            <postalCode>7070</postalCode>
            <city>Bruges</city>
            <state>BEL</state>
            <countryCode2>BE</countryCode2>
        </address>
		</shippingDetails>
    <specificPaymentData>
        <data xsi:type="keyStringValuePair">
            <key>PaymentDescription</key>
            <value>626e7c42-bf0e-45fe-9e6c-54e8353ad0b8</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>PaymentDescriptionLanguageCode</key>
            <value>en</value>
        </data>
        <data xsi:type="keyBooleanValuePair">
            <key>IsThreeDSecureRequired</key>
            <value>true</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>SuccessPageUrl</key>
            <value>http:////success</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>ErrorPageUrl</key>
            <value>http:////error</value>
        </data>
        <data xsi:type="keyIntValuePair">
            <key>PaymentProviderID</key>
            <value>92</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>BrowserVerificationNotificationURL</key>
            <value>https://www.notification.com</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>BrowserLanguage</key>
            <value>en</value>
        </data>
        <data xsi:type="keyIntValuePair">
            <key>BrowserScreenHeight</key>
            <value>768</value>
        </data>
        <data xsi:type="keyIntValuePair">
            <key>BrowserScreenWidth</key>
            <value>1024</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>BrowserTimeZone</key>
            <value>180</value>
        </data>
        <data xsi:type="keyBooleanValuePair">
            <key>BrowserJavaEnabled</key>
            <value>true</value>
        </data>
        <data xsi:type="keyBooleanValuePair">
            <key>BrowserJavaScriptEnabled</key>
            <value>true</value>
        </data>
        <data xsi:type="keyIntValuePair">
            <key>BrowserScreenColorDepth</key>
            <value>15</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>BrowserHeaderAccept</key>
            <value>BrowserHeaderAccept</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>BrowserHeaderUserAgent</key>
            <value>BrowserHeaderUserAgent</value>
        </data>
        <data xsi:type="keyIntValuePair">
            <key>UserVerificationWindowSize</key>
            <value>5</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>UserVerificationNotificationURL</key>
            <value>https://userverificationnotificationurl.com</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>CardholderHomePhone</key>
            <value>044-52186</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>CardholderMobilePhone</key>
            <value>051-813678</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>CardholderWorkPhone</key>
            <value>044-13281</value>
        </data>
        <data xsi:type="keyStringValuePair">
            <key>CardholderEmail</key>
            <value>[email protected]</value>
        </data>
    </specificPaymentData>
    <paymentAccount>
        <specificPaymentAccountData>
            <data xsi:type="keyStringValuePair">
                <key>CardNumber</key>
                <value>4012005162084369</value>
            </data>
            <data xsi:type="keyStringValuePair">
                <key>HolderName</key>
                <value>John Doe</value>
            </data>
            <data xsi:type="keyIntValuePair">
                <key>ExpiryMonth</key>
                <value>12</value>
            </data>
            <data xsi:type="keyIntValuePair">
                <key>ExpiryYear</key>
                <value>2030</value>
            </data>
            <data xsi:type="keyStringValuePair">
                <key>CardVerificationCode</key>
                <value>111</value>
            </data>
        </specificPaymentAccountData>
    </paymentAccount>
</initiatePaymentRequest>

Receive initiatePaymentResponse

The table below lists the fields in initiatePaymentResponse:

FieldDescription
State.Definition.ValueThe possible states that could be returned in initiatePaymentResponse as described in the above tables
RedirectPostDataBase-64 encoded fingerprint data for a 3DS 2.0 payment. This must be used in Step 2.
RedirectUrlFor a 3DS 2.0 payment, this is the Method URL to which the received fingerprint data should be posted.
For a 3DS 1.0 payment, this is the URL to which the user will be redirected for further authentication (challenge).
ThreeDSecureVersionThe protocol version of 3DS
CardholderAuthenticationVerificationValuePayment System-specific value provided by the Issuer. This value may be used to provide proof of authentication.
ThreeDSecureTransactionStatusThe authentication status of the payment. Possible values:
Y - Authenticated successfully
A - Attempts Processing Performed; Not Authenticated/Verified, but a proof of attempted authentication/verification is provided.
N - Not Authenticated /Account Not Verified; Transaction denied.
C - Challenge Required
U - Authentication/ Account Verification Could Not Be Performed; Technical or other problem occurred
R - Authentication/ Account Verification rejected by the Issuer
ThreeDSecureTransactionStatusReasonThis field is sent only when ThreeDSecureTransactionStatus is different from Y or A.
Possible values:
01 - Card authentication failed
02 - Unknown Device
03 - Unsupported Device
04 - Exceeds authentication frequency limit
05 - Expired card
06 - Invalid card number
07 - Invalid transaction
08 - No Card record
09 - Security failure
10 - Stolen card
11 - Suspected fraud
12 - Transaction not permitted to cardholder
13 - Cardholder not enrolled in service
14 - Transaction timed out at the ACS
15 - Low confidence
16 - Medium confidence
17 - High confidence
18 - Very High confidence
19 - Exceeds ACS maximum challenges
20 - Non-Payment transaction not supported
21 - 3RI transaction not supported
22 - ACS technical issue
23 - Decoupled Authentication required by ACS but not requested by 3DS Requestor
24 - 3DS Requestor Decoupled Max Expiry Time exceeded
25 - Decoupled Authentication was provided insufficient time to authenticate cardholder. ACS will not make attempt
26 - Authentication attempted but not performed by the cardholder
DirectoryServerTransactionIDThe unique ID assigned to the payment by the Scheme

🚧

3DS 1.0 Fallback

When the payment request is received by PXP Financial, we check if 3DS 2.0 is supported for the card. If not, the payment is authenticated through 3DS 1.0.

Successful fallback to 3DS 1.0 requires sending the required fields relevant for this version (described in Submit initiatePaymentRequest section) and handling the response states accordingly as described below.

The table below lists the states in State.definition.value in the initiatePaymentResponse when a 3DS 1.0 fallback takes place:

PaymentState (payment state ID)DescriptionAction
RedirectDataCreated (287)The card is enrolled or the merchant chooses to allow redirection also for ADS (Activation During Shopping). PXP Financial's MPI has prepared the redirection data needed by the merchant for customer redirection to the 3DS authentication page.
The merchant should continue with step 5 3DS Authentication.
Redirect the customer to the 3DS authentication.
NotEnrolledInThreeDSecure (284)The card is not enrolled.Continue with authorisation.
The chargeback liability is with the Issuer.
NotEnrolledInThreeDSecureADSAvailable (285)The card is not enrolled, but "on-the-fly" enrollment is possible. This state is only returned in case the merchant has decided to not redirect the user for ADS (Activation During Shopping).Continue with authorisation.
The chargeback liability is with the Merchant.
VerifyThreeDSecureEnrollmentErrorReported (302)The enrollment check failed due to a scheme reported error.Continue with authorisation.
The chargeback liability is with the Merchant.
VerifyThreeDSecureEnrollmentErrorOccurred (283)The enrollment check failed due to a communication error or an invalid response from the scheme.Continue with authorisation.
The chargeback liability is with the Merchant.

For more information about the next steps in the 3DS 1.0 authentication process, please refer to Card Deposits with 3DS section.

The table below lists the states in State.definition.value in the initiatePaymentResponse that are relevant to a 3DS 2.0 frictionless flow:

PaymentState (payment state ID)DescriptionAction
PendingOnClientDeviceDataCollection (581)The card is enrolled for 3DS 2.0 and a Method URL exists.Continue with Step 2
UserAuthenticationSuccessful (586)The card is enrolled for 3DS 2.0, authentication is successful (frictionless flow ends)Continue according to the specific Authorisation Policy behavior
UserAuthenticationFailed (587)The card is enrolled for 3DS 2.0 but is not authenticated immediately without a challenge.
If the state is returned in initiatePaymentResponse then fingerprinting hasn't been performed because it's not supported by the Issuer.
Continue according to the specific Authorisation Policy behavior
UserAuthenticationErrorOccurred (600)The card is enrolled for 3DS 2.0 but is not authenticated due to a technical or other issue at the scheme's directory server.
If the state is returned in initiatePaymentResponse then fingerprinting hasn't been performed becase it's not supported by the Issuer.
Continue according to the specific Authorisation Policy behavior
UserAuthenticationRejected (597)The card is enrolled for 3DS 2.0 but authentication is declined by Issuer (frictionless flow ends).
If the state is returned in initiatePaymentResponse then fingerprinting hasn't been performed becase it's not supported by the Issuer.
Authorisation is not possible
AuthorisedByProvider (13)The card is enrolled for 3DS 2.0, authentication is successful (frictionless flow ends) and automatic authorisation is performed. It depends on the specific Authorisation Policy behaviorAuthorisation is successful - end of payment flow.
The chargeback liability is with Issuer.
PendingOnUserVerification (589)The card is enrolled for 3DS 2.0, authentication is performed and a challenge is required (challenge flow begins).Continue with Step 4

Example initiatePaymentResponse:

<initiatePaymentResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <payment xsi:type="paymentWithPaymentAccount">
        <merchantID>3DSv2_TestMerchant</merchantID>
        <shopID>3DSv2_TestShop</shopID>
        <paymentMethod>
            <key>2</key>
            <value>VISA Deposit</value>
        </paymentMethod>
        <merchantTransactionID>TestCase3DSS-102-1001</merchantTransactionID>
        <paymentID>e150a656-9b67-459e-b6f2-72b18355a680</paymentID>
        <userID>82937a69-ff7e-4ec3-8985-56f221659e87</userID>
        <paymentProvider>
            <key>92</key>
            <value>CQRUK</value>
        </paymentProvider>
        <amount currencyCode="USD">10</amount>
        <creationType>
            <key>3</key>
            <value>Api</value>
        </creationType>
        <userIP>127.0.0.1</userIP>
        <state>
            <id>7c53aca4-f366-4270-b028-82dbe6d06d5a</id>
            <definition>
                <key>581</key>
                <value>PendingOnClientDeviceDataCollection</value>
            </definition>
            <createdOn>2019-05-16T14:18:19.9970102Z</createdOn>
            <paymentStateDetails>
                <detail xsi:type="keyStringValuePair">
                    <key>RedirectUrl</key>
                    <value>http://bowser.com/getdata</value>
                </detail>
                <detail xsi:type="keyStringValuePair">
                    <key>RedirectPostData</key>
                    <value>threeDSMethodData=eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly93d3cubm90aWZpY2F0aW9uLmNvbSIsInRocmVlRFNTZXJ2ZXJUcmFuc0lEIjoiZTE1MGE2NTYtOWI2Ny00NTllLWI2ZjItNzJiMTgzNTVhNjgwIn0=</value>
                </detail>
                <detail xsi:type="keyStringValuePair">
                    <key>PaymentStateReasonID</key>
                    <value>1</value>
                </detail>
            </paymentStateDetails>
        </state>
        <isExecuted>false</isExecuted>
        <baseAmount currencyCode="EUR">6.64</baseAmount>
        <paymentDetails xsi:nil="true">
          <detail xsi:type="keyStringValuePair">
						<key>ElectronicCommerceIndicator</key>
						<value>07</value>
					</detail>
          <detail xsi:type="keyStringValuePair">
            <key>ThreeDSecureVersion</key>
            <value>2</value>
          </detail>
        </paymentDetails>
        <paymentAccount>
            <paymentAccountID>bceb192e-8488-4615-a459-87ea33b46608</paymentAccountID>
        </paymentAccount>
    </payment>
</initiatePaymentResponse>

Further details on initiatePaymentResponse can be found here
.

Step 2: Perform Device fingerprinting

When the state of the payment is PendingOnClientDeviceDataCollection device fingerprinting should be carried out:

  1. Use the information from initiatepaymentResponse provided in the fields RedirectPostData and RedirectURL.
    Note: If RedirectUrl and RedirectPostData are missing from the InitiatePaymentResponse, skip this step and proceed to Step 3.
  2. Extract the threeDSMethodData value from the RedirectPostData field.
  3. Render a hidden HTML iframe, in the Cardholder browser, with a form containing a field named threeDSMethodData with the extracted value
  4. Submit the form via HTTP POST to the RedirectURL.
    Example: threeDSMethodData to be sent to ACS in the 3DS Method HTTP form POST
<form name="frm" method="POST" action="RedirectURL">
	<input type="hidden" name="threeDSMethodData"
value="eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjNhYzdjYWE3LWFhNDItMjY2My03OTFiLTJhYzA1YTU0MmM0YSIsInRocmVlRFNNZXRob2ROb3RpZmljYXRpb25VUkwiOiJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIn0" />
</form>
  1. The Issuer’s ACS should respond with an HTTP POST with a field threeDSMethodData submitted to your BrowserVerificationNotificationURL. If the response is not received within 10 seconds of the POST you should consider the fingerprinting as unsuccessful, continue with point 6 and refer to the example HandleClientDeviceDataCollection action if fingerprinting is not successful.
    Example: threeDSMethodData to be sent to 3DS Method Notification URL from the ACS.
<form name="frm" method="POST" action="BrowserVerificationNotificationURL">
<input type="hidden" name="threeDSMethodData"
value="eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjNhYzdjYWE3LWFhNDItMjY2My03OTFiLTJhYzA1YTU0MmM0YSIsInRocmVlRFNNZXRob2ROb3RpZmljYXRpb25VUkwiOiJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIn0" />
</form>

Note 1: We provide a mock for the issuer’s ACS fingerprinting at https://api.test.kalixa.com/WebMockProviders/threedsv2acs/fingerprint (this URL will be returned in the RedirectURL). In order to simulate the timeout and test your implementation, you may additionally specify a delay in seconds by adding a query string parameter 'delay' in the HTTP POST action URL. Example: https://api.test.kalixa.com/WebMockProviders/threedsv2acs/fingerprint?delay=11.
Note 2: To match the received request to a payment in your system we recommend to use a unique id of the payment on your side in the BrowserVerificationNotificationURL that you send in the initiatePaymentRequest. Example: https://domain.com/api/verificationListener?paymentId=284894.

  1. Send PXPFinancial a HandleClientDeviceDataCollection action for the payment with the following details:
ActionDataKeyDescriptionComments
merchantIDThe id of the merchant
shopIDThe id of the shop
paymentIDThe ID of the payment returned in the initiatePaymentResponse.
actionIDThe ID of the action - set to 2000
actionDataThe threeDSMethodData received at the BrowserVerificationNotificationURLThe data.key is threeDSMethodData.
If you don't receive fingerprint notification within 10 sec, it is considered unsuccessful. In this case, you should not send the actionData.

Example HandleClientDeviceDataCollection action:

<executePaymentActionRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cqrpayments.com/PaymentProcessing">
    <merchantID>3DSv2_TestMerchant</merchantID>
    <shopID>3DSv2_TestShop</shopID>
    <paymentID>e150a656-9b67-459e-b6f2-72b18355a680</paymentID>
    <actionID>2000</actionID>
    <actionData>
        <data xsi:type="keyStringValuePair">
            <key>threeDSMethodData</key>
            <value>eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjI0N2UyYzU2LT UyZWUtNGQ2My05NjljLTUwNzg2NjY2YjY5MCJ9</value>
        </data>
     </actionData>
</executePaymentActionRequest>

Example HandleClientDeviceDataCollection action if fingerprinting is not successful:

<executePaymentActionRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cqrpayments.com/PaymentProcessing">
    <merchantID>3DSv2_TestMerchant</merchantID>
    <shopID>3DSv2_TestShop</shopID>
    <paymentID>e150a656-9b67-459e-b6f2-72b18355a680</paymentID>
    <actionID>2000</actionID>
</executePaymentActionRequest>

If the format of the 'HandleClientDeviceDataCollection' action is invalid, we will stop processing the payment, it will remain in its last state up to that moment - PendingOnClientDeviceDataCollection. If PaymentID cannot be matched with existing payment on our side, we will stop processing the payment.

Example 'HandleClientDeviceDataCollection' action response:

<?xml version="1.0"?>
<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <statusCode>1</statusCode>
  <actionResults>
    <result xsi:type="keyStringValuePair">
      <key>lastStateDefinition</key>
      <value>589</value>
    </result>
    <result xsi:type="keyStringValuePair">
      <key>ElectronicCommerceIndicator</key>
      <value>07</value>
     </result>
     <result xsi:type="keyStringValuePair">
       <key>ThreeDSecureVersion</key>
       <value>2.1.0</value>
     </result>
     <result xsi:type="keyStringValuePair">
       <key>ThreeDSecureTransactionStatus</key>
        <value>C</value>
      </result>
      <result xsi:type="keyStringValuePair">
        <key>DirectoryServerTransactionID</key>
        <value>71271871-b53a-4089-9a21-a7202dcecd46</value>
      </result>
      <result xsi:type="keyStringValuePair">
        <key>RedirectUrl</key>
       <value>https://api.test.kalixa.com/WebMockProviders/threedsv2acs/challenge</value>
      </result>
      <result xsi:type="keyStringValuePair">
        <key>RedirectPostData</key>
      <value>creq=eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiJkZWEwZDcxMC1iZjgwLTQ1NzQtODA4NS1mYjc4OGQ0ZDBkNmYiLCJhY3NUcmFuc0lEIjoiNDJhNGIyMWQtOTgzNy00NDUxLTkxZGItOGI5YjdiYWY3YzBiIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjA1In0=</value>
        </result>
        <result xsi:type="keyStringValuePair">
          <key>PaymentStateReasonID</key>
          <value>1</value>
        </result>
   </actionResults>
</executePaymentActionResponse>

Step 3: PXP Financial performs authentication

Frictionless Authentication

If the state of the payment is 13 (AuthorisedByProvider) then a challenge is not required and the payment will proceed according to the specific 3DS Authorisation Policy behaviour. The authentication process stops here.

Challenge requested

If the state of the payment is 589 (PendingOnUserVerification) then a challenge is required and the user must be redirected to the Issuer’s ACS for further authentication. In this case the following data is provided to you in the executeActionResponse:

FieldDescription
RedirectUrlThe ACS’s URL to which the user should be redirected to perform the challenge.
RedirectPostDataContains the creq field (ChallengeRequest) that should be posted to the ACS.

Example executeActionResponse for a Challenge:

<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <statusCode>1</statusCode>
    <actionResults>
        <result xsi:type="keyStringValuePair">
            <key>lastStateDefinition</key>
            <value>589</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>RedirectUrl</key>
            <value>https://api.test.kalixa.com/WebMockProviders/threedsv2acs/challenge</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>RedirectPostData</key>
              <value>creq=eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiIyN2ZhN2U2Yy1iY2NkLTQwM2YtOGRiYS1hNTU2NzA1N2JlNTkiLCJhY3NUcmFuc0lEIjoiYzkyYTM3ZmUtNTg2Mi00NWEyLWEzNWMtNjM5Y2RkNmMwY2FkIiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAxIn0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>PaymentStateReasonID</key>
            <value>1</value>
        </result>
    </actionResults>
</executePaymentActionResponse>

Step 4: Perform Challenge Flow

The challenge flow has the following steps:

  1. Use the RedirectPostData value from the executeActionResponse or initiatePaymentResponse to extract the CReq (only the value).
  2. Create an HTML iframe in the cardholder’s browser with a form containing a field named creq with the extracted value. Note: this iframe/ window is sized according to the value of UserVerificationWindowSize sent in the initiatePaymentRequest.
  3. Submit the form via HTTP POST to the ACSURL returned in RedirectUrl value in order to display the challenge window. Note: We provide a mock for the issuer’s challenge window, where you can choose the outcome of the challenge, to test the different scenarios.
  4. Wait for the Issuer's challenge response to the UserVerificationNotificationURL (sent in the initiatePaymentRequest). This will contain a cres field which should be extracted.
    If a response is not received within 10 minutes then the challenge process is considered as unsuccessful.
    Note: To match the received challenge response to a payment in your system we recommend to include a unique payment id on your side in the UserVerificationNotificationURL that you send in the initiatePaymentRequest.
  5. Send PXPFinancial a HandleUserVerification action for the payment with the following details:
FieldDescription
merchantIDThe id of the merchant
shopIDThe id of the shop
paymentIDThe ID of the payment returned in the initiatePaymentResponse
actionIDThe ID of the action - set to 2010
actionDataThe cres received from the ACS at the UserVerificationNotificationURL. The data.key is cres.

The table below lists the states in State.definition.value in the HandleUserVerificationResponse that are relevant to a 3DS 2.0 challenge flow:

PaymentState (payment state ID)DescriptionAction
UserVerificationPassed (591)The card is enrolled for 3DS 2.0 and is authenticated following a successful challenge.Continue according to the specific Authorisation Policy behavior
UserVerificationFailed (592)The card is enrolled for 3DS 2.0 but is not authenticated following a failed challenge.Continue according to the specific Authorisation Policy behavior
UserVerificationErrorOccurred (599)The card is enrolled for 3DS 2.0 but is not authenticated following a challenge due to a technical or other issue at the scheme's directory server.Continue according to the specific Authorisation Policy behavior
UserVerificationRejected (598)The card is enrolled for 3DS 2.0 but challenge is declined by Issuer (challenge flow ends).Authorisation is not possible
AuthorisedByProvider (13)The card is enrolled for 3DS 2.0, challenge is successful and automatic authorisation is performed. It depends on the specific Authorisation Policy behaviorAuthorisation is successful - end of payment flow.
The chargeback liability is with Issuer.

Example HandleUserVerification action:

<executePaymentActionRequest xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <merchantID>3DSv2_TestMerchant</merchantID>
   <shopID>3DSv2_TestShop</shopID>
    <paymentID>27fa7e6c-bccd-403f-8dba-a5567057be59</paymentID>
   <actionID>2010</actionID>
   <actionData>
      <data xsi:type="keyStringValuePair">
         <key>cres</key>
         <value>ew0KCQkJCSJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjI3ZmE3ZTZjLWJjY2QtNDAzZi04ZGJhLWE1NTY3MDU3YmU1OSIsDQoJCQkJImFjc1RyYW5zSUQiOiIzNTJlNzJlOC04ZDM5LTRkODctODM0Ni1iMWM5MDFlZWJmZjEiLA0KCQkJCSJjaGFsbGVuZ2VDb21wbGV0aW9uSW5kIjoiWSIsDQoJCQkJInRyYW5zU3RhdHVzIjoiWSIsDQoJCQkJIm1lc3NhZ2VUeXBlIjoiQ1JlcyIsDQoJCQkJIm1lc3NhZ2VWZXJzaW9uIjoiMi4xLjAifQ</value>
      </data>
   </actionData>
</executePaymentActionRequest>

If PaymentID cannot be matched with existing payment on our side or the format of the HandleUserVerification action is invalid, we will stop processing the payment, it will remain in its last state up to that moment.

Step 5. Complete Authorisation (Challenge Flow)

If the challenge is successful, the payment will proceed according to the specific 3DS Authorisation Policy behaviour.

Example HandleUserVerification action response:

<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <statusCode>0</statusCode>
    <actionResults>
        <result xsi:type="keyStringValuePair">
            <key>lastStateDefinition</key>
            <value>13</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ElectronicCommerceIndicator</key>
            <value>05</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureTransactionStatus</key>
            <value>Y</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>DirectoryServerTransactionID</key>
            <value>cddfdd81-ca02-4fff-8914-07587ffbd312</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureVersion</key>
            <value>2.1.0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>CardholderAuthenticationVerificationValue</key>
            <value>MTIzNDU2Nzg5MDA5ODc2NTQzMjE=</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ProviderResponseCode</key>
            <value>0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ApprovalCode</key>
            <value>893639</value>
        </result>
    </actionResults>
</executePaymentActionResponse>

🚧

Downgraded payments - MasterCard

Successfully authenticated payments are chargeback protected by Issuer and have ECI = 02. However, it is possible during authorization the Issuer to downgrade the payments from authenticated to unauthenticated and the liability is shifted back to the merchant. When this happens, we return the following two fields in initiatePayment/ executeAction response:
ElectronicCommerceIndicator = 07
ECIAfterAuthentication = 02

Handling Authentication Failures

PXP Financial will authorise successfully authenticated transactions by default or based on the auhtorisation policy configure for the merchant. When authentication is not successful however, PXP Financial will proceed with authorisation only if the specific authorisation policy allows it.

One of the following states is returned for a payment with failed authentication:

  • UserAuthenticationFailed (587)
  • UserAuthenticationErrorOccurred (600)
  • UserVerificationFailed (592)
  • UserVerificationErrorOccurred (599) - this state is returned in shop notifications during challenge flow.

For more information about the states you can refer to the table with states relevant to 3DS 2.0 in Step 1 of the Integration Steps section.

Payments in these states have ECI value = 07. The reason code is received in ThreeDSecureTransactionStatusReason.
To proceed with the authorisation, send an Authorise executePaymentActionRequest.

🚧

Liability shift for authentication failures

There is no liability shift to Issuer when the payment hasn’t been authenticated successfully or user challenge hasn’t been successful. This means that the payment does not receive chargeback protection.

Example Authorise executePaymentActionRequest for authorising a payment:

<executePaymentActionRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cqrpayments.com/PaymentProcessing">
    <merchantID>3DSv2_TestMerchant</merchantID>
    <shopID>3DSv2_TestShop</shopID>
    <paymentID>ac6f9509-f477-44f7-bbb6-d5e3b7654c43</paymentID>
    <actionID>120</actionID>
</executePaymentActionRequest>

Example Authorise executePaymentActionResponse for the authorised payment:

<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <statusCode>0</statusCode>
    <actionResults>
        <result xsi:type="keyStringValuePair">
            <key>lastStateDefinition</key>
            <value>13</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ElectronicCommerceIndicator</key>
            <value>07</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureTransactionStatus</key>
            <value>U</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>DirectoryServerTransactionID</key>
            <value>90057b4d-76b5-48bd-bbb4-d0dc665ada40</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureVersion</key>
            <value>2.1.0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ProviderResponseCode</key>
            <value>0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ApprovalCode</key>
            <value>128634</value>
        </result>
    </actionResults>
</executePaymentActionResponse>

📘

Challenge cancelled by user

Payments with failed authentication due to challenge cancelled by user are considered as risky for authorising.
For that purpose, we could pass the information to you so that you can better decide whether to proceed with authorisation in such cases.
The information is returned in ThreeDSecureChallengeCancelIndicator.
Possible values:
01 - Cardholder selected “Cancel”
03 - Transaction Timed Out—Decoupled Authentication
04 - Transaction Timed Out at ACS—other timeouts
05 - Transaction Timed Out at ACS—First CReq not received by ACS
06 - Transaction Error
07 - Unknown
08 - Transaction Timed Out at SDK

Example HandleUserVerification action response with ThreeDSecureChallengeCancelIndicator:

<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <statusCode>1</statusCode>
    <actionResults>
        <result xsi:type="keyStringValuePair">
            <key>lastStateDefinition</key>
            <value>592</value>
        </result>
        <result xsi:type="keyBooleanValuePair">
            <key>IsFrictionlessAuthenticated</key>
            <value>false</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureTransactionStatus</key>
            <value>N</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>DirectoryServerTransactionID</key>
            <value>26caf68a-ced8-47f8-830c-af2bcc63bb48</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureVersion</key>
            <value>2.2.0</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureTransactionStatusReason</key>
            <value>01</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>ThreeDSecureChallengeCancelIndicator</key>
            <value>01</value>
        </result>
        <result xsi:type="keyStringValuePair">
            <key>PaymentStateReasonID</key>
            <value>1</value>
        </result>
    </actionResults>
</executePaymentActionResponse>

Authentication Declines

A payment declined by the Issuer cannot be authorised.
One of the following states is returned for a payment with declined authentication:

  • 597 (UserAuthenticationRejected) - when payment is declined during frictionless flow
  • 598 (UserVerificationRejected) - when payment is declined during challenge flow.

The reason code for declining the payment is received in ThreeDSecureTransactionStatusReason. For more information about the possible values you can refer to the table with fields relevant to 3DS 2.0 in Step 1 of the Integration Steps section.

👍

3DS 2.0 Integration Summary

In order to integrate with PXP Financial for 3DS 2.0 you will need to:

  • Send additional data in initiatePaymentRequest
  • Perform Device Fingerprinting using a listener you have implemented
  • Notify PXP Financial of the result
  • In a frictionless flow, PXP Financial will proceed the the payment according to the specific 3DS Authorisation Policy behaviour, then notify you
  • In case of a challenge flow, perform the challenge using a second listener you have implemented
  • Forward the results to PXP Financial
  • PXP Financial will notify you of the authentication result, and proceed the payment according to the specific 3DS Authorisation Policy behaviour

3DS Test Scripts

3DS Test scripts can be found here.

Version History

DateDescription
5.06.2019Added more code samples to Perform Device fingerprinting section.
4.07.2019Add new fields to initiatePaymentResponse: ElectronicCommerceIndicator and ThreeDSecureVersion.
Add new fields to HandleClientDeviceDataCollection action response: ElectronicCommerceIndicator, ThreeDSecureVersion, ThreeDSecureTransactionStatus and DirectoryServerTransactionID
Add new fields to HandleUserVerification action response: ElectronicCommerceIndicator, ThreeDSecureTransactionStatus, DirectoryServerTransactionID, ThreeDSecureVersion and CardholderAuthenticationVerificationValue.
19.09.2019Added link to 3DS test scripts.
22.10.2019Addition of 3DS Authorisation Policies information to describe how authentication-to-authorisation behaviour can be managed.
13.12.2019Added Handling Authentication Failures and Authentication Declines sections.
Added new fields to Receive initiatePaymentResponse section: CardholderAuthenticationVerificationValue, ThreeDSecureTransactionStatus, ThreeDSecureTransactionStatusReason and DirectoryServerTransactionID.
17.01.2020Added sentence about validation of fields in 'initiatePaymentRequest'.
26.07.2021Added callout about MasterCard downgraded transactions.
Added callout about challenge cancelled by user.
30.07.2021Remove IsThreeDSecureRequired from the table with 3DS 1.0 and and 3DS 2.0 fields because it is going to be deprecated soon. Merchants who have integrated PSD 2 have to use ScaPolicyID and ScaChallengeIndicator fields instead.
3.06.2022Add callout "Use of IsThreeDSecureRequired field" with clarification on the cases when IsThreeDSecureRequired still has to be sent in initiatePayment requests.