EMV® 3-D Secure (v2)

Overview

As part of the second Payment Service Directive mandate (PSD2), certain e-commerce transactions as of the 14th March 2022 are subjected to Secure Customer Authentication (SCA) in Europe.

This developer documentation will focus on SCA’s requirements, which transactions will be affected and how to integrate via the Acquired.com API solution.

To satisfy SCA’s requirements, you, the merchant, will have to authenticate your customers using EMV® 3-D Secure. This is the updated version of the 3-D Secure authentication protocol as agreed by EMVco.

For more information on the background of 3-D Secure v1, please see here.

SCA is a European requirement created to reduce levels of fraudulent transactions and to increase overall security for consumers. Currently, SCA requires customer authentication to include two of the following three aspects:

  1. Knowledge: Something only the customer knows e.g a password.
  2. Possession: Something only the customer possess e.g. phone number, email address).
  3. Inherence: Something the customer is e.g biometric reader, face ID, fingerprint).

By integrating via EMV® 3-D Secure, you will be satisfying all these criteria. Issuers may authenticate cardholders using a phone number or ensuring the customer is present by requiring a fingerprint/Face ID. If you do not satisfy two of the three requirements, the issuing banks may decline some transactions, reducing your authorisation rate. For further information on PSD2’s SCA requirements, please see here.

When do you need to apply SCA

If you’re Merchant Category Code (MCC) is set as 6012, you will lie within the Financial Services industry and as such, you will be more than familiar with Continuous Payment Authorities (CPA).

SCA will only be applicable to you and your business when customers are signing up to your services and if they visit your site to complete ad hoc payments.

What this means for your integration is that EMV® 3-D Secure only applies for your INIT transactions and REBILLs are exempt. REBILL transactions processed using tokenised details are known as Merchant Initiated Transactions (MIT) and are exempt from SCA requirements. For further information on SCA exemptions, please see here.

Other Exemptions

Low value payments: authorisiation below €30 are considered to be "low value" are are potentially exempt from SCA. However, it may be required where the cardholder has not been authenticated for the previous 5 transactions or if the sum of the previous 5 exempt transactions exceeds €100.

Fixed Amount Subscriptions: transactions where the cardholder makes a series of recurring payments for the same amount, to the same business. SCA will be required on the first transaction (INIT), with subsequent payments potentially being exempt.

Mail Order Telephone Order: payments taken over the phone should be exempt. Make sure you are passing the vt parameter set to 1 for these payments.

The Flow

The 3-D Secure process involves a number of steps which we’ve summarised below.

  1. Check the 3DS Version: Check with us if the customers issuing bank supports EMV® 3-D Secure so you know how to proceed. If they do, the customer is enrolled and you can continue with authentication via EMV® 3-D Secure. If they do not, you should continue the authentication process using 3-D Secure v1.
  2. Gathering Device Data: If the cardholder is enrolled, you will be required to gather additional device data.
  3. Perform Authentication: The issuer is ready and as such, you are going to proceed using EMV® 3-D Secure. To do this, you will be passing through some additional parameters within the authorisation message sent to us (customer, billing and device data).
  4. Challenge Flow: There are cases where the issuing bank may require or request more information from the cardholder when processing transactions. You will receive a response message informing you to display the issuers page to the customer. You must handle this response, open an i-Frame for the customer and then send us one more request to complete the payment.
Just so you know, our Hosted Payment Page solution will handle all these steps for you. It just requires a few extra parameters in the request.

Check 3-D Secure Version

In October 2022, the card schemes (Visa & Mastercard) stopped support for 3-D Secure v1 and removed any liability shift. Due to this we recommend not accepting transactions where the enrolled status is false.

Request

As the user is entering their card details on your payment page, you will need to check with us if the customer's issuing bank supports EMV® 3-D Secure.

We recommend executing this request as soon as the user completes the card number field on your payment form.

To complete this step, you have to send the below JSON message to https://qaapi.acquired.com/api.php/forward/tds_version.

{
    “company_id”: “113”,
    "company_mid_id": "1045",
    "currency_code_iso3": "GBP",
    “cardnumber”: "4263970000005262",
    “method_notification_url”: “https://yourdomain.com/method_notification_url”
}
Parameter Format Length Description
company_id
Required
int 3 API Company ID we issue to merchants.
company_mid_id int 4 Targets a specific mid_id within the company structure. If you want to send the authorisation through a specific MID you will need to send it here.
currency_code_iso3 string 3 Transaction currency, an ISO 4217 3-digit code. If you process in more than one currency you will need to pass which one here.
cardnumber
Required
string 16-19 Card number used for the transaction.
method_notification_url
Required
url 1-256 Where the ACS should POST back their response to if threeDSMethodData is returned.

Response

In the response message back to you, we will let you know if the customer is enrolled for EMV® 3-D Secure. If the customer is enrolled, we will pass back the true value. If the customer is not enrolled, we will pass back the false value.

Here is an example where the cardholder is enrolled for EMV® 3-D Secure and the issuing bank wants to gather more device data via the method_url as described here.

{
    "server_trans_id": "d1eb55be-1095-4dc8-a65d-1d14a230ddac",
    "enrolled": true,
    "method_url": "https://acs.acquired.com/method",
    "threeDSMethodData": "ewogICJ0aHJlZURTU2VydmVyVHJhbnNJRCIgOiAiNTM5ZWExZjUtMTdkYy00Y2M1LWJhN2ItYTk5ZjdkZTE5ZTlhIiwKICAidGhyZWVEU01ldGhvZE5vdGlmaWNhdGlvblVSTCIgOiAiaHR0cHM6Ly95b3VyZG9tYWluLmNvbS9tZXRob2Rfbm90aWZpY2F0aW9uX3VybCIKfQ"
}
Pro Tip: You will need the server_trans_id for the next step.
Parameter Format Length Description
server_trans_id string 36 Unique Acquired.com reference, needed for Authentication.
enrolled boolean Will let you know if the cardholder is enrolled for EMV® 3-D Secure or not.
method_url url The URL of the ACS which you should open in a hidden i-Frame.
threeDSMethodData string 1-2048 Base64url encoded value that must you must POST to the method_url.

Method URL

If you receive the method_url and method_data parameters, the issuing bank is requesting to collect additional data about the customer's device to help them authenticate the transaction.

To gather said additional data, you will have to open up a hidden i-Frame and POST the threeDSMethodData value to the method_url. The threeDSMethodData value is a base64 encoded JSON object containing a unique "threeDSServerTransID" and your method_notification_url.

Here is a handy emample of what you need to do:

><!DOCTYPE html>
    <html>
    <meta charset="ISO-8859-1">
    <head>
    <title>Sample Open method_url Page</title>
    <script>
        var form = document.createElement("form");
        form.setAttribute("method", "POST");
        form.setAttribute("action", "https://acs.acquired.com/method");
        form.setAttribute("target", "hidden_iframe");
    
        var threeDSMethodData = document.createElement("input");
        threeDSMethodData.setAttribute("type", "hidden");
        threeDSMethodData.setAttribute("name", "threeDSMethodData");    
        form.appendChild(threeDSMethodData);
        document.body.appendChild(form);
    
        form.submit();
    </script>
    </head>
    <body>
        <iframe id="hidden_iframe" name="hidden_iframe" style="display: none;"></iframe>
    </body>
    </html>

    

If the issuing bank then successfully gathers the Device ID they will send back a POST message to your method_notification_url within 10 seconds (please be aware, the timeframe should be a lot quicker, this is the longest it can take) returning the threeDSMethodData.

If you've executed the "Check 3-D Secure Version" request when the user completes the card number field, you should have got a response by the time the user submits the payment form.

Great, you got a response, you can close the i-Frame and set the method_url_completion value in the next step to 1.

If you haven’t received a response or can not wait the full 10 seconds to proceed (waiting 3 seconds might be enough), you can close the i-Frame and set the method_url_completion value in the next step to 2.

Never received a method_url or threeDSMethodData? You can set the method_url_completion to 3.

Gathering Device Data

As EMV® 3-D Secure is an improved authentication method, there is more information required to be gathered about each customer when submitting the transaction request. To complete this, you will have to collect and send us more information about the customer’s browser / device used.

This required information can be gathered when your customer lands onto your website (recommended) or when they’re entering their card details after you've checked the 3-D Secure version - the choice is yours but we will need the following fields:

Parameter Format Length Description
accept_header string 1-2048 HTTP accept headers as sent by the browser.
color_depth Enum Browser color depth: Acceptable values: ONE_BIT, TWO_BITS, FOUR_BITS, EIGHT_BITS, FIFTEEN_BITS, SIXTEEN_BITS, TWENTY_FOUR_BITS, THIRTY_TWO_BITS, FORTY_EIGHT_BITS.
ip string 7-39 IP address returned by the browser in either IPv4 or IPv6 format.
java_enabled boolean If the browser can execute Java.
javascript_enabled boolean If the browser can execute JavaScript.
language string 1-8 Browser language (en-US = English for example).
screen_height int 1-6 Total height of the user's screen in pixels.
screen_width int 1-6 Total width of the user's screen in pixels.
user_agent string 1-2048 Exact content of the HTTP user-agent header sent by the browser.
timezone string 1-5 Time difference between UTC time and the user’s browser time, in minutes.
Keep reading: You will see exactly where you need to send these through to us.

You can gather this device / browser data on the client-side using JavaScript. Here's a handy example:

function gatherBrowserData() {
    var colorDepth = screen.colorDepth; 
    var javaEnabled = navigator.javaEnabled(); 
    var browserLanguage = navigator.language; 
    var screenHeight = screen.height; 
    var screenWidth = screen.width; 
    var userAgent = navigator.userAgent;
    var browserTime = new Date();
    var browserTimezoneZoneOffset = (browserTime.getTimezoneOffset() / 60); 
}

Authentication

Now that you have queried if your customer is enrolled in EMV® 3-D Secure and gathered their additional data, you are ready to perform the Authentication and Authorisation steps.

EMV® 3-D Secure requires more data (required fields) about the cardholder to be passed through to the issuing bank to allow the issuer to authenticate the transaction when compared to processing transactions without SCA.

We've marked out the standard required fields (look out for SCA) in our Authorisation guide, take a look here..

Your ad hoc and INIT requests will need a new tds object added to the request, just like this one:

"tds": {
    "action": "SCA",
    "source": "1",
    "type": "2",
    "preference": "0",
    "method_url_complete": "1",
    "server_trans_id": "d1eb55be-1095-4dc8-a65d-1d14a230ddac",
    "browser_data": {
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "color_depth": "TWENTY_FOUR_BITS",
        "ip": "127.0.0.1",
        "java_enabled": "true",
        "javascript_enabled": "true",
        "language": "en-US",
        "screen_height": "1080",
        "screen_width": "1920",
        "challenge_window_size": "WINDOWED_600X400",
        "timezone": "0",
        "user_agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
    },
    "merchant": {
        "contact_url": "https://yourdomain.com/contactus",
        "challenge_url": "https://yourdomain.com/challenge_url"
    }
}
Parameter Format Length Description
tds object
action int 3-12 For EMV 3-D Secure (v2) should be set to SCA when Initiating Authentication.
source int 1 The channel being used to initiate the transaction, the value should be set to 1 in your request.
type int 1 The type of transaction you are processing, value should be set to 2 in your request.
preference int 1 If you'd like the customer to be challenged:

0 = No Preference.
1 = Don't Challenge.
2 = Request Challenge.

The issuer may decide to ignore your preference.

For requests where card details are being stored for future use, this value must be set to: 2 = Request Challenge.
method_url_complete int 1 Please see here for more information on this field:

1 = Yes, it was completed.
2 = No we didn't get a response.
3 = We never got any method_data.
server_trans_id string 36 Please see here, you got it when you checked the version of 3-D Secure.
browser_data object
accept_header string 1-2048 HTTP accept headers as sent by the browser.
color_depth enum Browser color depth.

Acceptable values: ONE_BIT, TWO_BITS, FOUR_BITS, EIGHT_BITS, FIFTEEN_BITS, SIXTEEN_BITS, TWENTY_FOUR_BITS, THIRTY_TWO_BITS, FORTY_EIGHT_BITS.
ip string 7-39 IP address returned by the browser in either IPv4 or IPv6 format.
java_enabled boolean If the device can execute Java.
javascript_enabled boolean If the browser can execute JavaScript.
language string 1-8 Browser language (EN = English for example).
screen_height int 1-6 Total height of the users screen in pixels.
screen_width int 1-6 Total width of the users screen in pixels.
user_agent string 1-2048 Exact content of the HTTP user-agent header sent by the browser.
challenge_window_size enum The size of the challenge window you are going to display to the customer, the ACS will send it back formatted appropriately.

Acceptable values: WINDOWED_250X400,WINDOWED_390X400,WINDOWED_500X600,WINDOWED_600X400,FULL_SCREEN
timezone string 1-5 Time difference between UTC time and the user’s browser time, in minutes.
merchant object
contact_url url Link to the contact / customer care section of your website, just in case something goes wrong.
challenge_url url In the event of a Challenge Flow, where the ACS should POST back their response to.

Frictionless Flow

Using the information you have collected and passed to the issuer, they have authenticated the transaction without the need to Challenge the cardholder. Hooray!

In this scenario, we will send the transaction straight on to your acquiring partner(s) for authorisation. Within the response message we return to you, we will pass through some additional fields to let you know the outcome of the authentication as well as the standard authorisation response.

It will look something like this:

{
        "timestamp":"20190807063659",
        "response_code":"1",
        "response_message":"Transaction Success",
        "company_id":"133",
        "mid":"1045",
        "transaction_id":"215212",
        "transaction_type":"AUTH_ONLY",
        "merchant_order_id":"20190807063659",
        "amount":"0",
        "currency_code_iso3":"USD",
        "authorization_code": "123456",
        "acquirer_reference_number": "",
        "avsaddress": "M",
        "avszipcode": "M",
        "cvvresult": "M",
        "bank_response_code": "85",
        "tds":{
            "eci":"5",
            "status":"1",
            "reason": "17"
        },
        "bin": {
            "issuing_bank": "ACQUIRED.COM",
            "card_category": "DEBIT",
            "card_level": "STANDARD",
            "issuing_country": "United Kingdom",
            "issuing_country_iso2": "GB"
        },
        "response_hash":"835956a9fe56d65416....."
    }

Most of these response fields are covered in our Card API documentation but here are a few to note for EMV® 3-D Secure:

Parameter Format Length Description
response_code int 1-3 If the Authentication is successful, we'll return one of our standard authorisation response codes.

However, if it fails you'll see one of the following values:

540 SCA: Failed
541 SCA: Not Successful
542 SCA: Issuer Rejected
565 SCA: Required
eci int 1 Just like the existing version of 3-D Secure the ECI (e-Commerence Indicator) has been used to indicate the outcome of the authentication.

Possible values for Visa are: 5 (Success), 6 (Attempted), 7 (Failed).
Possible values for MasterCard are: 2 (Success), 1 (Attempted), 0 (Failed).
reason int 1-2 Provides more information on the outcome of the authentication. Possible values are:

01 = Authentication Failed
02 = Unknown Device
03 = Unsupported Device
04 = Exceed 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 ACS
15 = Low Confidence
16 = Medium Confidence
17 = High Confidence
18 = Very High Confidence
19 = Exceeds ACS Max Challenges
20 = Not Payment Transction Not Supported
21 = Threeri_Transaction_Not_Supported
22 = ACS_Technical_Issue
23 = Decoupled_Authentication_Required_By_ACS
24 = Decoupled_Max_Expiry_Time_Exceeded
25 = Insuficient_Time_To_Authenticate
26 = Authentication_Attempted_But_Not_Performed
27 = Scheme_Status_Reason##

Challenge Flow

The issuing bank has decided they require further information to authenticate the cardholder and has Challenged your request. This can be for a series of reasons but the decision lies solely with the issuing bank.

In this scenario, we will return a 503 response_code along with additional information you will need to complete in the next step. It will look something like this:

{
    "timestamp":"20170612200234",
    "response_code":"503",
    "response_message":"SCA: Challenge Required",
    "company_id":"133",
    "mid":"1045",
    "transaction_id":"215212",
    "transaction_type":"AUTH_ONLY",
    "merchant_order_id":"20170612200234",
    "amount":"15.92",
    "currency_code_iso3":"USD",
    "tds":{
        "source":"1",
        "type":"1",
        "message_version":"2.1.0"
        "challenge_mandated": “1”,
        "creq":"ewogICJ0aHJlZURTU2VydmVyVHJhbnNJRCIgOiAiNjBmNGJmZjItOGEyZi00M2Q0LThmMTUtMWJkZjAwMjM4MWRmIiwKICAiYWNzVHJhbnNJRCIgOiAiZTQwZjgzMTgtNjE2ZC00YmQxLWE4MjYtYTY5MzNjYTg0YjhjIiwKICAibWVzc2FnZUV4dGVuc2lvbiIgOiBbIHsKICAgICJjcml0aWNhbGl0eUluZGljYXRvciIgOiB0cnVlLAogICAgImRhdGEiIDogInNvbWUgc2FtcGxlIGRhdGEiLAogICAgImlkIiA6ICJleHQtMDAxIiwKICAgICJuYW1lIiA6ICJzYW1wbGUiCiAgfSBdLAogICJtZXNzYWdlVHlwZSIgOiAiQ1JlcSIsCiAgIm1lc3NhZ2VWZXJzaW9uIiA6ICIyLjEuMCIKfQ==",
        "url":"https://server.acsdomainname.com",
    } ,
    "response_hash":"835956a9fe56d65416....."
}

First, you will need to POST the creq value to the url value in an i-Frame / Lightbox. This will present the Challenge window to the customer (remember you set the size challenge_window_size back here). Once the customer has completed the challenge, the i-Frame will send a form POST and redirect the customer to the challenge_url you specified in the authentication request.

Once the cardholder has authenticated themselves, in the response message you will receive a cres value. All you have to do with this value is send it onto us to allow us to decode it and subsequently proceed to authorisation if the cardholder has successfully authenticated themselves. If the authentication has failed, we will let you know.

{
    "timestamp":"20190620101530",
    "company_id":113,
    "company_pass":"password",
    "request_hash":"f0a18260b08a0bfacb.....",
    "transaction": {
        "transaction_type":"AUTH_ONLY",
        "original_transaction_id":"215212"
    },
    "tds": {
        "action": "SCA_COMPLETE",
        "cres":"eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImFmNjVjMzY5LTU5YjktNGY4ZC1iMmY2LTdkN2Q1ZjVjNjlkNSIsImFjc1RyYW5zSUQiOiIxM2M3MDFhMy01YTg4LTRjNDUtODllOS1lZjY1ZTUwYThiZjkiLCJjaGFsbGVuZ2VDb21wbGV0aW9uSW5kIjoiWSIsIm1lc3NhZ2VUeXBlIjoiQ3JlcyIsIm1lc3NhZ2VWZXJzaW9uIjoiMi4xLjAiLCJ0cmFuc1N0YXR1cyI6IlkifQ,,"
    }
}
Pro Tip: You'll find out how to create the request_hash for this transaction_type here.

That's it, we'll send you a response (same as the example shown in the Frictionless Flow) to let you know the outcome of the authentication / authorisation just like we do here.