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.
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:
- Knowledge: Something only the customer knows e.g a password.
- Possession: Something only the customer possess e.g. phone number, email address).
- 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.
- 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.
- Gathering Device Data: If the cardholder is enrolled, you will be required to gather additional device data.
- 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).
- 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.
Check 3-D Secure Version
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"
}
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. |
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.
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,,"
}
}
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.