Browser-based flow for 3DS 2.0 - Authentication-Only payments

Introduction

This page aims to describe the 3DS2 authentication-only flow to merchants with a backend-to-backend integration to the PXP Financial Payment Service.

An authentication-only payment can be used when a merchant only requires to perform 3DS2 authentication and authorisation is not required until later.

After the 3DS2 authentication data has been returned successfully for an authentication-only payment, a 3DS 2.0 Pass through payment can be initiated through PXP Financial using the relevant data fields, or the payment can be authorised through another Payment Service Provider.

In this flow, a merchant will perform 3DS 2.0 authentication without authorisation.

Process Overview

An authentication-only flow is initiated from a Merchant front-end, via a backend-to-backend call to PXP Financial. 3DS 2.0 Authentication is initiated, with the user experience being determined by either a frictionless or a challenge flow.

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

Integration Steps

Step 1: Create a new payment

Submit initiatePaymentRequest

The initiatePaymentRequest has been extended with new fields relevant to 3DS2 authentication. Existing merchants will need to extend their integration and send these fields in addition to those that they usually send.

Refer to the table from our main browser-based flow page which lists the 3DS 2.0 fields that should be sent in the initiatePaymentRequest (API documentation about initiatePaymentRequest can be located here).

❗️

Payment Method ID

The PaymentMethodID must be set to 345 for an authentication-only payment.

The merchant must send the following fields additionally in the initiatePaymentRequest:

FieldDescriptionRequired
AcquirerMIDThe merchant ID as assigned by the AcquirerY
AcquirerBINAcquiring institution identification code as assigned by the SchemeY
ThreeDSecureRequestorIDUnique identifier assigned by Scheme following 3DS2 enrolment. This must be provided if you are authorising through a different Acquirer or Gateway.Y

🚧

Consistency of Acquirer BIN and Acquirer MID in authentication and authorisation

Merchants are advised to ensure the Acquirer BIN and Acquirer MID are the same both in authentication and authorization requests.

🚧

Payments with '0' amount

There are two ways for submitting initiatePaymentRequest for a payment with '0' amount:

  • Do not send the amount element at all
  • Send '0' amount together with currencyCode attribute

📘

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

Example initiatePaymentRequest:

<?xml version="1.0" encoding="UTF-8"?>
<initiatePaymentRequest 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>
   <merchantTransactionID>852e88bd-3049-4c59-8fc5-f02ba65ccd3b</merchantTransactionID>
   <paymentMethodID>345</paymentMethodID>
   <userID>dd42ee1b-daab-40d4-8d04-82bf7ea7a53e</userID>
   <userData>
      <username>V3DSv2TesUser</username>
      <firstname>John</firstname>
      <lastname>Doe</lastname>
      <currencyCode>EUR</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>
   <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="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>UTC</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>60</value>
      </data>
      <data xsi:type="keyStringValuePair">
         <key>UserVerificationNotificationURL</key>
         <value>https://api.test2.kalixa.com/WebMockProviders/threedsv2acs/showcres</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>
      <data xsi:type="keyStringValuePair">
            <key>AcquirerMID</key>
            <value>7171021111000</value>
       </data>
       <data xsi:type="keyStringValuePair">
            <key>AcquirerBIN</key>
            <value>491677</value>
        </data>
      <data xsi:type="keyStringValuePair">
            <key>ThreeDSecureRequestorID</key>
            <value>100679177171021111</value>
      </data>
   </specificPaymentData>
   <paymentAccount>
      <specificPaymentAccountData>
         <data xsi:type="keyStringValuePair">
            <key>CardNumber</key>
            <value>5301250070000191</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

Information about the 3DS related fields returned in initiatePaymentResponse can be found here.

Further details on initiatePaymentResponse can be found here
.

The below table contains the specific fields for authentication-only payments returned in initiatePaymentResponse/ executePaymentActionResponse:

FieldDescription
IsFrictionlessAuthenticatedIndicates whether the payment has been successfully authenticated during frictionless flow.
Possible values: true/ false
IsScaMandatedIndicates if Strong Customer Authentications is mandatory as evaluated by PXP's Payment Service.
Possible values: true/ false

Example initiatePaymentResponse:

<?xml version="1.0" encoding="utf-8"?>
<initiatePaymentResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cqrpayments.com/PaymentProcessing">
	<payment xsi:type="paymentWithPaymentAccount">
		<merchantID>3DSv2_TestMerchant</merchantID>
		<shopID>3DSv2_TestShop</shopID>
		<paymentMethod>
			<key>345</key>
			<value>ThreeDSecureCardAuthentication</value>
		</paymentMethod>
		<merchantTransactionID>852e88bd-3049-4c59-8fc5-f02ba65ccd3b</merchantTransactionID>
		<paymentID>35076dd0-e138-4cbf-83a4-41a39658665f</paymentID>
		<userID>dd42ee1b-daab-40d4-8d04-82bf7ea7a53e</userID>
		<paymentProvider>
			<key>92</key>
			<value>CQRUK</value>
		</paymentProvider>
		<amount currencyCode="EUR">10</amount>
		<creationType>
			<key>3</key>
			<value>Api</value>
		</creationType>
		<userIP>127.0.0.1</userIP>
		<state>
			<id>8dfa209e-c501-4eb4-9a29-0a44e53a4b03</id>
			<definition>
				<key>581</key>
				<value>PendingOnClientDeviceDataCollection</value>
			</definition>
			<createdOn>2019-07-02T16:10:34.7624501Z</createdOn>
			<paymentStateDetails>
				<detail xsi:type="keyStringValuePair">
					<key>RedirectUrl</key>
					<value>https://api.test2.kalixa.com/WebMockProviders/threedsv2acs/fingerprint</value>
				</detail>
				<detail xsi:type="keyStringValuePair">
					<key>RedirectPostData</key>
					<value>threeDSMethodData=eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly93d3cubm90aWZpY2F0aW9uLmNvbSIsInRocmVlRFNTZXJ2ZXJUcmFuc0lEIjoiMzUwNzZkZDAtZTEzOC00Y2JmLTgzYTQtNDFhMzk2NTg2NjVmIn0=</value>
				</detail>
				<detail xsi:type="keyStringValuePair">
					<key>PaymentStateReasonID</key>
					<value>1</value>
				</detail>
			</paymentStateDetails>
		</state>
		<isExecuted>false</isExecuted>
		<baseAmount currencyCode="EUR">10</baseAmount>
		<paymentDetails>
			<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>18da3dbb-f493-4318-946a-5a998d339974</paymentAccountID>
		</paymentAccount>
	</payment>
</initiatePaymentResponse>

Step 2: Perform device fingerprinting

Integration steps for performing device fingerprinting are described here.

Step 3: PXP Financial performs authentication

Frictionless Authentication

If the state of the payment returned in initiatePaymentResponse or HandleClientDeviceDataCollection action response is 291 (AuthenticatedByThreeDSecure) then a challenge is not required. IsFictionlessAuthenticated field with value 'true' is returned to indicate that the payment has been successfully authenticated during frictionless flow. The authentication process stops here.

Example code sample with IsFictionlessAuthenticated field:

...
<paymentDetails>
            <detail xsi:type="keyStringValuePair">
                <key>ElectronicCommerceIndicator</key>
                <value>05</value>
            </detail>
            <detail xsi:type="keyBooleanValuePair">
                <key>IsScaMandated</key>
                <value>true</value>
            </detail>
            <detail xsi:type="keyStringValuePair">
                <key>ThreeDSecureVersion</key>
                <value>2.1.0</value>
            </detail>
            <detail xsi:type="keyStringValuePair">
                <key>CardholderAuthenticationVerificationValue</key>
                <value>MTIwODc5OTgyMTAzOTAwMzE2ODk=</value>
            </detail>
            <detail xsi:type="keyStringValuePair">
                <key>ThreeDSecureTransactionStatus</key>
                <value>Y</value>
            </detail>
            <detail xsi:type="keyBooleanValuePair">
                <key>IsFrictionlessAuthenticated</key>
                <value>true</value>
            </detail>
            <detail xsi:type="keyStringValuePair">
                <key>DirectoryServerTransactionID</key>
                <value>7b5fed48-70d2-4812-a8ca-56ec115ba35f</value>
            </detail>
        </paymentDetails>
...

Challenge requested

Explanation about the fields related to performing the challenge can be found here. If a challenge is required the value of IsFrictionlessAuthenticated is false.

Step 4: Perform Challenge Flow

Follow the instructions described here to perform the challenge.
If the challenge is successful, 291 (AuthenticatedByThreeDSecure) is returned in HandleUserVerification action response.

Step 5: Complete Authorisation

After the 3DS2 authentication data has been returned, a 3DS 2.0 Pass through payment can be initiated through PXP Financial or the payment can be authorised through another Payment Service Provider.

Failed authentication

If authentication was unsuccessful (authentication failed either in frictionless or challenge flow), the merchant will receive a reason code in ThreeDSecureTransactionStatusReason.

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

  • UserAuthenticationFailed (587) - when authentication fails during frictionless flow
  • UserAuthenticationErrorOccurred (600) - when an error occurs during frictionless flow
  • UserVerificationFailed (592) - when authentication fails during challenge flow
  • UserVerificationErrorOccurred (599) - this state is returned in shop notifications during challenge flow

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.

Payments in these states have ECI value = 07.

Possible values for TransactionStatusReason:

IDDescription
01Card authentication failed
02Unknown Device
03Unsupported Device
04Exceeds authentication frequency limit
05Expired card
06Invalid card number
07Invalid transaction
08No Card record
09Security failure
10Stolen card
11Suspected fraud
12Transaction not permitted to cardholder
13Cardholder not enrolled in service
14Transaction timed out at the ACS
15Low confidence
16Medium confidence
17High confidence
18Very High confidence
19Exceeds ACS maximum challenges
20Non-Payment transaction not supported
213RI transaction not supported
22ACS technical issue
23Decoupled Authentication required by ACS but not requested by 3DS Requestor
243DS Requestor Decoupled Max Expiry Time exceeded
25Decoupled Authentication was provided insufficient time to authenticate cardholder. ACS will not make attempt
26Authentication attempted but not performed by the cardholder

👍

3DS2 authentication only Integration Summary

In order to integrate with PXP Finanacial for a 3DS2 authentication only payment 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, proceed with the authorisation with PXP Financial or another Payment Service Provider
  • 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

3DS Test Scripts

3DS Test scripts can be found here.

Version History

DateDescription
22.12.2022Initial publication
16.01.2024Updated with minor text changes and removed 3DS1 Fallback information