3DS Payment Integration

3DS Payment Authentication allows you to authenticate a payment request using 3DS. This guide will outline the requirements for authenticating a payment using 3DS through Wpay and will highlight where the 3DS payment flow and information differs from the normal guide for Making a Payment.

The typical flow for making a payment with 3DS authentication is as follows:

Step 1 - Make a Payment Request:

  1. Ensure you have a payment instrument obtained either from the customer's wallet (for saved instruments) or from tokenizing a payment instrument (for new instruments) which is supported for 3DS authentication.
  2. Make a payment request and include the requires3DS flag in the payment request to indicate that you wish to apply 3DS authentication to the payment
  3. Check the payment response to determine if 3DS authentication is required as part of the payment.
    1. Should the outcome of the payment provide an error outcome indicating 3DS TOKEN REQUIRED then you will need to authenticate the payment via 3DS utilising the Frames SDK. See Step 2.

Step 2 - Request 3DS Authentication:

  1. Utilizing the Frames SDK request 3DS authentication for the requested payment. The outcome of the 3DS authentication will either be frictionless or a challenge required.
  2. Should the 3DS process be successful you will be provided with the 3DS token and reference data which will be required when making the subsequent payment request.

Step 3 - Make a Final Payment Request including the 3DS Data:

  1. Include the requires3DS flag as well as the 3DS token and reference data in the payment request and process the payment
  2. The 3DS data will be authenticated with the issuer to ensure that it is valid and the payment will then be processed.

1. Make a Payment Request

1.1. Request Payment with 3DS Authentication

Make a payment request and include the merchantPayload and set the requires3DS flag to true.

Example of required merchantPayload:
"merchantPayload": {
  "payload": {
    "requires3DS": true
  },
  "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
}
Example of payment request with included merchantPayload :
curl --location --request POST 'https://{{environment}}.wpay.com.au/wow/v1/pay/instore/customer/payments' \
--header 'X-Api-Key: {{yourAPIKey}}' \
--header 'Authorization: Bearer {{yourBearerToken}}' \
--header 'x-guest: false' \
--header 'Content-Type: application/json' \
--data-raw '{
  "data": {
    "transactionType": {
      "creditCard": "PREAUTH",
      "giftCard": "PURCHASE",
      "payPal": "PURCHASE",
      "googlePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      },
      "applePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      }
    },
    "merchantPayload": {
      "payload": {
      	"requires3DS": true
      },
      "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
    },
    "clientReference": "UNIQUE_CLIENT_REFERENCE",
    "orderNumber": "UNIQUE_ORDER_NO",
    "payments": [
      {
        "paymentInstrumentId": "213553",
        "amount": 10.5
      },
       {
        "paymentInstrumentId": "215319",
        "amount": 6.5
      }
    ]
  },
  "meta": {
    "fraud": {
        "provider": "cybersource",
        "version": "CyberSourceTransaction_1.101",
        "format": "XML",
        "responseFormat": "XML",
        "message": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<RequestMessage xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n  <merchantID>TEST_MERCHANT_ID</merchantID>\r\n  <merchantReferenceCode>1234-26IO8JUN</merchantReferenceCode>\r\n  <billTo>\r\n    <firstName>Jane</firstName>\r\n    <lastName>Doe</lastName>\r\n    <street1>407 ELIZABETH STREET</street1>\r\n    <city>SURRY HILLS</city>\r\n    <state>NSW</state>\r\n    <postalCode>2199</postalCode>\r\n    <country>AU</country>\r\n    <phoneNumber>0400000000</phoneNumber>\r\n    <email>[email protected]</email>\r\n    <ipAddress>202.39.111.236</ipAddress>\r\n    <dateOfBirth>1987-02-14</dateOfBirth>\r\n    <customerID>3732442</customerID>\r\n  </billTo>\r\n  <shipTo>\r\n    <firstName>Jane</firstName>\r\n    <lastName>Doe</lastName>\r\n    <phoneNumber>0400000000</phoneNumber>\r\n    <email>[email protected]</email>\r\n  </shipTo>\r\n  <item id=\"0\">\r\n    <unitPrice>7.59</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Mccain Protein Plus Frozen Meal Satay Chicken</productName>\r\n    <productSKU>483660</productSKU>\r\n  </item>\r\n  <item id=\"1\">\r\n    <unitPrice>2.00</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Habee Savers Needles Household Repair</productName>\r\n    <productSKU>159489</productSKU>\r\n  </item>\r\n  <item id=\"2\">\r\n    <unitPrice>6.60</unitPrice>\r\n    <quantity>5</quantity>\r\n    <productName>Chicken Breast Fillet Skinless Small</productName>\r\n    <productSKU>118963</productSKU>\r\n  </item>\r\n  <item id=\"3\">\r\n    <unitPrice>5.43</unitPrice>\r\n    <quantity>5</quantity>\r\n    <productName>Chicken Drumsticks </productName>\r\n    <productSKU>169014</productSKU>\r\n  </item>\r\n  <item id=\"4\">\r\n    <unitPrice>3.50</unitPrice>\r\n    <quantity>4</quantity>\r\n    <productName>Chicken Thigh Cutlets Skinless</productName>\r\n    <productSKU>166830</productSKU>\r\n  </item>\r\n  <item id=\"5\">\r\n    <unitPrice>10.80</unitPrice>\r\n    <quantity>4</quantity>\r\n    <productName>Lamb Diced Heart Smart</productName>\r\n    <productSKU>208970</productSKU>\r\n  </item>\r\n  <item id=\"6\">\r\n    <unitPrice>4.94</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Macro Chicken Lovely Legs Free Range</productName>\r\n    <productSKU>700257</productSKU>\r\n  </item>\r\n  <item id=\"7\">\r\n    <unitPrice>19.64</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Macro Organic Whole Chicken</productName>\r\n    <productSKU>229320</productSKU>\r\n  </item>\r\n  <item id=\"8\">\r\n    <unitPrice>9.60</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Msa Australian Beef Steak Porterhouse</productName>\r\n    <productSKU>208988</productSKU>\r\n  </item>\r\n  <item id=\"9\">\r\n    <unitPrice>15.20</unitPrice>\r\n    <quantity>3</quantity>\r\n    <productName>Roast Pork Shoulder Boneless Small</productName>\r\n    <productSKU>203420</productSKU>\r\n  </item>\r\n  <item id=\"10\">\r\n    <unitPrice>10.80</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Select Corned Beef Silverside </productName>\r\n    <productSKU>148345</productSKU>\r\n  </item>\r\n  <item id=\"11\">\r\n    <unitPrice>13.00</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Clairol Nice N Easy 114a Natural Lightest Golden Brown</productName>\r\n    <productSKU>226536</productSKU>\r\n  </item>\r\n  <purchaseTotals>\r\n    <currency>AUD</currency>\r\n    <grandTotalAmount>298.09</grandTotalAmount>\r\n  </purchaseTotals>\r\n  <merchantDefinedData>\r\n    <mddField id=\"19\">Pickup</mddField>\r\n    <mddField id=\"10\">NO</mddField>\r\n    <mddField id=\"3\">Woolworths WOLLI CREEK, WOLLI CREEK</mddField>\r\n    <mddField id=\"1\">2017-09-22 16:00</mddField>\r\n    <mddField id=\"2\">NSW</mddField>\r\n    <mddField id=\"12\">NO</mddField>\r\n    <mddField id=\"16\">103</mddField>\r\n    <mddField id=\"23\"></mddField>\r\n    <mddField id=\"17\">2017-09-18 12:40</mddField>\r\n    <mddField id=\"18\">2017-09-18 12:40</mddField>\r\n    <mddField id=\"25\">2017-09-22 16:00</mddField>\r\n    <mddField id=\"20\">WEB</mddField>\r\n    <mddField id=\"57\">Normal</mddField>\r\n    <mddField id=\"58\"></mddField>\r\n    <mddField id=\"59\" />\r\n    <mddField id=\"60\">298.09</mddField>\r\n  </merchantDefinedData>\r\n  <afsService run=\"true\" />\r\n  <deviceFingerprintID>18S###-26IO####</deviceFingerprintID>\r\n</RequestMessage>"
    },
    "challengeResponses": [
      {
        "instrumentId": "213553",
        "type": "STEP_UP",
        "token": "55bda344-c0ec-####-####-############"
      }
    ]
  }
}'
var myHeaders = new Headers();
var environment = "substitute environment-value here"
var yourAPIkey = "YOUR-API-KEY";
var accessToken = "ACCESS-TOKEN";
var selectedIntrument1 = "1ST_SELECTED_INTRUMENT_NUMBER"
var selectedIntrument2 = "2ND_SELECTED_INTRUMENT_NUMBER"
myHeaders.append("X-Api-Key", yourAPIKey);
myHeaders.append("Authorization", `Bearer ${accessToken}`);
myHeaders.append("x-guest", "false");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
    "data": {
        "transactionType": {
            "creditCard": "PREAUTH",
            "giftCard": "PURCHASE",
            "payPal": "PURCHASE",
            "googlePay": {
                "creditCard": "PREAUTH",
                "debitCard": "PURCHASE"
            },
            "applePay": {
                "creditCard": "PREAUTH",
                "debitCard": "PURCHASE"
            }
        },
        "merchantPayload": {
            "payload": {
                "requires3DS": true
            },
            "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
        },
        "clientReference": "UNIQUE_CLIENT_REFERENCE",
        "orderNumber": "UNIQUE_ORDER_NO",
        "payments": [
            {
                "paymentInstrumentId": selectedInstrument1,
                "amount": 10.5
            },
            {
                "paymentInstrumentId": selectedInstrument2,
                "amount": 6.5
            }
        ]
    },
    "meta": {
        "fraud": {
            "provider": "cybersource",
            "version": "CyberSourceTransaction_1.101",
            "format": "XML",
            "responseFormat": "XML",
            "message": "<?xml version="1.0" encoding="Windows-1252"?>rn<RequestMessage xmlns:xsd="http: //www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">rn  <merchantID>TEST_MERCHANT_ID</merchantID>rn  <merchantReferenceCode>1234-26IO8JUN</merchantReferenceCode>rn  <billTo>rn    <firstName>Jane</firstName>rn    <lastName>Doe</lastName>rn    <street1>407 ELIZABETH STREET</street1>rn    <city>SURRY HILLS</city>rn    <state>NSW</state>rn    <postalCode>2199</postalCode>rn    <country>AU</country>rn    <phoneNumber>0400000000</phoneNumber>rn    <email>[email protected]</email>rn    <ipAddress>202.39.111.236</ipAddress>rn    <dateOfBirth>1987-02-14</dateOfBirth>rn    <customerID>3732442</customerID>rn  </billTo>rn  <shipTo>rn    <firstName>Jane</firstName>rn    <lastName>Doe</lastName>rn    <phoneNumber>0400000000</phoneNumber>rn    <email>[email protected]</email>rn  </shipTo>rn  <item id="0">rn    <unitPrice>7.59</unitPrice>rn    <quantity>2</quantity>rn    <productName>Mccain Protein Plus Frozen Meal Satay Chicken</productName>rn    <productSKU>483660</productSKU>rn  </item>rn  <item id="1">rn    <unitPrice>2.00</unitPrice>rn    <quantity>2</quantity>rn    <productName>Habee Savers Needles Household Repair</productName>rn    <productSKU>159489</productSKU>rn  </item>rn  <item id="2">rn    <unitPrice>6.60</unitPrice>rn    <quantity>5</quantity>rn    <productName>Chicken Breast Fillet Skinless Small</productName>rn    <productSKU>118963</productSKU>rn  </item>rn  <item id="3">rn    <unitPrice>5.43</unitPrice>rn    <quantity>5</quantity>rn    <productName>Chicken Drumsticks </productName>rn    <productSKU>169014</productSKU>rn  </item>rn  <item id="4">rn    <unitPrice>3.50</unitPrice>rn    <quantity>4</quantity>rn    <productName>Chicken Thigh Cutlets Skinless</productName>rn    <productSKU>166830</productSKU>rn  </item>rn  <item id="5">rn    <unitPrice>10.80</unitPrice>rn    <quantity>4</quantity>rn    <productName>Lamb Diced Heart Smart</productName>rn    <productSKU>208970</productSKU>rn  </item>rn  <item id="6">rn    <unitPrice>4.94</unitPrice>rn    <quantity>2</quantity>rn    <productName>Macro Chicken Lovely Legs Free Range</productName>rn    <productSKU>700257</productSKU>rn  </item>rn  <item id="7">rn    <unitPrice>19.64</unitPrice>rn    <quantity>2</quantity>rn    <productName>Macro Organic Whole Chicken</productName>rn    <productSKU>229320</productSKU>rn  </item>rn  <item id="8">rn    <unitPrice>9.60</unitPrice>rn    <quantity>2</quantity>rn    <productName>Msa Australian Beef Steak Porterhouse</productName>rn    <productSKU>208988</productSKU>rn  </item>rn  <item id="9">rn    <unitPrice>15.20</unitPrice>rn    <quantity>3</quantity>rn    <productName>Roast Pork Shoulder Boneless Small</productName>rn    <productSKU>203420</productSKU>rn  </item>rn  <item id="10">rn    <unitPrice>10.80</unitPrice>rn    <quantity>2</quantity>rn    <productName>Select Corned Beef Silverside </productName>rn    <productSKU>148345</productSKU>rn  </item>rn  <item id="11">rn    <unitPrice>13.00</unitPrice>rn    <quantity>2</quantity>rn    <productName>Clairol Nice N Easy 114a Natural Lightest Golden Brown</productName>rn    <productSKU>226536</productSKU>rn  </item>rn  <purchaseTotals>rn    <currency>AUD</currency>rn    <grandTotalAmount>298.09</grandTotalAmount>rn  </purchaseTotals>rn  <merchantDefinedData>rn    <mddField id="19">Pickup</mddField>rn    <mddField id="10">NO</mddField>rn    <mddField id="3">Woolworths WOLLI CREEK, WOLLI CREEK</mddField>rn    <mddField id="1">2017-09-22 16:00</mddField>rn    <mddField id="2">NSW</mddField>rn    <mddField id="12">NO</mddField>rn    <mddField id="16">103</mddField>rn    <mddField id="23"></mddField>rn    <mddField id="17">2017-09-18 12:40</mddField>rn    <mddField id="18">2017-09-18 12:40</mddField>rn    <mddField id="25">2017-09-22 16:00</mddField>rn    <mddField id="20">WEB</mddField>rn    <mddField id="57">Normal</mddField>rn    <mddField id="58"></mddField>rn    <mddField id="59" />rn    <mddField id="60">298.09</mddField>rn  </merchantDefinedData>rn  <afsService run="true" />rn  <deviceFingerprintID>18S###-26IO####</deviceFingerprintID>rn</RequestMessage>"
        },
        "challengeResponses": [
            {
                "instrumentId": selectedInstrument1,
                "type": "STEP_UP",
                "token": "55bda344-c0ec-####-####-############"
            }
        ]
    }
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch(`https://${environment}.wpay.com.au/wow/v1/pay/instore/customer/payments`, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

1.2. Check Payment Response to Determine if 3DS Authentication is Required

{
    "data": {
        "transactionId": "9b8e30bb-c8bb-4762-8a47-2233e59c21d7",
        "paymentRequestId": "1037fca0-9118-4664-9f63-696ecbcfe44d",
        "type": "PAYMENT",
        "status": "REJECTED",
        "rollback": "NOT_REQUIRED",
        "grossAmount": 50.5,
        "executionTime": "2022-02-21T08:51:54.908Z",
        "merchantReferenceId": "82799438",
        "clientReference": "80085011",
        "instruments": [
            {
                "paymentInstrumentId": "2159648",
                "instrumentType": "CREDIT_CARD",
                "transactions": []
            }
        ],
        "subTransactions": [
            {
                "errorCode": "3DS_001",
                "errorMessage": "3DS TOKEN REQUIRED",
                "threeDS": {
                    "paymentInstrumentId": "2159648",
                    "sessionId": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDM3ZmNhMC05MTE4LTQ2NjQtOWY2My02OTZlY2JjZmU0NGQiLCJpYXQiOjE2NDU0MzM1MTguMDQzLCJpc3MiOiI2MGI2ODk3ZDhmZjhhNzQ5OGY4ZDFhYmUiLCJPcmdVbml0SWQiOiI2MGFmOGExZTBiYWM1ZDUwY2MyNmYzM2MiLCJQYXlsb2FkIjp7InBheW1lbnRJbnN0cnVtZW50SWQiOiIyMTU5NjQ4IiwidG9rZW5UeXBlIjoiUEFOIiwib3JkZXJJbmZvcm1hdGlvbiI6eyJhbW91bnREZXRhaWxzIjp7ImN1cnJlbmN5IjoiQVVEIiwiYW1vdW50Ijo1MC41fX19LCJPYmplY3RpZnlQYXlsb2FkIjp0cnVlLCJSZWZlcmVuY2VJZCI6IjVlYThkYThmLTVkOWYtNGZlYy04Nzg5LWE1NGM5Mzg2MzlkYyJ9.xcz0QKB6Ngq7zDPVk_rOALTwvzo-tQm-0u9D3OHek0g"
                }
            }
        ]
    },
    "meta": {}
}

Where:

  • The "errorCode": "3DS_001" indicate that a 3DS token is required and that 3DS authentication should be requested.
  • The threeDS - sessionId is required when completing authentication via 3DS in the next step.

2. Request 3DS2 Authentication

Using the sessionId obtained in the previous step you will use the Wpay Frames SDK to request 3DS authentication from your customer's issuing bank.

if (paymentResponse.status === 'APPROVED') {
  paymentComplete = true;
  paymentStatus = 'Payment Complete';
} else {
  // If error code is 3DS_001 then failure was due to a 3DS challenge
  if (paymentResponse.subTransactions[0].errorCode === '3DS_001') {
    const sessionId = paymentResponse.subTransactions[0].threeDS.sessionId;

    // Perform 3DS authentication
    const threeDSResponse = await capture3DS(sessionId, this.selectedInstrument, FRAMES.ActionTypes.ValidatePayment);

    if (threeDSResponse.threeDSData && 
        (threeDSResponse.threeDSData.status === 'AUTHENTICATION_SUCCESSFUL' || 
         threeDSResponse.threeDSData.ActionCode === 'SUCCESS')) {
      challengeResponses.push(
        threeDSResponse.challengeResponse,
      );
    } else {
      paymentFailed = true;

      this.paymentStatus = 
        (threeDSResponse.threeDSData && threeDSResponse.threeDSData.Payment &&
         threeDSResponse.threeDSData.Payment.ExtendedData && 
         threeDSResponse.threeDSData.Payment.ExtendedData.ChallengeCancel === '01') ? 
        'Payment Failed - 3DS verification cancelled by user' : 
        'Payment Failed - 3DS verification failed';
    }
  } else {
    paymentFailed = true;
    paymentStatus = 'Payment Failed';
  }
}

Where:

  • cardCaptureResponse.errorCode will show any errors encoutered during 3DS authentication as defined in the section Error Codes

2.1. Authenticate payment via 3DS

Usually a customer will be authenticated frictionlessly meaning that no customer authentication is required, however in some cases the card issuer may require additional authentication. In this case a challenge-response is requested from the customer. This usually takes the form of an OTP via SMS.

Where a challenge-response is generated from the customer's issuer you will render a 3DS Challenge Model. While the content is controlled by the issuer there are some modifications that can be made to better fit this model into your existing CX.

Controlling the visibility of the 3DS Challenge Model.

The Model can be controlled in a couple of ways, size and the spinner.

let showSpinner = true;

private async capture3DS(sessionId, paymentInstrumentId, actionType) {
  const enrollmentRequest = {
    sessionId,
    paymentInstrumentId,
    threeDS: {
      consumerAuthenticationInformation: {
        acsWindowSize: settings.customer.acsWindowSize,
      },
    },
  };

  // Create a new payment validation frames action
  const action = framesSDK.createAction(actionType, enrollmentRequest);

  // Start the action, creating a new JWT and initialising cardinal
  await action.start();

  // Set the placeholder for the challenge IFrame to be injected
  action.createFramesControl('3DSValidation', 'overlay');

  const elementHandle = document.getElementById('overlay');

  const renderEventListener = () => {
    this.showSpinner = false;
    this.show3DS = true;
  };

  const closeEventListener = () => {
    this.showSpinner = true;
    this.show3DS = false;
  };

  // Add the event listeners for OnRender and OnClose for the 3DS challenge response
  elementHandle.addEventListener(FRAMES.FramesCardinalEventType.OnRender, renderEventListener);
  elementHandle.addEventListener(FRAMES.FramesCardinalEventType.OnClose, closeEventListener);

  // Check card enrolment, allowing cardinal show issuer challenge
  const authorizationResponse = await action.complete();

  // Romove the event listeners for OnRender and OnClose for the 3DS challenge response
  elementHandle.removeEventListener(FRAMES.FramesCardinalEventType.OnRender, renderEventListener);
  elementHandle.removeEventListener(FRAMES.FramesCardinalEventType.OnClose, closeEventListener);

  // 3DS check complete, use returned information to provide a challenge response within the payment endpoint
  console.log(`3DS authorization complete: ${JSON.stringify(authorizationResponse)}`);

  if (actionType === FRAMES.ActionTypes.ValidatePayment) {
    paymentAuthentication = authorizationResponse;
  } else if (actionType === FRAMES.ActionTypes.ValidateCard) {
    cardValidation = authorizationResponse;
  }

  return authorizationResponse;
}
<div class="container">
  <!-- 
       3DS iFrame Challenge response placeholer.
       Includes a Vue.js class which controls the visible of this model, 
       based on the value of the show3DS variable.
  -->
  <div 
       id="overlay" 
       class="overlay" 
       style="" 
       v-bind:class="{ hidden: !this.show3DS }">
  </div>
  
  <!-- Card Capture iFrame place holder -->
  <div id="cardGroupPlaceholder"></div>
  
  <!--
      Display the Spinner component, when 
        the paymentDisabled variable is true or 
        the showSpinner variable is true.
  -->
  <div class="processing" 
       v-bind:class="{ hidden: !this.paymentDisabled || this.showSpinner === false }">
    <Spinner/>
  </div>
</div>
/*
  You provide can style the 3DS Challenge reponse iframe model
  with custom css as shown below:
*/
.overlay {
  position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.5); 
  display: flex; 
  flex-direction: column; 
  align-items: center;
  z-index: 1; 
  justify-content: center;
}

.overlay iframe {
  background: white;
  padding: 5px;
  border-radius: 5px;
  border: 1px solid black;
}

/* Positioning the Spinner component. */
.processing {
  text-align: center;
}

Where:

  • acsWindowSize allows you to control the size of the 3DS challenge window and has values defined in the FAQs
  • After validation of the card entered by the user the showSpinner is set to try showing a spinner while we wait for the issuer to return
Show the 3DS payment challenge response modal

When action.complete is called and the renderEventListener is fired, causing:

  • the showSpinner to be set to false, causing this spinner to be hidden and
  • the show3DS variable will be set to true, causing the Challenge Response Modal to be displayed like the one shown below:
215

Sample 3DS2 OTP screen for a $12 payment

Once the challenge is authenticated (in the above example this means the one time password that has been texted to the customer is entered and submitted), the closeEventListener is fired, setting the show3DS variable to false hiding the challenge-response iFrame.

Example of 3DS Challenge Response:

Below is an example of the response from the 3DS authentication request made through the Frames SDK. You can take the response as is and use it when making a payment as part of the challengeResponses array in the next step.

{
  "type": "3DS-frictionless",
  "instrumentId": "213553",
  "token": "{{challengeResponseToken}}",
  "reference": "{{ServerJWT}}"
}

3. Make a Final Payment Request including the 3DS Data

Now that we've completed our 3DS authentication we can add the required 3DS data to the challengeResponses and attempt to reprocess the payment.

curl --location --request POST 'https://{{environment}}.wpay.com.au/wow/v1/pay/instore/customer/payments' \
--header 'X-Api-Key: {{yourAPIKey}}' \
--header 'Authorization: Bearer {{yourBearerToken}}' \
--header 'x-guest: false' \
--header 'Content-Type: application/json' \
--data-raw '{
  "data": {
    "transactionType": {
      "creditCard": "PREAUTH",
      "giftCard": "PURCHASE",
      "payPal": "PURCHASE",
      "googlePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      },
      "applePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      }
    },
    "merchantPayload": {
      "payload": {
      	"requires3DS": true
      },
      "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
    },
    "clientReference": "UNIQUE_CLIENT_REFERENCE",
    "orderNumber": "UNIQUE_ORDER_NO",
    "payments": [
      {
        "paymentInstrumentId": "213553",
        "amount": 10.5
      },
       {
        "paymentInstrumentId": "215319",
        "amount": 6.5
      }
    ]
  },
  "meta": {
    "fraud": {
        "provider": "cybersource",
        "version": "CyberSourceTransaction_1.101",
        "format": "XML",
        "responseFormat": "XML",
        "message": "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n<RequestMessage xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\r\n  <merchantID>TEST_MERCHANT_ID</merchantID>\r\n  <merchantReferenceCode>1234-26IO8JUN</merchantReferenceCode>\r\n  <billTo>\r\n    <firstName>Jane</firstName>\r\n    <lastName>Doe</lastName>\r\n    <street1>407 ELIZABETH STREET</street1>\r\n    <city>SURRY HILLS</city>\r\n    <state>NSW</state>\r\n    <postalCode>2199</postalCode>\r\n    <country>AU</country>\r\n    <phoneNumber>0400000000</phoneNumber>\r\n    <email>[email protected]</email>\r\n    <ipAddress>202.39.111.236</ipAddress>\r\n    <dateOfBirth>1987-02-14</dateOfBirth>\r\n    <customerID>3732442</customerID>\r\n  </billTo>\r\n  <shipTo>\r\n    <firstName>Jane</firstName>\r\n    <lastName>Doe</lastName>\r\n    <phoneNumber>0400000000</phoneNumber>\r\n    <email>[email protected]</email>\r\n  </shipTo>\r\n  <item id=\"0\">\r\n    <unitPrice>7.59</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Mccain Protein Plus Frozen Meal Satay Chicken</productName>\r\n    <productSKU>483660</productSKU>\r\n  </item>\r\n  <item id=\"1\">\r\n    <unitPrice>2.00</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Habee Savers Needles Household Repair</productName>\r\n    <productSKU>159489</productSKU>\r\n  </item>\r\n  <item id=\"2\">\r\n    <unitPrice>6.60</unitPrice>\r\n    <quantity>5</quantity>\r\n    <productName>Chicken Breast Fillet Skinless Small</productName>\r\n    <productSKU>118963</productSKU>\r\n  </item>\r\n  <item id=\"3\">\r\n    <unitPrice>5.43</unitPrice>\r\n    <quantity>5</quantity>\r\n    <productName>Chicken Drumsticks </productName>\r\n    <productSKU>169014</productSKU>\r\n  </item>\r\n  <item id=\"4\">\r\n    <unitPrice>3.50</unitPrice>\r\n    <quantity>4</quantity>\r\n    <productName>Chicken Thigh Cutlets Skinless</productName>\r\n    <productSKU>166830</productSKU>\r\n  </item>\r\n  <item id=\"5\">\r\n    <unitPrice>10.80</unitPrice>\r\n    <quantity>4</quantity>\r\n    <productName>Lamb Diced Heart Smart</productName>\r\n    <productSKU>208970</productSKU>\r\n  </item>\r\n  <item id=\"6\">\r\n    <unitPrice>4.94</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Macro Chicken Lovely Legs Free Range</productName>\r\n    <productSKU>700257</productSKU>\r\n  </item>\r\n  <item id=\"7\">\r\n    <unitPrice>19.64</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Macro Organic Whole Chicken</productName>\r\n    <productSKU>229320</productSKU>\r\n  </item>\r\n  <item id=\"8\">\r\n    <unitPrice>9.60</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Msa Australian Beef Steak Porterhouse</productName>\r\n    <productSKU>208988</productSKU>\r\n  </item>\r\n  <item id=\"9\">\r\n    <unitPrice>15.20</unitPrice>\r\n    <quantity>3</quantity>\r\n    <productName>Roast Pork Shoulder Boneless Small</productName>\r\n    <productSKU>203420</productSKU>\r\n  </item>\r\n  <item id=\"10\">\r\n    <unitPrice>10.80</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Select Corned Beef Silverside </productName>\r\n    <productSKU>148345</productSKU>\r\n  </item>\r\n  <item id=\"11\">\r\n    <unitPrice>13.00</unitPrice>\r\n    <quantity>2</quantity>\r\n    <productName>Clairol Nice N Easy 114a Natural Lightest Golden Brown</productName>\r\n    <productSKU>226536</productSKU>\r\n  </item>\r\n  <purchaseTotals>\r\n    <currency>AUD</currency>\r\n    <grandTotalAmount>298.09</grandTotalAmount>\r\n  </purchaseTotals>\r\n  <merchantDefinedData>\r\n    <mddField id=\"19\">Pickup</mddField>\r\n    <mddField id=\"10\">NO</mddField>\r\n    <mddField id=\"3\">Woolworths WOLLI CREEK, WOLLI CREEK</mddField>\r\n    <mddField id=\"1\">2017-09-22 16:00</mddField>\r\n    <mddField id=\"2\">NSW</mddField>\r\n    <mddField id=\"12\">NO</mddField>\r\n    <mddField id=\"16\">103</mddField>\r\n    <mddField id=\"23\"></mddField>\r\n    <mddField id=\"17\">2017-09-18 12:40</mddField>\r\n    <mddField id=\"18\">2017-09-18 12:40</mddField>\r\n    <mddField id=\"25\">2017-09-22 16:00</mddField>\r\n    <mddField id=\"20\">WEB</mddField>\r\n    <mddField id=\"57\">Normal</mddField>\r\n    <mddField id=\"58\"></mddField>\r\n    <mddField id=\"59\" />\r\n    <mddField id=\"60\">298.09</mddField>\r\n  </merchantDefinedData>\r\n  <afsService run=\"true\" />\r\n  <deviceFingerprintID>18S###-26IO####</deviceFingerprintID>\r\n</RequestMessage>"
    },
    "challengeResponses": [
      {
        "instrumentId": "213553",
        "type": "STEP_UP",
        "token": "55bda344-c0ec-####-####-############"
      },
      {
        "type": "3DS-frictionless",
        "instrumentId": "213553",
        "token": "{{challengeResponseToken}}",
        "reference": "{{ServerJWT}}"
      }
    ]
  }
}'
var myHeaders = new Headers();
var environment = "substitute environment-value here"
var yourAPIkey = "YOUR-API-KEY";
var accessToken = "ACCESS-TOKEN";
var challengeResponseToken = "CHALLENGE_RESPONSE_TOKEN";
var serverJWT = "SERVER_JWT";
var selectedIntrument1 = "1ST_SELECTED_INTRUMENT_NUMBER"
var selectedIntrument2 = "2ND_SELECTED_INTRUMENT_NUMBER"
myHeaders.append("X-Api-Key", yourAPIKe);
myHeaders.append("Authorization", `Bearer ${yourBearerToken}`);
myHeaders.append("x-guest", "false");
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({
  "data": {
    "transactionType": {
      "creditCard": "PREAUTH",
      "giftCard": "PURCHASE",
      "payPal": "PURCHASE",
      "googlePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      },
      "applePay": {
        "creditCard": "PREAUTH",
        "debitCard": "PURCHASE"
      }
    },
    "merchantPayload": {
      "payload": {
      	"requires3DS": true
      },
      "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
    },
    "clientReference": "UNIQUE_CLIENT_REFERENCE",
    "orderNumber": "UNIQUE_ORDER_NO",
    "payments": [
      {
        "paymentInstrumentId": selectedIntrument1,
        "amount": 10.5
      },
       {
        "paymentInstrumentId": selectedIntrument2,
        "amount": 6.5
      }
    ]
  },
  "meta": {
    "fraud": {
        "provider": "cybersource",
        "version": "CyberSourceTransaction_1.101",
        "format": "XML",
        "responseFormat": "XML",
        "message": "<?xml version="1.0" encoding="Windows-1252"?>rn<RequestMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">rn  <merchantID>TEST_MERCHANT_ID</merchantID>rn  <merchantReferenceCode>1234-26IO8JUN</merchantReferenceCode>rn  <billTo>rn    <firstName>Jane</firstName>rn    <lastName>Doe</lastName>rn    <street1>407 ELIZABETH STREET</street1>rn    <city>SURRY HILLS</city>rn    <state>NSW</state>rn    <postalCode>2199</postalCode>rn    <country>AU</country>rn    <phoneNumber>0400000000</phoneNumber>rn    <email>[email protected]</email>rn    <ipAddress>202.39.111.236</ipAddress>rn    <dateOfBirth>1987-02-14</dateOfBirth>rn    <customerID>3732442</customerID>rn  </billTo>rn  <shipTo>rn    <firstName>Jane</firstName>rn    <lastName>Doe</lastName>rn    <phoneNumber>0400000000</phoneNumber>rn    <email>[email protected]</email>rn  </shipTo>rn  <item id="0">rn    <unitPrice>7.59</unitPrice>rn    <quantity>2</quantity>rn    <productName>Mccain Protein Plus Frozen Meal Satay Chicken</productName>rn    <productSKU>483660</productSKU>rn  </item>rn  <item id="1">rn    <unitPrice>2.00</unitPrice>rn    <quantity>2</quantity>rn    <productName>Habee Savers Needles Household Repair</productName>rn    <productSKU>159489</productSKU>rn  </item>rn  <item id="2">rn    <unitPrice>6.60</unitPrice>rn    <quantity>5</quantity>rn    <productName>Chicken Breast Fillet Skinless Small</productName>rn    <productSKU>118963</productSKU>rn  </item>rn  <item id="3">rn    <unitPrice>5.43</unitPrice>rn    <quantity>5</quantity>rn    <productName>Chicken Drumsticks </productName>rn    <productSKU>169014</productSKU>rn  </item>rn  <item id="4">rn    <unitPrice>3.50</unitPrice>rn    <quantity>4</quantity>rn    <productName>Chicken Thigh Cutlets Skinless</productName>rn    <productSKU>166830</productSKU>rn  </item>rn  <item id="5">rn    <unitPrice>10.80</unitPrice>rn    <quantity>4</quantity>rn    <productName>Lamb Diced Heart Smart</productName>rn    <productSKU>208970</productSKU>rn  </item>rn  <item id="6">rn    <unitPrice>4.94</unitPrice>rn    <quantity>2</quantity>rn    <productName>Macro Chicken Lovely Legs Free Range</productName>rn    <productSKU>700257</productSKU>rn  </item>rn  <item id="7">rn    <unitPrice>19.64</unitPrice>rn    <quantity>2</quantity>rn    <productName>Macro Organic Whole Chicken</productName>rn    <productSKU>229320</productSKU>rn  </item>rn  <item id="8">rn    <unitPrice>9.60</unitPrice>rn    <quantity>2</quantity>rn    <productName>Msa Australian Beef Steak Porterhouse</productName>rn    <productSKU>208988</productSKU>rn  </item>rn  <item id="9">rn    <unitPrice>15.20</unitPrice>rn    <quantity>3</quantity>rn    <productName>Roast Pork Shoulder Boneless Small</productName>rn    <productSKU>203420</productSKU>rn  </item>rn  <item id="10">rn    <unitPrice>10.80</unitPrice>rn    <quantity>2</quantity>rn    <productName>Select Corned Beef Silverside </productName>rn    <productSKU>148345</productSKU>rn  </item>rn  <item id="11">rn    <unitPrice>13.00</unitPrice>rn    <quantity>2</quantity>rn    <productName>Clairol Nice N Easy 114a Natural Lightest Golden Brown</productName>rn    <productSKU>226536</productSKU>rn  </item>rn  <purchaseTotals>rn    <currency>AUD</currency>rn    <grandTotalAmount>298.09</grandTotalAmount>rn  </purchaseTotals>rn  <merchantDefinedData>rn    <mddField id="19">Pickup</mddField>rn    <mddField id="10">NO</mddField>rn    <mddField id="3">Woolworths WOLLI CREEK, WOLLI CREEK</mddField>rn    <mddField id="1">2017-09-22 16:00</mddField>rn    <mddField id="2">NSW</mddField>rn    <mddField id="12">NO</mddField>rn    <mddField id="16">103</mddField>rn    <mddField id="23"></mddField>rn    <mddField id="17">2017-09-18 12:40</mddField>rn    <mddField id="18">2017-09-18 12:40</mddField>rn    <mddField id="25">2017-09-22 16:00</mddField>rn    <mddField id="20">WEB</mddField>rn    <mddField id="57">Normal</mddField>rn    <mddField id="58"></mddField>rn    <mddField id="59" />rn    <mddField id="60">298.09</mddField>rn  </merchantDefinedData>rn  <afsService run="true" />rn  <deviceFingerprintID>18S###-26IO####</deviceFingerprintID>rn</RequestMessage>"
    },
    "challengeResponses": [
      {
        "instrumentId": "213553",
        "type": "STEP_UP",
        "token": "55bda344-c0ec-####-####-############"
      },
      {
        "type": "3DS-frictionless",
        "instrumentId": "213553",
        "token": challengeResponseToken,
        "reference": ServerJWT
      }
    ]
  }
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch(`https://${environment}.wpay.com.au/wow/v1/pay/instore/customer/payments`, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

Where:

  • type is either 3DS or 3DS-frictionless depending on whether the frictionless or normal 3DS authenticationflow was applied.
  • token is the challengeResponseToken received from the 3DS authentication
  • reference is the ServerJWT received from the 3DS authentication
3DS Payment Success Response

Should the payment be successful you will receive an approved payment. The only difference between the payment response for a successful payment made with vs without a 3DS authenticationis the inclusion of the threeDSData as part of the response payload.

{
    "paymentRequest": {
        "expiryTime": "2021-11-17T08:27:32.309Z",
        "grossAmount": 12.4,
        "usesRemaining": 1,
        "merchantPayload": {
            "payload": {
                "requires3DS": true
            },
            "schemaId": "0a221353-b26c-4848-9a77-4a8bcbacf228"
        },
        "paymentRequestId": "cdbf72ab-03f6-4445-98dc-ec79bce91f17",
        "merchantReferenceId": "9c92a1f2-89c2-47f4-a1d5-dafe6e89bb50"
    },
    "cardValidation": {},
    "cardCapture": {},
    "paymentAuthentication": {
        "threeDSData": {
            "id": "6371373770786754404005",
            "submitTimeUtc": "2021-11-17T08:22:57Z",
            "status": "AUTHENTICATION_SUCCESSFUL",
            "clientReferenceInformation": {
                "code": "cdbf72ab-03f6-4445-98dc-ec79bce91f17"
            },
            "consumerAuthenticationInformation": {
                "acsTransactionId": "f3166c8b-f4c7-484e-99d8-f153fcd14976",
                "authenticationTransactionId": "UsFCe2c0h6cmh8S94sg0",
                "ecommerceIndicator": "spa",
                "eciRaw": "02",
                "paresStatus": "Y",
                "specificationVersion": "2.2.0",
                "threeDSServerTransactionId": "c271835d-d874-413b-846b-17b481bba171",
                "ucafAuthenticationData": "Y2FyZGluYWxjb21tZXJjZWF1dGg=",
                "ucafCollectionIndicator": "2",
                "veresEnrolled": "Y",
                "directoryServerTransactionId": "25050f2a-752d-4b7c-a2c8-7c0e8a379e17"
            }
        },
        "challengeResponse": {
            "type": "3DS-frictionless",
            "instrumentId": "1506694",
            "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjZGJmNzJhYi0wM2Y2LTQ0NDUtOThkYy1lYzc5YmNlOTFmMTciLCJpYXQiOjE2MzcxMzczNzcuNDg3LCJpc3MiOiI2MGI2ODk3ZDhmZjhhNzQ5OGY4ZDFhYmUiLCJPcmdVbml0SWQiOiI2MGFmOGExZTBiYWM1ZDUwY2MyNmYzM2MiLCJQYXlsb2FkIjp7ImlkIjoiNjM3MTM3Mzc3MDc4Njc1NDQwNDAwNSIsInN1Ym1pdFRpbWVVdGMiOiIyMDIxLTExLTE3VDA4OjIyOjU3WiIsInN0YXR1cyI6IkFVVEhFTlRJQ0FUSU9OX1NVQ0NFU1NGVUwiLCJjbGllbnRSZWZlcmVuY2VJbmZvcm1hdGlvbiI6eyJjb2RlIjoiY2RiZjcyYWItMDNmNi00NDQ1LTk4ZGMtZWM3OWJjZTkxZjE3In0sImNvbnN1bWVyQXV0aGVudGljYXRpb25JbmZvcm1hdGlvbiI6eyJhY3NUcmFuc2FjdGlvbklkIjoiZjMxNjZjOGItZjRjNy00ODRlLTk5ZDgtZjE1M2ZjZDE0OTc2IiwiYXV0aGVudGljYXRpb25UcmFuc2FjdGlvbklkIjoiVXNGQ2UyYzBoNmNtaDhTOTRzZzAiLCJlY29tbWVyY2VJbmRpY2F0b3IiOiJzcGEiLCJlY2lSYXciOiIwMiIsInBhcmVzU3RhdHVzIjoiWSIsInNwZWNpZmljYXRpb25WZXJzaW9uIjoiMi4yLjAiLCJ0aHJlZURTU2VydmVyVHJhbnNhY3Rpb25JZCI6ImMyNzE4MzVkLWQ4NzQtNDEzYi04NDZiLTE3YjQ4MWJiYTE3MSIsInVjYWZBdXRoZW50aWNhdGlvbkRhdGEiOiJZMkZ5WkdsdVlXeGpiMjF0WlhKalpXRjFkR2c9IiwidWNhZkNvbGxlY3Rpb25JbmRpY2F0b3IiOiIyIiwidmVyZXNFbnJvbGxlZCI6IlkiLCJkaXJlY3RvcnlTZXJ2ZXJUcmFuc2FjdGlvbklkIjoiMjUwNTBmMmEtNzUyZC00YjdjLWEyYzgtN2MwZThhMzc5ZTE3In19LCJPYmplY3RpZnlQYXlsb2FkIjp0cnVlfQ.OON_4vZk4di0neHFdgBKYznJCP04dn5MxA_thAU5INg",
            "reference": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjZGJmNzJhYi0wM2Y2LTQ0NDUtOThkYy1lYzc5YmNlOTFmMTciLCJpYXQiOjE2MzcxMzczNzQuOTE4LCJpc3MiOiI2MGI2ODk3ZDhmZjhhNzQ5OGY4ZDFhYmUiLCJPcmdVbml0SWQiOiI2MGFmOGExZTBiYWM1ZDUwY2MyNmYzM2MiLCJQYXlsb2FkIjp7InBheW1lbnRJbnN0cnVtZW50SWQiOiIxNTA2Njk0IiwidG9rZW5UeXBlIjoiUEFOIiwib3JkZXJJbmZvcm1hdGlvbiI6eyJhbW91bnREZXRhaWxzIjp7ImN1cnJlbmN5IjoiQVVEIiwiYW1vdW50IjoxMi40fX19LCJPYmplY3RpZnlQYXlsb2FkIjp0cnVlLCJSZWZlcmVuY2VJZCI6ImE0YTM0NjY0LTI4NzYtNDhkMC1hNzc5LTEwZGQ3N2JmZjI3ZiJ9.h5isqwE_q_0loex354OkYjap3g1mczStfSXkrVYow_s"
        }
    },
    "transactions": [
       {
            "type": "PAYMENT",
            "status": "APPROVED",
            "merchantId": "petculture",
            "grossAmount": 12.4,
            "instruments": [
               {
                    "transactions": [
                       {
                            "type": "PAYMENT",
                            "amount": 12.4,
                            "status": "APPROVED",
                            "executionTime": "2021-11-17T08:22:58.390Z",
                            "paymentTransactionRef": "1000000021406539"
                        }
                    ],
                    "instrumentType": "CREDIT_CARD",
                    "paymentInstrumentId": "1506694"
                }
            ],
            "executionTime": "2021-11-17T08:22:57.834Z",
            "transactionId": "9adec1ec-c50e-4b8f-9dcc-122d41333691",
            "clientReference": "9adec1ec-c50e-4b8f-9dcc-122d41333691",
            "subTransactions": [
               {
                    "fraudResponse": {
                        "clientId": null,
                        "decision": null,
                        "reasonCode": null
                    },
                    "partialSuccess": false,
                    "paymentResponses": [
                       {
                            "threeDS": {
                                "car": null,
                                "sli": null,
                                "dsTransID": "25050f2a-752d-4b7c-a2c8-7c0e8a379e17"
                            },
                            "receiptData": {
                                "scheme": "MASTERCARD",
                                "cardSuffix": "2235",
                                "expiryYear": "24",
                                "expiryMonth": "03"
                            },
                            "paymentToken": "a1d12c5e-9179-42ee-92ca-671fa9ec90b1",
                            "externalServiceCode": "00",
                            "paymentInstrumentId": "1506694",
                            "paymentInstrumentType": "CREDIT_CARD",
                            "paymentTransactionRef": "1000000021406539",
                            "externalServiceMessage": "APPROVED",
                            "extendedTransactionData": [
                               {
                                    "field": "bin",
                                    "value": "520000"
                                },
                               {
                                    "field": "stan",
                                    "value": "035772"
                                },
                               {
                                    "field": "rrn",
                                    "value": "000000035772"
                                },
                               {
                                    "field": "mid",
                                    "value": "6110006020Q0001"
                                },
                               {
                                    "field": "terminalId",
                                    "value": "Q0001100"
                                }
                            ]
                        }
                    ],
                    "transactionReceipt": "1000000021406539"
                }
            ],
            "paymentRequestId": "cdbf72ab-03f6-4445-98dc-ec79bce91f17",
            "merchantReferenceId": "9c92a1f2-89c2-47f4-a1d5-dafe6e89bb50-1"
        }
    ]
}
3DS Payment Error Response

Should an error occur either due to payment validation or due to 3DS an error response will be returned as per the below:

{
    "data": {
        "transactionId": "9b8e30bb-c8bb-4762-8a47-2233e59c21d7",
        "paymentRequestId": "1037fca0-9118-4664-9f63-696ecbcfe44d",
        "type": "PAYMENT",
        "status": "REJECTED",
        "rollback": "NOT_REQUIRED",
        "grossAmount": 50.5,
        "executionTime": "2022-02-21T08:51:54.908Z",
        "merchantReferenceId": "82799438",
        "clientReference": "80085011",
        "instruments": [
            {
                "paymentInstrumentId": "2159648",
                "instrumentType": "CREDIT_CARD",
                "transactions": []
            }
        ],
        "subTransactions": [
            {
                "errorCode": "3DS_001",
                "errorMessage": "3DS TOKEN REQUIRED",
                "threeDS": {
                    "paymentInstrumentId": "2159648",
                    "sessionId": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMDM3ZmNhMC05MTE4LTQ2NjQtOWY2My02OTZlY2JjZmU0NGQiLCJpYXQiOjE2NDU0MzM1MTguMDQzLCJpc3MiOiI2MGI2ODk3ZDhmZjhhNzQ5OGY4ZDFhYmUiLCJPcmdVbml0SWQiOiI2MGFmOGExZTBiYWM1ZDUwY2MyNmYzM2MiLCJQYXlsb2FkIjp7InBheW1lbnRJbnN0cnVtZW50SWQiOiIyMTU5NjQ4IiwidG9rZW5UeXBlIjoiUEFOIiwib3JkZXJJbmZvcm1hdGlvbiI6eyJhbW91bnREZXRhaWxzIjp7ImN1cnJlbmN5IjoiQVVEIiwiYW1vdW50Ijo1MC41fX19LCJPYmplY3RpZnlQYXlsb2FkIjp0cnVlLCJSZWZlcmVuY2VJZCI6IjVlYThkYThmLTVkOWYtNGZlYy04Nzg5LWE1NGM5Mzg2MzlkYyJ9.xcz0QKB6Ngq7zDPVk_rOALTwvzo-tQm-0u9D3OHek0g"
                }
            }
        ]
    },
    "meta": {}
}

Where

  • errorCode will give the error received during the payment request. A full list of error codes can be found here.
  • errorMessage will give a description of the error received.

Additional Information

  • A set of 3DS specific test cards are available to validate the full range of results available from issuers
  • The list of 3DS error codes are listed here
  • 3DS information (e.g. frame sizing) is included on our FAQs