Credit/Debit Card Authentication

Shopper authentication is supported for all credit and debit cards, which is handled by either 3D Secure version 1 (3DSv1) or 3D Secure version 2 (3DSv2). Both protocols are designed by the card schemes (Mastercard, Visa, Amex) and supported by the payment system.
Note that 3D Secure version 1 is being phased out by the card schemes, therefore it will be no longer supported in the future. This does not apply for Bancontact as they do not support 3DSv2 at the moment.

The integration requirements between 3DSv1 and 3DSv2 are, unfortunately, significantly different. For 3DSv1 a redirect URL and parameters will be provided by the payment system, whereas for 3DSv2 multiple URLs may be returned each requiring their own handling. See also Start Payment.

Finally, the information presented on this page is only relevant when the payment menu of CM.com is not used.

The used (sample) scripts can be downloaded from the sandbox environment:

3DSv1

For 3Dsv1 authentication only a redirect has to be performed in the browser towards the issuing bank of the card. The payment system returns the URL and any additional parameters as part of the start payment response. The purpose of the URL element is set to REDIRECT and only one URL needs to be handled. The shopper returns to the webshop after the authentication result has been processed by the payment system.

Sample Script

Below is an example JavaScript that handles the 3DSv1 authentication request, after the initial payment request has been performed.

/**
 * Redirect the shopper for 3DSv1 authentication.
 * @param authenticationUrl The authentication URL.
 * @param postParameters The parameters to the post request.
 */
function redirectForThreeDsOneAuthentication(authenticationUrl, postParameters) {
    var form = document.createElement('form');
    document.body.appendChild(form);
    form.method = 'post';
    form.action = authenticationUrl;
    for (var name in postParameters) {
        var input = document.createElement('input');
        input.type = 'hidden';
        input.name = name;
        input.value = postParameters[name];
        form.appendChild(input);
    }
    form.submit();
}

3DSv2

For 3DS authentication one or two URLs are returned as part of the start payment response. The two possible URLs are:

  • The Issuer/ACS Method URL, which must be loaded in a hidden i-frame. The purpose of this URL will be set to HIDDEN_IFRAME.
  • The authentication URL, which must be used to start the authentication with. The purpose of the URL is set to 'IFRAME', but should not be loaded into an i-frame. The response (of the POST request) must be loaded into an i-frame.

Below is a diagram how the interaction looks like between the shopper's browser, the payment system, and the issuer, in case that the shopper must authenticate (challenge flow).

3DSv2 Authentication Flow with Challenge

A frictionless flow, when the shopper does not have to authenticate as followed:

3DSv2 Authentication Flow Frictionless

Strong Customer Authentication (SCA) Exemptions

It is possible to apply an SCA exemption for certain credit card payments. In these cases 3DSv1 or 3DSv2 is not used to authenticate the shopper, but the original payment is used to validate that the shopper was authenticated.

See also Start the Payment with referenced Order.

Request

Field Type M Description
force_authentication boolean O Boolean value to indicate if authentication must be forced. Default is false.
browser_info Block M Information about the browser.
+ ip_address String(1, 255) O The IP address of the shopper. If not supplied, then the payment system uses the IP of the request.
+ java_enabled boolean M Boolean value to indicate if Java is enabled in the browser. The call navigator.javaEnabled() can be used to determine the value.
+ java_script_enabled boolean M Boolean value to indicate if JavaScript/ECMAScript is enabled. This should always be true.
+ language String(1, 16) O The language as reported by the browser, following the format as specified in IETF BCP47. The call navigator.language can be used for the value. The default is en-EN.
+ color_depth Number(1, 48) O The color depth of the screen. Defaults to 24bits.
+ screen_height Number(1, 999999) M The screen height.
+ screen_width Number(1, 999999) M The screen width.
+ time_zone_offset Number(-9999, 9999) O The time offset in the browser compared to UTC in minutes. The call new Date().getTimezoneOffset() can be used to determine the value.
challenge_window_size Enum(2) M The size of the challenge window.
shopper_info Block O Additional information about the shopper.
+ shopper_name String(1, 50) M The name of the shopper as on the card.

The possible values for the field challenge_window_size are (width x height in pixels):

  • 01: 250 x 400
  • 02: 390 x 400
  • 03: 500 x 600
  • 04: 600 x 400
  • 05: 100% of the available screen (i-frame) size.

Response The response has the following fields, similar to the start payment response:

Field Type M Description
result Enum(64) M The authentication result.
urls Block[] C Required for result states CHALLENGE and SOFT_DECLINED.
url Block M The redirect details for the shopper.
+ purpose Enum(64) M The purpose of this URL.
+ method Enum(16) M The HTTP method to be used, either "GET" or "POST".
+ url Url M The URL the shopper must be redirected to.
+ order Number(1,10) M The order in which the URLs must be displayed or handled.
+ parameters Map O Map with parameter name/values pairs for the body of the redirect request.
error Block C The details of the error.
+ message_key Enum(64) M The message key for the error.
+ message String(1, 255) O The details of the error, if any additional information is available.

The URLs need to be processed in the order as specified by the field order.

The field result returns one of the following values:

Result Description
AUTHORIZED The payment is authorized.
CHALLENGE The shopper must be authenticated before authorization can occur. Handle the URLs as specified in the response.
SOFT_DECLINE The authorization was declined, but can be re-attempted after authentication of the shopper. Handle the URLs as specified in the response.
ERROR Some intermediate system error occurred.
CANCELED The shopper authentication failed, risk check failure, or authorization failed.

For the field purpose the following values are possible:

Purpose Description and required actions
REDIRECT Redirect the shopper to the specified URL using the given method and parameters.
HIDDEN_IFRAME The URL must be loaded in an i-frame that is hidden from the shopper. The size of the i-frame can be 0x0 or 1x1 pixels.
IFRAME The URL must be loaded in an i-frame that is visible to the shopper. The i-frame will be used by the issuer to display the authentication page.

In case of an 'HIDDEN_IFRAME' the data has to be sent via a basic HTML-form. A basic HTML-form is needed to ensure that the HTTP-POST request is a simple request according to Cross-Origin Resource Sharing (CORS). This avoids the browser from doing a pre-flight request (HTTP-OPTIONS request), as some issuer may or may not handle the preflight-request properly.

The same applies also in case the purpose is 'IFRAME'.

Finally, the field 'message_key' has one of the following possible values: Message Key Description
payment_authentication_canceled The authentication was canceled by the shopper. The payment is canceled.
payment_3dsv2_authentication_rejected The authentication was rejected by the issuing bank. The payment is canceled.
payment_processing_error There was a problem processing the authentication request or authorization request. The payment is canceled.

Note: Additional message keys can be added in the future.

Test Card Numbers

Below are several card numbers for each scheme to test or validate 3DSv2 integration.

Each number must be prefixed to get a complete card number:

  • for American Express the prefix is 34 followed by nine times a 1 (one);
  • for Visa the prefix is 41 followed by ten times a 1 (one);
  • for Master Card the prefix is 55 followed by ten times a 5 (five).
Scenario Scheme Last Four Digits Method URL Authentication Scenario
American Express 1111 Yes Standard test card number; authentication required.
51 1517 No Frictionless, no authentication required.
52 1525 No Card is soft-declined during first authorization attempt.
53 1533 No Card is always soft-declined.
55 1558 No Card is not enrolled for 3DSv2 and with reason code 13.
57 1574 No Card is rejected at authentication.
59 1590 No Card not supported by the issuer.
61 1616 N/A 3RI with decoupled successful authentication (5 seconds delay).
62 1624 N/A 3RI with decoupled failed authentication (5 seconds delay).
65 1657 N/A 3RI decoupled authentication not supported, authentication success.
66 1665 N/A 3RI decoupled authentication not supported, authentication failed.
wxyz Depends Any other 4 digits not mentioned; authentication required.
MasterCard 4444 Yes Standard test card number; authentication required.
51 4519 No Frictionless, no authentication required.
52 4527 No Card is soft-declined during first authorization attempt.
53 4535 No Card is always soft-declined.
54 4543 No Card is not enrolled for 3DSv2 and with reason code 82.
55 4550 No Card is not enrolled for 3DSv2 and with reason code 13.
57 4576 No Card is rejected at authentication.
59 4592 No Card not supported by the issuer.
61 4618 N/A 3RI with decoupled successful authentication (5 seconds delay).
62 4626 N/A 3RI with decoupled failed authentication (5 seconds delay).
65 4659 N/A 3RI decoupled authentication not supported, authentication success.
66 4667 N/A 3RI decoupled authentication not supported, authentication failed.
wxyz Depends Any other 4 digits not mentioned; authentication required.
Visa 1111 Yes Standard test card number; authentication required.
51 1517 No Frictionless, no authentication required.
52 1525 No Card is soft-declined during first authorization attempt.
53 1533 No Card is always soft-declined.
55 1558 No Card is not enrolled for 3DSv2 and with reason code 13.
57 1574 No Card is rejected at authentication.
59 1590 No Card not supported by the issuer.
61 1616 N/A 3RI with decoupled successful authentication (5 seconds delay).
62 1624 N/A 3RI with decoupled failed authentication (5 seconds delay).
65 1657 N/A 3RI decoupled authentication not supported, authentication success.
66 1665 N/A 3RI decoupled authentication not supported, authentication failed.
wxyz Depends Any other 4 digits not mentioned; authentication required.

The column 'Scenario' can be used for in communication with support if there are any (integration) questions. The column 'Method URL' indicates if an ACS/3DS Method URL will be part of the start payment response.

The following OTP values can be used, when presented with an authentication request form:

OTP value 3DS Status Result
1234 Y Authentication success
1111 N Authentication failed
2222 R Authentication rejected
3333 U Authentication could not be performed
4444 A Authentication attempted (not authenticated, but attempt proof provided)

The values 1234 and 4444 are success scenarios, while the other values lead to a failed payment attempt.

Sample Script

Below is an example JavaScript that handles the 3DSv2 authentication request, after the initial payment request has been performed. This includes the handling of a payment that is directly authorized as well as for which a challenge is requested.

/**
 * <em>SAMPLE SCRIPT for performing 3DS v2 authentication</em>
 * <p>
 * Executes the 3DS v2 ACS method URL of the browser and authentication instructions for the shopper.
 *
 * This function performs two things:
 * <ol>
 *     <li>It loads the ACS method URL, and after loading</li>
 *     <li>Executes the authentication call to CM Payments to authenticate the shopper.</li>
 * </ol>
 *
 * The ACS Method URL is performed in an i-frame, hidden from the shopper, by posting the <code>acsMethodData</code>
 * to the <code>acsMethodURl</code>. The result is processed by the ACS and a notification of that is
 * directly received by CM payments from the ACS.
 * <br/>
 * Shopper authentication is performed by posting the <code>authenticationData</code> to the authentication URL
 * (<code>authenticationUrl</code>). For further details see handleThreeDsAuthentication().
 * <p>
 * For additional information see EMVCo 3DS spec 2.2.0 chapters '3.3 - Browser-based Requirements' and chapter
 * '5.8 - Browser-based Message Handling'.
 *
 * @param acsMethodUrl The ACS method URL.
 * @param acsMethodData The ACS method data.
 *                      <br/>The data should be posted as is using the parameter name 'threeDSMethodData'.
 * @param authenticationUrl The authentication URL.
 * @param authenticationData The authentication data.
 *                           <br/>The authentication data should be amended with additional information about the
 *                                browser and shopper.
 * @param forceAuthentication <code>true</code>, if the authentication of the shopper must be forced.
 *                            Otherwise, <code>false</code>, it is left to payment system and/or issuer.
 */
function performThreeDsAuthentication(acsMethodUrl, acsMethodData,
                                      authenticationUrl, authenticationData,
                                      forceAuthentication) {
    if (!authenticationUrl || !authenticationData) {
        throw Error('Not all ACS Authentication parameters provided');
    }

    if (!acsMethodUrl) {
        // No ACS method URL, so can skip that part. Directly authenticate the shopper.
        handleThreeDsAuthentication(authenticationUrl, authenticationData, forceAuthentication);
    } else {
        if (!acsMethodData) {
            throw Error('Not all ACS 3DS method parameters provided');
        }
        window.nca3DSWebSDK.createIframeAndInit3DSMethod(acsMethodUrl, acsMethodData,
                                                         'threeDSMethodIFrame', document.body,
                                                         new function () {
                                                             handleThreeDsAuthentication(authenticationUrl,
                                                                                         authenticationData,
                                                                                         forceAuthentication)
                                                         });
    }
}

/**
 * Perform the authentication request at CM Payments. The request is then forwarded to the ACS for evaluation.
 *
 * <p>
 * The parameter <code>authenticationData</code> is used to provide additional authentication and has the
 * following structure:
 * <pre>
 * {
 *    "browser_info" : { ... },
 *    "shopper_info" : { ... }
 *  }
 * </pre>
 * The additional data is used to provide additional information about the shopper that was not provided in the original
 * create-order API request or if more precise information is available. The data is optional, but may allow the shopper
 * to experience the frictionless flow, in which case the shopper does not have to authenticate.
 *
 * @param authenticationUrl The authentication URL
 * @param authenticationData  The additional authentication data
 * @param forceAuthentication <code>true</code>, if the authentication of the shopper must be forced.
 *                            Otherwise, <code>false</code>, it is left to payment system and/or issuer.
 */
function handleThreeDsAuthentication(authenticationUrl, authenticationData, forceAuthentication) {

    let xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState === 4) {
            if (this.status === 200) {

                /**
                 * The response structure is similar to the REST API start response; the error component is added to
                 * present a more detailed error message to the shopper. For sake of brevity only the used fields are
                 * mentioned here.
                 *
                 * <pre>
                 *     "result" : <"CHALLENGE" | "AUTHORIZED" | "SOFT_DECLINE" | "ERROR" | "CANCELED"> (mandatory)
                 *     "url"    : [ {
                 *                    "url" : "some URL", (mandatory)
                 *                    "order" : 1, (mandatory)
                 *                    "purpose" : <"REDIRECT" | "IFRAME" | "HIDDEN_IFRAME">, (mandatory)
                 *                    "parameters" : [{key, value}]
                 *                  },
                 *                  ...
                 *               ],
                 *     "error" : {
                 *                 "message" : "some message", (conditional, if result === ERROR or result === CANCELED)
                 *                 "message_key : "some key" (conditional, if result === ERROR or result === CANCELED)
                 *     }
                 * </pre>
                 */
                let response = JSON.parse(this.responseText);
                if (response.result === 'CHALLENGE') {
                    let redirectUrlData = findUrlWithPurpose(response.urls, 'REDIRECT');
                    if (redirectUrlData) {
                        redirectForThreeDsOneAuthentication(redirectUrlData.url, redirectUrlData.parameters);
                    } else {

                        /* We have some knowledge of the returned data here. All the URLs require POST and the parameter
                         * names are known. The parameter name is 'creq', which is the same as what is required in the form
                         * that needs to be posted to the ACS (see also EMVco 3DSv2 specification; table A.3 - CReq/CRes POST data).
                         */
                        let challengeUrlData = findUrlWithPurpose(response.urls, 'IFRAME');

                        // The authentication frame is created and maintained by the OPC menu. The i-frame itself must have
                        // a name/identifier.
                        let authenticationFrame = window.showAuthenticationFrame();
                        window.nca3DSWebSDK.init3DSChallengeRequest(challengeUrlData.url,
                            challengeUrlData.parameters['creq'],
                            authenticationFrame);
                    }
                } else if (response.result === 'SOFT_DECLINE') {
                        /* The payment authorization was soft-decline by the acquirer/issuer; the payment can be completed
                         * if the shopper is authenticated. This requires a restart of the authentication process, so the
                         * function 'performThreeDsAuthentication' is called again.
                         *
                         * We have some knowledge of the returned data here. All the URLs require POST and the parameter
                         * names are known. The ACS method is passed along under 'threeDSMethodData' and must be posted
                         * using the same (parameter) name (see also EMVco 3DSv2 specification; table A.2 - 3DS Method Data).
                         */

                        let acsMethodUrlData = findUrlWithPurpose(response.urls, 'HIDDEN_IFRAME');
                        let methodUrl = acsMethodUrlData === null ? null : acsMethodUrlData.url;
                        // The parameter is named 'threeDSMethodData'.
                        let methodData = acsMethodUrlData === null ? null : acsMethodUrlData.parameters['threeDSMethodData'];

                        // There is always an authentication URL and no parameter data
                        let authenticationUrlData = findUrlWithPurpose(response.urls, 'IFRAME');
                        let authUrl = authenticationUrlData.url;
                        performThreeDsAuthentication(methodUrl, methodData, authUrl, '{}', true);
                } else if (response.result === 'AUTHORIZED') {
                    // Payment is authorized, need to wait for the order status to be updated.
                    window.pollOrderStatus();
                } else {
                    // No need to poll the status, show the error message
                    window.showPaymentCanceled(response.error.message_key, response.error.message);
                }
            } else {
                // Show the payment canceled dialog
                window.showPaymentCanceled('payment_processing_error', this.statusText);
            }
        }
    };

    xhttp.open('POST', authenticationUrl, true);
    xhttp.setRequestHeader('Content-Type', 'application/json');
    xhttp.setRequestHeader('Accept', 'application/json');

    /* Add any additional browser information for the authentication request. The user-agent and browser-accept header
     * are retrieved from the request itself that is retrieved by the Payment system; so there is no need to specify
     * those.
     *
     * If a soft-decline is being handled, then the field 'force_authentication' is required. This field is passed along
     * as part of the initial authentication/authorization result as well. In this sample script, that particular
     * information is ignored and the value is directly set based on the passed-in parameters.
     */
    let data = JSON.parse(authenticationData);
    data.force_authentication = forceAuthentication;

    data.browser_info = {};
    data.browser_info.java_enabled = navigator.javaEnabled();
    /*always enabled*/
    data.browser_info.java_script_enabled = true;
    data.browser_info.language = navigator.language;
    data.browser_info.color_depth = screen.colorDepth;
    data.browser_info.screen_height = screen.height;
    data.browser_info.screen_width = screen.width;
    data.browser_info.time_zone_offset = new Date().getTimezoneOffset();
    data.browser_info.challenge_window_size = '05';

    xhttp.send(JSON.stringify(data));
}

/**
 * Helper logic to search for a particular URL with a specific purpose.
 *
 * @param urls The urls for 3DSv1 or 3DSv2 authentication.
 * @param purpose The purpose of URL.Can be 'REDIRECT', 'HIDDEN_IFRAME' or 'IFRAME'.
 *
 * @return the URL with given purpose.
 */
function findUrlWithPurpose(urls, purpose) {
    for (let url of urls) {
        if (url.purpose === purpose) {
            return url;
        }
    }
    return null;
}