About 3D Secure 2.0
3-D Secure 2.0 is an EMVCo payment authentication protocol designed to reduce card not present fraud by making a risk assessment based on transaction and device data, while also supporting further risk minimization measures, such as a challenge to the cardholder. In some cases, a liability shift takes effect for certain card-not-present fraud-related chargebacks enabling the merchant to provide goods and services with confidence.
The Moneris Gateway can enable transactions using the 3-D Secure protocol via Moneris 3DS Server and Access Control Server (ACS).
Moneris Gateway supports the following 3-D Secure implementations:
- Visa Secure
- Mastercard Identity Check
- American Express SafeKey (please not American Express only supports authentication requests for merchants who have an AMEX OFI merchant account)
3D Secure Implementations
Visa Secure, Mastercard Identity Check and American Express SafeKey are programs based on the 3-D Secure Protocol to improve the security of online transactions.
These programs involve authentication of the cardholder during an online e-commerce transaction.
Authentication is based on the issuer’s selected method of authentication.
The following are examples of authentication methods:
- Risk-based authentication
- Biometric authentication
- One-Time Passwords ie. SMS
Some benefits of these programs are reduced risk of fraudulent transactions and protection against chargebacks for certain fraudulent transactions.
Out of Scope/Not Supported
Version Compatibility
All development to the Moneris API must be able to support the addition of new fields in the response and new error conditions in the response. Otherwise any changes that affect backwards compatibility will be communicated by Moneris Solutions with an appropriate period of notice. When developing to the solution it is recommended to validate for success state of the request and then handle errors states separately and ensure there is a final catch for any unexpected/undocumented errors that are returned.
Upgrading from 3D Secure 1.0 to 3D Secure 2.0
The 3DS 2.0 API is different from the 3DS 1.0 API therefore developers will have to complete all steps listed below:
- Activating 3D Secure Functionality
- Transaction flow for 3DS 2.0
- Implementing Card Lookup Request
- Implementing Authentication Request
- Handling the Challenge Flow
- Performing the Authorization
Activating 3D Secure Functionality
To activate Visa Secure, Mastercard Identity Check and/or American Express SafeKey transaction functionality, call Moneris Sales Support at 1-855-465-4980 to have Moneris enroll you in the program(s) and enable the functionality on your account.
Transaction flow for 3DS 2.0

The Java 3DS 2.0 API is called when the customer wishes to checkout. An optional card lookup request can be performed to initiate cardholder browser fingerprinting. Once the fingerprint is complete, or as a first step if not performing a fingerprint, the transactional information can then be transmitted to the 3DS 2.0 service so a risk assessment may be initiated.
The flow can then proceed in one of two ways. The two different flows are referred to as “frictionless” and “challenge”.
The “frictionless” flow is transparent to a cardholder. If the issuing financial institution has enough information to make a risk assessment and assume liability, this will manifest itself as with an authentication attempt or success with an accompanying cavv value. No cardholder challenge is presented.
In the “challenge” flow the issuing financial institution may wish to take a further step and issue a challenge to the cardholder. In this case the cardholder’s browser gets re-directed to the issuer’s 3DS platform for authentication. Once this challenge is complete, the cardholder browser is again re-directed back to the merchant’s site. The merchant’s server then issues a server-to-server request in order to obtain the CAVV value from Moneris.
Implementing Card Look Up Request
The CardLookup request verifies the applicability of 3DS 2.0 on the card and returns the 3DS Method URL. That is used for device fingerprinting. This request is optional, it may increase the chance of a frictionless flow.
The threeDSMethodURL
& threeDSMethodData
are returned to the merchant server on the CardLookup response. The threeDSMethodData
can be transmitted to the threeDSMethodURL
via a browser post in order to supplement the authentication request with device data pertaining to the cardholder’s browser.
The threeDSMethodData
must be sent via HTTP POST to the threeDSMethodURL
in a hidden iFrame.
In your implementation, use the following URLs as Host, depending on the development stage:
Testing: esqa.moneris.com
Production: www3.moneris.com
package Canada;
import JavaAPI.*;
public class TestCanadaMpiCardLookup
{
public static void main(String[] args)
{
String store_id = "moneris";
String api_token = "hurgle";
java.util.Date createDate = new java.util.Date();
String order_id = "Test"+createDate.getTime();
String pan = "4740611374762707";
String processing_country_code = "CA";
MpiCardLookup mpiCardLookup = new MpiCardLookup();
mpiCardLookup.setOrderId(order_id);
mpiCardLookup.setPan(pan);
mpiCardLookup.setNotificationUrl("https://yournotificationurl.com"); //(Website URL that will receive 3DS Method Completion response from ACS)
//************************OPTIONAL VARIABLES***************************
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setProcCountryCode(processing_country_code);
mpgReq.setTestMode(true); //false or comment out this line for production transactions
mpgReq.setStoreId(store_id);
mpgReq.setApiToken(api_token);
mpgReq.setTransaction(mpiCardLookup);
mpgReq.send();
/********************** REQUEST ************************/
try
{
Receipt receipt = mpgReq.getReceipt();
System.out.println("ResponseCode = " + receipt.getResponseCode());
System.out.println("ReceiptId = " + receipt.getReceiptId());
System.out.println("Message = " + receipt.getMessage());
System.out.println("MessageType = " + receipt.getMpiMessageType());
System.out.println("ThreeDSMethodURL = " + receipt.getMpiThreeDSMethodURL());
System.out.println("ThreeDSMethodData = " + receipt.getMpiThreeDSMethodData());
System.out.println("ThreeDSServerTransId = " + receipt.getMpiThreeDSServerTransId());
}
catch (Exception e)
{
e.printStackTrace();
}
}
} // end TestResMpiTxn
CardLookup Request
MpiCardLookup transaction object definition
MpiCardLookup mpiCardLookup = new MpiCardLookup();
HttpsPostRequest object for MpiCardLookup transaction
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setTransaction(mpiCardLookup);
Core connection object fields (all API transactions)
Request fields for CardLookup request – Required
Note: Either a pan or a data_key must be passed in the request
CardLook up Receipt Request
Receipt object definition
Receipt receipt = mpgReq.getReceipt();
Implementing MPI 3DS Authentication Request
The MPI 3DS authentication request is used to start the validation process of the card. The result of this request determines whether 3DS2.0 is supported by the card and what type of authentication is required. It is recommended that you send as many variables as possible in the 3DS Authentication Request to increase the chance of a frictionless authentication.
In your implementation, use the following URLs as Host, depending on the development stage:
Testing: esqa.moneris.com
Production: www3.moneris.com
package Canada;
import JavaAPI.*;
public class TestCanadaMpiThreeDSAuthentication
{
public static void main(String[] args)
{
String store_id = "moneris";
String api_token = "hurgle";
String processing_country_code = "CA";
MpiThreeDSAuthentication mpiThreeDSAuthentication = new MpiThreeDSAuthentication();
mpiThreeDSAuthentication.setOrderId("Test15978735193"); //must be the same one that was used in MpiCardLookup call
mpiThreeDSAuthentication.setCardholderName("Moneris Test");
mpiThreeDSAuthentication.setPan("4740611374762707");
mpiThreeDSAuthentication.setExpdate("2310");
mpiThreeDSAuthentication.setAmount("1.00");
mpiThreeDSAuthentication.setThreeDSCompletionInd("Y"); //(Y|N|U) indicates whether 3ds method MpiCardLookup was successfully completed
mpiThreeDSAuthentication.setRequestType("01"); //(01=payment|02=recur)
mpiThreeDSAuthentication.setPurchaseDate("20200819035249"); //(YYYYMMDDHHMMSS)
mpiThreeDSAuthentication.setNotificationURL("https://yournotificationurl.com"); //(Website where response from RRes or CRes after challenge will go)
mpiThreeDSAuthentication.setChallengeWindowSize("03"); //(01 = 250 x 400, 02 = 390 x 400, 03 = 500 x 600, 04 = 600 x 400, 05 = Full screen)
mpiThreeDSAuthentication.setBrowserUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36\\");
mpiThreeDSAuthentication.setBrowserJavaEnabled("true"); //(true|false)
mpiThreeDSAuthentication.setBrowserScreenHeight("1000"); //(pixel height of cardholder screen)
mpiThreeDSAuthentication.setBrowserScreenWidth("1920"); //(pixel width of cardholder screen)
mpiThreeDSAuthentication.setBrowserLanguage("en-GB"); //(defined by IETF BCP47)
//Optional Methods
mpiThreeDSAuthentication.setBillAddress1("3300 Bloor St W");
mpiThreeDSAuthentication.setBillProvince("ON");
mpiThreeDSAuthentication.setBillCity("Toronto");
mpiThreeDSAuthentication.setBillPostalCode("M8X 2X2");
mpiThreeDSAuthentication.setBillCountry("124");
mpiThreeDSAuthentication.setShipAddress1("3300 Bloor St W");
mpiThreeDSAuthentication.setShipProvince("ON");
mpiThreeDSAuthentication.setShipCity("Toronto");
mpiThreeDSAuthentication.setShipPostalCode("M8X 2X2");
mpiThreeDSAuthentication.setShipCountry("124");
mpiThreeDSAuthentication.setEmail("test@email.com");
mpiThreeDSAuthentication.setRequestChallenge("Y"); //(Y|N Requesting challenge regardless of outcome)
//************************OPTIONAL VARIABLES***************************
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setProcCountryCode(processing_country_code);
mpgReq.setTestMode(true); //false or comment out this line for production transactions
mpgReq.setStoreId(store_id);
mpgReq.setApiToken(api_token);
mpgReq.setTransaction(mpiThreeDSAuthentication);
mpgReq.send();
/********************** REQUEST ************************/
try
{
Receipt receipt = mpgReq.getReceipt();
System.out.println("ResponseCode = " + receipt.getResponseCode());
System.out.println("ReceiptId = " + receipt.getReceiptId());
System.out.println("Message = " + receipt.getMessage());
System.out.println("MessageType = " + receipt.getMpiMessageType());
System.out.println("TransStatus = " + receipt.getMpiTransStatus());
System.out.println("ChallengeURL = " + receipt.getMpiChallengeURL());
System.out.println("ChallengeData = " + receipt.getMpiChallengeData());
System.out.println("ThreeDSServerTransId = " + receipt.getMpiThreeDSServerTransId());
}
catch (Exception e)
{
e.printStackTrace();
}
}
} // end TestResMpiTxn
MpiThreeDSAuthentication Request
MpiThreeDSAuthentication transaction object definition
MpiThreeDSAuthentication mpiThreeDSAuthentication = new MpiThreeDSAuthentication();
HttpsPostRequest object for MpiThreeDSAuthentication transaction
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setTransaction(mpiThreeDSAuthentication);
Core connection object fields (all API transactions)
Request fields for threeDSAuthentication request – Required
Note: Either a pan or a data_key must be passed in the request
Request fields for threeDSAuthentication request – Optional
MpiThreeDSAuthentication Receipt Request
The result of the threeDSAuthentication request can be pulled from the TransStatus field. The results are defined in the TransStatus table in the Appendix.
A “Y” or an “A” transStatus means you can proceed immediately to the financial with the cavv value provided. This is a frictionless transaction flow.
A value of “C” indicates that the cardholder must be presented a challenge. In order to present the challenge you must POST a
Handling the Challenge Flow
If you get a TransStatus = “C” in your threeDSAuthentication Response, then a form must be built and POSTed to the URL provided.
The form can be dynamically generated and added to the DOM and submitted or created and submitted in a manner that suits your environment. This can be built as a full page redirect or presented as an inline iframe or as a lightbox.
If you wish for this to be loaded inside a defined space it must conform to the size specified in the challengeWindowSize from the request. The “action” is retrieved from the ChallengeURL and the “creq” field is retrieved from the ChallengeData.
Below is a sample of a basic static form to help visualize the data and fields that need to be submitted.
<form method="POST" action="https://3dsurl.example.com/do3DS">
<input name="creq" value="thisissamplechallengedata1234567890">
</form>
Cavv Lookup Request (Challenge flow only)
In the challenge flow, the 3DS server will POST a “cres” value back to the notificationURL provided in the threeDSAuthentication request once the cardholder has completed the challenge. The “cres” is then posted to the Moneris 3DS server in the CavvLookup request, the response to this request will include the result of the challenge, which will include the eci and the cavv if the challenge was successful.
package Canada;
import JavaAPI.*;
public class TestCanadaMpiCavvLookup
{
public static void main(String[] args)
{
String store_id = "moneris";
String api_token = "hurgle";
String processing_country_code = "CA";
//BASE64 Encoded CRes value returned from response at completion of challenge flow.
String cres = "eyJhY3NUcmFuc0lEIjoiNzQ0ZDI2NjUtNjU2Yy00ZGNiLTg3MWUtYTBkYmMwODA0OTYzIiwibWVzc2FnZVR5cGUiOiJDUmVzIiwiY2hhbGxlbmdlQ29tcGxldGlvbkluZCI6IlkiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidHJhbnNTdGF0dXMiOiJZIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiJlMTFkNDk4NS04ZDI1LTQwZWQtOTlkNi1jMzgwM2ZlNWU2OGYifQ==";
MpiCavvLookup mpiCavvLookup = new MpiCavvLookup();
mpiCavvLookup.setCRes(cres);
//************************OPTIONAL VARIABLES***************************
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setProcCountryCode(processing_country_code);
mpgReq.setTestMode(true); //false or comment out this line for production transactions
mpgReq.setStoreId(store_id);
mpgReq.setApiToken(api_token);
mpgReq.setTransaction(mpiCavvLookup);
mpgReq.send();
/********************** REQUEST ************************/
try
{
Receipt receipt = mpgReq.getReceipt();
System.out.println("ResponseCode = " + receipt.getResponseCode());
System.out.println("ReceiptId = " + receipt.getReceiptId());
System.out.println("Message = " + receipt.getMessage());
System.out.println("ThreeDSServerTransId = " + receipt.getMpiThreeDSServerTransId());
System.out.println("TransStatus = " + receipt.getMpiTransStatus());
System.out.println("ChallengeCompletionIndicator = " + receipt.getMpiChallengeCompletionIndicator());
System.out.println("Cavv = " + receipt.getMpiCavv());
System.out.println("ECI = " + receipt.getMpiEci());
}
catch (Exception e)
{
e.printStackTrace();
}
}
} // end TestResMpiTxn
Cavv Lookup Request transaction object definition
MpiCavvLookup mpiCavvLookup = new MpiCavvLookup();
HttpsPostRequest object for MpiCavvLookup transaction
HttpsPostRequest mpgReq = new HttpsPostRequest();
mpgReq.setTransaction(mpiCavvLookup);
Core connection object fields (all API transactions)
Request fields for Cavv Lookup request – Required
Cavv Lookup Receipt Request
Receipt object definition
Receipt receipt = mpgReq.getReceipt();
Performing the authorization
Once the authentication is complete and a cavv and eci value are retrieved these values can be sent to Moneris using the transactional cavv_purchase or cavv_preauth as defined in the Moneris Gateway transaction API.
Important note: Please include the CAVV, 3DS Version and 3DS Server Transaction ID in all 3DS authorization requests to ensure that you retain chargeback liability rights for the transaction.
Testing your 3D Secure 2.0 integration
In the testing stage of development:
- Use the testing URL as Host for your requests: esqa.moneris.com
- In all CardLookUp requests, make sure that you are using the testing version of your credentials for store ID and API token
- In all threeDSAuthentication requests, make sure that you are using the testing version of your credentials for store ID and API token
- In all CavvLookup requests, make sure that you are using the testing version of your credentials for store ID and API token
Note: 3DS test cases and card numbers can be found here
Moving to production with 3D Secure 2.0
Once you have finished testing your 3D Secure 2.0 integration, do the following to move the integration into production:
- Use the production URL as Host for your requests: www3.moneris.com
- In all CardLookUp requests, make sure that you are using the production version of your credentials for store ID and API token
- In all threeDSAuthentication requests, make sure that you are using the production version of your credentials for store ID and API token
- In all CavvLookup requests, make sure that you are using the production version of your credentials for store ID and API token
3-D Secure 2.0 TransStatus Codes