This document explains how to integrate with the Cardknox 3D Secure 2 (3DS2) card authentication, which is an additional layer of security for debit and credit card transactions.

3D Secure 2 vs. 3D Secure 1

3DS 2 is an improvement of 3DS 1 because it:

  • Collects more data elements than 3DS 1. This helps issuing banks assess risk more efficiently by reducing the need to ask for more authentication from the cardholder. It also helps to increase the rate of frictionless transactions and decrease the number of authentication challenges during a transaction.

  • Supports mobile clients. By adding support for native iOS and Android SDKs, cardholders have a smoother mobile authentication experience, without requiring redirects or webviews.


Add a JS reference to your web page.

<script src="" type="text/javascript"></script><script src="" type="text/javascript"></script>

When the Page Loads…

  1. Add an event handler for the payments.validated event. This event will be raised when a payment that requires a popup has completed validation.

Cardinal.on("payments.validated", function (data, jwt) {
            log('payment.validated - ' + data.ActionCode);
            if (data.ActionCode === "ERROR") {
                //handle error
            else {
                //submit payment completion to Cardknox

2. Generate a JWT secure token.

log("Retrieving JWT");
        method: "POST",
        url: "",
        datatype: "json"
    .done(function (response) {
        log('Incoming Response (from GetJWT): ');
        if (response.xResult.toLowerCase() === 'e')
            log('Error retrieving JWT: ' + response.xError);
        else {
            var jwt = response.xResultData;
            var jwtJSON = parseJwt(jwt);
            threeDSRefnum = jwtJSON.ReferenceId;
            log("3DS Refnum: " + threeDSRefnum);
            configureCardinal(jwt); // this is the Cardinal "init" as indicated in step 3
            initializedCardinal = true;

3. Initialize the Cardinal object (init) using the newly generated JWT.

Cardinal.setup("init", {
            jwt: myjwt

When the submit button is clicked…

  1. Wait for initialization to complete before submitting the payment.

    if (checking3DSecureRequirement || (!!process3DSecure && !initializedCardinal)) {
            log('initializing 3D secure, setting timeout');
            window.setTimeout(function () { $("#process_cc_form").submit(); }, 200);
            return false;

  2. Begin the bin profiling process. Wait for completion using .then() syntax as below example.

    Cardinal.trigger("bin.process", 9_digit_card_bin)
    .then(function (results) {
                if (results.Status) {
                  // ...process sale
                } else {
                   // ...handle error
  3. Submit a cc:sale/cc:authonly to Cardknox.


Required fields

  • Standard required fields (see API Documentation for cc:sale and cc:authonly required fields) 

  • x3DSRefnum (ReferenceID present in the JWT)

  • xAuthenticate3d=1

  • xBillCity

  • xBillCountry

  • xBillFirstName

  • xBillLastName

  • xBillState

  • xBillStreet

  • xBillZip

Additional fields (recommended)

  • xShipCity

  • xShipCountry

  • xShipFirstName

  • xShipLastName

  • xShipState

  • xShipStreet

  • xShipZip

Possible responses are xStatus=Approved/Declined or xStatus=Verify:

Contact to configure behavior on non-authenticated 3DS responses.

4. Feed Gateway response fields xVerifyURL, xVerifyPayload, and xInternalID fields into the Javascript function cardinal.Continue. The Javascript function may display a pop-up page, which may require input from the cardholder.

lastGatewayRefnum = objJSON.xRefNum; //lastGatewayRefnum will be submitted in the next Cardknox request
                            log('PAReq and ACSUrl returned');
                            var myRequestObj = {
                                AcsUrl: urldecode(objJSON.xVerifyUrl),
                                Payload: objJSON.xVerifyPayload
                            var myOrderDetailsObj = {
                                "OrderDetails": {
                                    "TransactionId": objJSON.xInternalID
                            log('Cardinal.continue Request object: ' + JSON.stringify(myRequestObj));
                            log('Cardinal.continue OrderDetails object: ' + JSON.stringify(myOrderDetailsObj));
                            Cardinal.continue('cca', myRequestObj, myOrderDetailsObj);

When complete, the payments.validated event is triggered with a response containing the CAVV,ECIFlag,PAResStatus, and SignatureVerification. If data.ActionCode is a successful action code, the event in Step #1 should be configured to send the final cc:sale/cc:authonly transaction to Cardknox referencing the original transaction and including the 3DS verification data.  


Required fields

  • xKey

  • xVersion

  • xSoftwareName

  • xSoftwareVersion

  • xCAVV (CAVV)

  • xECI (ECIFlag)

  • xRefnum from the original cc:sale/cc:authonly response

  • xAuthenticateStatus (PAResStatus)

  • xSignatureVerification (SignatureVerification)

The transaction response xStatus will be Approved or Declined, and the payment is now complete.