Skip to content

3D Secure

The full implementation of the 3DS authentication process is out scope for this documentation, but here you can find information on how to perform an authenticated authorization and some key concepts from the EMV 3DS Protocol are also explained.

Please note that the Rapyd Authorization host is not performing any 3DS actions, it is expected that the authentication process has already been completed before sending the transaction to the authorization host.

Concepts

AReq

- the authentication request in the EMV 3DS Protocol

ACS

- the access control server, controlled by the card issuer and 
  manages the authentication rules

Challenge flow

- required flow when storing a card on file
- a challenge is requested with the appropriate values in the 3DS Requestor 
  Challenge Indicator and 3DS Requestor Authentication Indicator 
  data elements in the AReq message

Frictionless flow

- when the authentication process is performed without cardholder interaction
- the ACS decides when this flow is appropriate but it can be requested using 
  the 3DS Requestor Challenge Indicator data element in the AReq message

3RI

- requestor initiated authentication
- used to perform authentication on various MIT transaction scenarios

3DS specific parameters

Request

CAVD is a value returned from the 3DS Server.
In the EMV 3DS Protocol the field name is authenticationValue. It is also known as CAVV (Cardholder Authentication Verification Value)

dsTransID is the id of the authentication, provided by the 3DS Server.
In the EMV 3DS Protocol the field name is dsTransID

ThreeDSMessageVersion is the message version used when performing the authentication, provided by the 3DS Server. In the EMV 3DS Protocol the field name is messageVersion

CardVD is the CVV/CVC2/CID value on the card. Not required but recommended when possible

Response

Eci is returned in the response with the accepted value from the issuer. See here for possible values
CAVR is the cardholder authentication verification result. See here for possible values
CardVR is the card authentication verification result. See here for possible values

Ecommerce transactions

In addition to all mandatory parameters and the above mentioned 3DS request parameters use the conditional parameters appropriate for your merchant setup and circumstance.

To determine the appropriate Transaction Type the merchant/processor should use the Electronic Commerce Indicator (ECI) value received in the response message from the 3DS Server.

Amex

Card scheme ECI TransType
Amex 05 15, 12(if card on file)
Amex 06 16, 12(if card on file)
Amex 07 17, 12(if card on file)

Visa

Card scheme ECI TransType
Visa 05 15, 12(if card on file)
Visa 06 16, 12(if card on file)
Visa 07 17, 12(if card on file)

MasterCard

Card scheme ECI TransType
MasterCard 07 1B, 12(if card on file)
MasterCard 06 1B, 12(if card on file)
MasterCard 02 1B, 15, 12(if card on file)
MasterCard 01 16, 12(if card on file)
MasterCard 00 17, 12(if card on file)

Stored credential transactions

Only for subsequent transactions. For first transactions, when the initial storing of the card data is performed, see information about ecommerce transactions and how to capture card data

Follow the instruction for stored credentials and add the 3DS request parameters

Downgrade

When sending a 3-D Secure authorization with transaction type 15 (3-D Secure) or 16 (3-D Secure Attempt), the card schemes can in some cases downgrade the transaction which results in the downgraded transaction type to be returned in the TransType parameter in the 0110 response message. The issuer accepted eci value is also returned in the response.

The downgraded TransType should be sent in for clearing in the .otf file.

All other transaction types are echoed back unchanged in the TransType parameter in the 0110 response message.

Notice

Transaction type 15 can be downgraded to 16 or 17. Transaction type 16 can be downgraded to transaction type 17.

Notice

A 3D Secure transaction is downgraded if CAVD is invalid.

See Transaction types

Examples

Fully authenticated CIT using Stored Credentials (Visa)

// code is compatible with .net8 console app
using System.Web;
using Microsoft.Extensions.DependencyInjection;

var service = new ServiceCollection();
service.AddHttpClient();

var client = service.BuildServiceProvider()
    .GetService<IHttpClientFactory>()!
    .CreateClient();

var parameters = new Dictionary<string, string>
{
    { "MsgType", "0100" },
    { "MsgSenderID", "[insert your username]" },
    { "MsgSenderAP", "[insert your password]" },
    { "MsgID", "123456" },
    { "MerchantXID", "2995652ABCDEFGH" },
    { "MerchantType", "5999" },
    { "TerminalID", "18101001" },
    { "CardType", "V" },
    { "CardNumber", "4761739001010010" },
    { "CardExpDate", "2512" },
    { "TransType", "12" },
    { "TransAmount", "199.99" },
    { "TransCurrency", "978" },
    { "TransTime", "230101" },
    { "TransDate", "0310" },
    { "MerchantName", "CIP*Billy shoes" },
    { "MerchantCity", "London" },
    // 3DS specific parameters
    { "CAVD", "ACIzRFVmd4iZAKq7zN3u/wAAAAA=" },
    { "dsTransID", "4E192AD7-D2EF-4AD6-B2E1-460FDA4898CB" },
    // Stored credential specific parameters
    { "StoredCredential", "1" },
    { "Initiator", "C" },
    { "InitiationReason", "CRE" }
};

var request = new HttpRequestMessage(HttpMethod.Post, "https://authorization.acquiring.uat.valitor.com/process")
{
    Content = new FormUrlEncodedContent(parameters)
};

HttpResponseMessage response = await client.SendAsync(request);

if (response.IsSuccessStatusCode)
{
    var content = await response.Content.ReadAsStringAsync();
    var responseParameters = System.Web.HttpUtility.ParseQueryString(content);
    // Process responseParameters here
}
else
{
    // Handle error
}

Fully authenticated transaction (Visa)

// code is compatible with .net8 console app
using System.Web;
using Microsoft.Extensions.DependencyInjection;

var service = new ServiceCollection();
service.AddHttpClient();

var client = service.BuildServiceProvider()
    .GetService<IHttpClientFactory>()!
    .CreateClient();

var parameters = new Dictionary<string, string>
{
    { "MsgType", "0100" },
    { "MsgSenderID", "[insert your username]" },
    { "MsgSenderAP", "[insert your password]" },
    { "MsgID", "123456" },
    { "MerchantXID", "2995652ABCDEFGH" },
    { "MerchantType", "5999" },
    { "TerminalID", "18101001" },
    { "CardType", "V" },
    { "CardNumber", "4761739001010010" },
    { "CardExpDate", "2512" },
    { "CardVD", "123" },
    { "TransType", "15" },
    { "TransAmount", "199.99" },
    { "TransCurrency", "978" },
    { "TransTime", "230101" },
    { "TransDate", "0310" },
    { "MerchantName", "CIP*Billy shoes" },
    { "MerchantCity", "London" },
    // 3DS specific parameters
    { "CAVD", "ACIzRFVmd4iZAKq7zN3u/wAAAAA=" },
    { "dsTransID", "4E192AD7-D2EF-4AD6-B2E1-460FDA4898CB" }
};

var request = new HttpRequestMessage(HttpMethod.Post, "https://authorization.acquiring.uat.valitor.com/process")
{
    Content = new FormUrlEncodedContent(parameters)
};

HttpResponseMessage response = await client.SendAsync(request);

if (response.IsSuccessStatusCode)
{
    var content = await response.Content.ReadAsStringAsync();
    var responseParameters = System.Web.HttpUtility.ParseQueryString(content);
    // Process responseParameters here
}
else
{
    // Handle error
}

Attempt (Visa)

// code is compatible with .net8 console app
using System.Web;
using Microsoft.Extensions.DependencyInjection;

var service = new ServiceCollection();
service.AddHttpClient();

var client = service.BuildServiceProvider()
    .GetService<IHttpClientFactory>()!
    .CreateClient();

var parameters = new Dictionary<string, string>
{
    { "MsgType", "0100" },
    { "MsgSenderID", "[insert your username]" },
    { "MsgSenderAP", "[insert your password]" },
    { "MsgID", "123456" },
    { "MerchantXID", "2995652ABCDEFGH" },
    { "MerchantType", "5999" },
    { "TerminalID", "18101001" },
    { "CardType", "V" },
    { "CardNumber", "4761739001010010" },
    { "CardExpDate", "2512" },
    { "CardVD", "123" },
    { "TransType", "16" },
    { "TransAmount", "199.99" },
    { "TransCurrency", "978" },
    { "TransTime", "230101" },
    { "TransDate", "0310" },
    { "MerchantName", "CIP*Billy shoes" },
    { "MerchantCity", "London" },
    // 3DS specific parameters
    { "CAVD", "ByIzRFVmd4iZAKq7zN3u/wAAAAA=" },
    { "dsTransID", "4E192AD7-D2EF-4AD6-B2E1-460FDA4898CB" }
};

var request = new HttpRequestMessage(HttpMethod.Post, "https://authorization.acquiring.uat.valitor.com/process")
{
    Content = new FormUrlEncodedContent(parameters)
};

HttpResponseMessage response = await client.SendAsync(request);

if (response.IsSuccessStatusCode)
{
    var content = await response.Content.ReadAsStringAsync();
    var responseParameters = System.Web.HttpUtility.ParseQueryString(content);
    // Process responseParameters here
}
else
{
    // Handle error
}