{"title":"Helper functions","category":"default","creationDate":1776961629,"content":"<p>Use our helper functions to:<\/p>\n<ul>\n<li>Collect browser info and store data in properties required in the EMVCo specifications.<\/li>\n<li>Perform base64url encoding and decoding.<\/li>\n<li>Create an iframe with an onload event listener for the 3D Secure 2 device fingerprinting and challenge results.<\/li>\n<li>Create a form with a target attribute to send the issuer requests for 3D Secure 2 device fingerprinting and the challenge.<\/li>\n<li>Configure the challenge window size according to the EMVCo specifications.<\/li>\n<\/ul>\n<h2 id=\"before-you-begin\">Before\u00a0you begin<\/h2>\n<p>Before you begin to integrate, make sure you have followed the <a href=\"\/pt\/get-started-with-adyen\">Get started with Adyen guide<\/a> to:<\/p>\n<ul>\n<li>Get an overview of the steps needed to accept live payments.<\/li>\n<li>Create your test account.<\/li>\n<\/ul>\n<p>After you have created your test account:<\/p>\n<ol>\n<li>\n<p><a href=\"\/pt\/development-resources\/api-credentials#generate-api-key\">Get your API Key<\/a>. Save a copy\u00a0as you'll need it for API calls you make to the Adyen payments platform.<\/p>\n<\/li>\n<li>\n<p>Install one of our\u00a0<a href=\"\/pt\/development-resources\/libraries\">Libraries<\/a>\u00a0to connect with the Adyen APIs. For more information on these steps, refer to\u00a0<a href=\"\/pt\/get-started-with-adyen\">Get started with Adyen<\/a>.<\/p>\n<\/li>\n<li>\n<p>Read and understand the\u00a0<a href=\"\/pt\/online-payments\/build-your-integration\/advanced-flow\/?platform=Web&amp;integration=API%20only&amp;version=71\">API-only integration<\/a> guide. You should already know how to collect shopper information, either with the\u00a0<a href=\"\/pt\/payment-methods\/cards\">Card component<\/a>\u00a0or with your\u00a0<a href=\"\/pt\/online-payments\/build-your-integration\/advanced-flow\/?platform=Web&amp;integration=API%20only&amp;version=71\">own payment form<\/a> implementation.<\/p>\n<\/li>\n<li>\n<p>Set up your notification URLs. The issuer will send an HTTP POST containing the 3D Secure 2 device fingerprinting process and the challenge result to these URLs.<\/p>\n<ul>\n<li><code>YOUR_3DS_METHOD_NOTIFICATION_URL<\/code>: Absolute URL\u00a0to where the issuer can post the result of the 3D Secure device fingerprinting process.\u00a0<\/li>\n<li><code>YOUR_3DS_NOTIFICATION_URL<\/code>: Absolute URL to where the issuer can post a base64url encoded Challenge Response (<code>CRes<\/code>)\u00a0message, containing the challenge result.<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>Import our helper functions by:<\/p>\n<ul>\n<li>\n<p>Cloning our repository from\u00a0<a href=\"https:\/\/github.com\/Adyen\/adyen-3ds2-js-utils\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">https:\/\/github.com\/Adyen\/adyen-3ds2-js-utils<\/a>\u00a0and importing the files into your project.\u00a0<\/p>\n<pre><code class=\"language-js\">import collectBrowserInfo from \".\/browser\";\nimport base64Url from \".\/base64url\";\nimport createIframe from \".\/iframe\";\nimport createForm from \".\/form\";\nimport {validateChallengeWindowSize, getChallengeWindowSize} from \".\/config.js\";<\/code><\/pre>\n<\/li>\n<li>\n<p>Or by building the file, hosting it, and then embedding it in your page.\u00a0<\/p>\n<pre><code class=\"language-xml\">&lt;script type=\"text\/javascript\" src=\"YOUR_PATH\/threeds2-js-utils.js\"&gt;<\/code><\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h2 id=\"collect-the-shoppers-browser-information\">Collect the shopper's browser information<\/h2>\n<p>The\u00a0<code>browserInfo<\/code>\u00a0object is required when submitting a 3D Secure 2 payment request. To get the required values for the transaction, use the\u00a0<code>collectBrowserInfo<\/code>\u00a0function. Pass on the values to your server.<\/p>\n<pre><code class=\"language-js\">const browserInf = collectBrowserInfo();\nconst requestObj =\n{\n    browserInfo         : {\n        \"acceptHeader\"  : \"TO BE ADDED BY SERVER\",\n        \"colorDepth\"    : browserInf.colorDepth,\n        \"javaEnabled\"   : browserInf.javaEnabled,\n        \"language\"      : browserInf.language,\n        \"screenHeight\"  : browserInf.screenHeight,\n        \"screenWidth\"   : browserInf.screenWidth,\n        \"timeZoneOffset\": browserInf.timeZoneOffset,\n        \"userAgent\"     : browserInf.userAgent\n};<\/code><\/pre>\n<h2 id=\"submit-a-payment-request\">Submit a payment request<\/h2>\n<p>Submit a payment request with a POST\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments<\/a>\u00a0call. Include the\u00a0following\u00a0to indicate that you are ready to accept 3D Secure 2 payments:<\/p>\n<ul>\n<li><code>channel<\/code>: <strong>web<\/strong><\/li>\n<li><code>authenticationData.threeDSRequestData.nativeThreeDS<\/code>:\u00a0<strong>preferred<\/strong><\/li>\n<li><code>browserInfo<\/code>: Collect information about your shopper's browser.<\/li>\n<li><code>threeDS2RequestData.notificationURL<\/code>:\u00a0<code>YOUR_3DS_NOTIFICATION_URL<\/code><\/li>\n<\/ul>\n<div class=\"sc-notice note\"><div>\n<p>To increase the likelihood of achieving a frictionless flow and higher authorisation rates, we also recommend that you send additional parameters in <a href=\"\/pt\/online-payments\/3d-secure\/api-reference#3d-secure-2-additional-data-objects\">this list<\/a>.<\/p>\n<\/div><\/div>\n<h6>Request<\/h6>\n<pre><code class=\"language-bash\">curl https:\/\/checkout-test.adyen.com\/v66\/payments \\\n-H 'X-API-key: [Your API Key here]' \\\n-H 'content-type: application\/json' \\\n-d '{\n   \"amount\":{\n      \"currency\":\"EUR\",\n      \"value\":1500\n   },\n   \"merchantAccount\":\"YOUR_MERCHANT_ACCOUNT\",\n   \"reference\":\"TEST\",\n   \"channel\": \"web\",\n   \"threeDS2RequestData\": {\n      \"notificationURL\":\"YOUR_3DS_NOTIFICATION_URL\"\n   },\n   \"authenticationData\": {\n      \"threeDSRequestData\": {\n        \"nativeThreeDS\": \"preferred\"\n      }\n   },\n   \"returnUrl\":\"https:\/\/your-company.example.com\/checkout\/\",\n   \"browserInfo\":{\n      \"userAgent\":\"Mozilla\\\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\\\/537.36 (KHTML, like Gecko) Chrome\\\/70.0.3538.110 Safari\\\/537.36\",\n      \"acceptHeader\":\"text\\\/html,application\\\/xhtml+xml,application\\\/xml;q=0.9,image\\\/webp,image\\\/apng,*\\\/*;q=0.8\",\n      \"language\":\"en\",\n      \"colorDepth\":24,\n      \"screenHeight\":723,\n      \"screenWidth\":1536,\n      \"timeZoneOffset\":0,\n      \"javaEnabled\":false\n  },\n   \"paymentMethod\":{\n      \"type\":\"scheme\",\n      \"encryptedCardNumber\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedExpiryMonth\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedExpiryYear\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedSecurityCode\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\"\n  },\n  \"reference\":\"YOUR_ORDER_NUMBER\"\n}'<\/code><\/pre>\n<h6>Response<\/h6>\n<p>You'll receive a response containing:<\/p>\n<ul>\n<li><code>resultCode<\/code>:\u00a0<strong>IdentifyShopper\u00a0<\/strong>or\u00a0<strong>ChallengeShopper<\/strong>. Perform the corresponding\u00a0<a href=\"#get-the-3d-secure-2-device-fingerprint\">3D Secure 2 device fingerprinting<\/a>\u00a0or\u00a0<a href=\"#present-a-challenge\">Present a challenge<\/a>\u00a0flows.\u00a0If the transaction is exempted from 3D Secure 2, you might get an\u00a0<strong>Authorised<\/strong>\u00a0<code>resultCode<\/code>.\u00a0<\/li>\n<li><code>threeds2.fingerprintToken<\/code>\u00a0or\u00a0<code>threeds2.challengeToken<\/code>: Use this to start the\u00a0corresponding\u00a0<a href=\"#get-the-3d-secure-2-device-fingerprint\">Identify the shopper<\/a>\u00a0or\u00a0<a href=\"#present-a-challenge\">Challenge the shopper<\/a>\u00a0flows.\u00a0<\/li>\n<li><code>paymentData<\/code>: Use this for your succeeding POST\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments<\/a>request.<\/li>\n<\/ul>\n<p>\u00a0For other possible\u00a0<code>resultCodes<\/code>, and the actions that you need to take, see\u00a0the\u00a0<a href=\"\/pt\/online-payments\/payment-result-codes\">Result codes<\/a>.<\/p>\n<pre><code class=\"language-json\">{\n  \"resultCode\": \"IdentifyShopper\",\n  \"authentication\": {\n    \"threeds2.fingerprintToken\": \"eyJ0aHJlZURTTWV0aG9kVXJsIjoiaHR0cHM6XC9cL...\"\n  },\n  \"details\": [\n    {\n      \"key\": \"threeds2.fingerprint\",\n      \"type\": \"text\"\n    }\n  ],\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}<\/code><\/pre>\n<h2 id=\"get-the-3d-secure-2-device-fingerprint\">Get the 3D Secure 2 device fingerprint<\/h2>\n<p>If your server receives an\u00a0 <strong>IdentifyShopper<\/strong> <code>resultCode<\/code>,\u00a0you are required to perform the 3D Secure 2 device fingerprinting.<\/p>\n<ol>\n<li>\n<p>Base64 decode the\u00a0<code>threeds2.fingerprintToken<\/code>\u00a0from the\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments<\/a>\u00a0response.\u00a0<\/p>\n<pre><code class=\"language-json\">{\n   \"threeDSMethodUrl\":\"https:\\\/\\\/pal-test.adyen.com\\\/threeds2simulator\\\/acs\\\/startMethod.shtml\",\n   \"threeDSServerTransID\":\"c9f82ec0-9e24-4f79-834d-6f8282de92fa\"\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>Create objects and pass on the values of\u00a0<code>threeDSServerTransID<\/code>\u00a0and\u00a0<code>YOUR_3DS_METHOD_NOTIFICATION_URL<\/code>. Next, use helper functions to base64url encode the data, create an iframe, and create a form that will send an HTTP POST to the\u00a0<code>threeDSMethodURL<\/code>.<\/p>\n<pre><code class=\"language-js\">const perform3DSDeviceFingerprint = (responseData) =&gt;\n{\n    const serverTransactionID = responseData.['threeDSServerTransID'];\n    const threeDSMethodURL = responseData.['threeDSMethodURL'];\n    const threedsContainer = document.getElementById('threedsContainer');\n    const dataObj = {\n        threeDSServerTransID : serverTransactionID,\n        threeDSMethodNotificationURL : YOUR_3DS_METHOD_NOTIFICATION_URL\n    };\n    const stringifiedDataObject = JSON.stringify(dataObj);\n    \/\/ Encode data\n    const base64URLencodedData = base64Url.encode(stringifiedDataObject);\n    const IFRAME_NAME = 'threeDSMethodIframe';\n\n    \/\/ Create hidden iframe\n    const iframe = createIframe(threedsContainer, IFRAME_NAME, '0', '0');\n    \/\/ Create a form that will use the iframe to POST data to the threeDSMethodURL\n    const form =  createForm('threedsMethodForm', threeDSMethodURL, IFRAME_NAME, 'threeDSMethodData', base64URLencodedData);\n    threedsContainer.appendChild(form);\n    setTimeout( function () {\n        threedsContainer.removeChild( form );\n    }, 1000 );\n    form.submit();\n};<\/code><\/pre>\n<\/li>\n<li>\n<p>Wait for the issuer's response posted in your\u00a0<code>YOUR_3DS_METHOD_NOTIFICATION_URL<\/code>\u00a0within 10 seconds from sending the HTTP POST. If do not get any response within 10 seconds, proceed to the next step.<\/p>\n<pre><code class=\"language-json\"> {\"threeDSServerTransID\":\"f8062b92-66e9-4c5a-979a-f465e66a6e48\"}<\/code><\/pre>\n<div class=\"sc-notice info\"><div>\n<p>To trigger your front end to remove the iframe after your notification URL receives a response or after 10 seconds has elapsed, see <a href=\"#handling-notification-urls\">Handling the communication from notification URLs to your front end<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<li>\n<p>Make a POST\u00a0\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\/details\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments\/details<\/a>\u00a0request from your server and include the\u00a0<code>threeds2.fingerprint<\/code>\u00a0and the\u00a0<code>paymentData<\/code>\u00a0objects as parameters.<\/p>\n<ul>\n<li><code>threeds2.fingerprint<\/code>: Pass a base64 encoded\u00a0<code>{\"threeDSCompInd\":\"Y\"}<\/code>.<\/li>\n<li><code>paymentData<\/code>:\u00a0Pass the\u00a0<code>paymentData<\/code>\u00a0from the\u00a0<a href=\"#submit-a-payment-request\">initial payment response<\/a>.<\/li>\n<\/ul>\n<div class=\"sc-notice note\"><div>\n<p>If you received a response to\u00a0<code>YOUR_3DS_METHOD_NOTIFICATION_URL<\/code>\u00a0within 10 seconds, send <code>{\"threeDSCompInd\": \"Y\"}<\/code> in a base64url encoded format. Otherwise, send <code>{\"threeDSCompInd\": \"N\"}<\/code>.<\/p>\n<\/div><\/div>\n<\/li>\n<\/ol>\n<h6>Request<\/h6>\n<pre><code class=\"language-json\">{\n  \"details\": {\n    \"threeds2.fingerprint\": \"base64urlencoded_threeDSCompInd\"\n  },\n  \"paymentData\": \"YOUR_PAYMENT_DATA...\"\n}<\/code><\/pre>\n<h6>Response<\/h6>\n<p>You'll receive a response containing a\u00a0<code>resultCode<\/code>:<\/p>\n<ul>\n<li><strong>Authorised<\/strong>\u00a0\u2013\u00a0Indicates that the\u00a03D Secure 2 authentication was frictionless, and the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of goods and services.\u00a0<\/li>\n<li><strong>ChallengeShopper<\/strong>\u00a0\u2013 The issuer has requested further verification of the shopper. See\u00a0<a href=\"#present-a-challenge\">Challenge flow<\/a>.<\/li>\n<\/ul>\n<p>For other possible\u00a0<code>resultCodes<\/code>\u00a0and the actions that you need to take, see\u00a0<a href=\"\/pt\/online-payments\/payment-result-codes\">Result codes<\/a>.<\/p>\n<pre><code class=\"language-json\">{\n  \"resultCode\": \"ChallengeShopper\",\n  \"authentication\": {\n    \"threeds2.challengeToken\": \"eyJ0aH...\"\n  },\n  \"details\": [\n    {\n      \"key\": \"threeds2.challengeResult\",\n      \"type\": \"text\"\n    }\n  ],\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}<\/code><\/pre>\n<h2 id=\"present-a-challenge\">Present a challenge<\/h2>\n<p>If your server receives a\u00a0<strong>ChallengeShopper\u00a0<\/strong><code>resultCode<\/code>,\u00a0this means that the issuer would like to perform additional checks in order to verify that the shopper is indeed the cardholder.<\/p>\n<ol>\n<li>\n<p>Base64 decode the\u00a0<code>threeds2.challengeToken<\/code>\u00a0from the\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments<\/a>\u00a0response.<\/p>\n<pre><code class=\"language-json\">{\n  \"acsReferenceNumber\":\"ADYEN-ACS-SIMULATOR\",\n  \"acsTransID\":\"c9051915-57b0-4079-816c-6bbf1e29acc9\",\n  \"acsURL\":\"https:\\\/\\\/pal-test.adyen.com\\\/threeds2simulator\\\/acs\\\/challenge.shtml\",\n  \"messageVersion\":\"2.1.0\",\n  \"threeDSNotificationURL\":\"https:\\\/\\\/test.com\",\n  \"threeDSServerTransID\":\"24f8457e-dac9-404a-86dc-5c5b8b76d831\"\n}<\/code><\/pre>\n<\/li>\n<li>\n<p>Create a\u00a0<code>cReqData<\/code>\u00a0object and pass on the values of\u00a0<code>threeDSServerTransID<\/code>,\u00a0<code>acsTransID<\/code>,\u00a0<code>messageVersion<\/code>, and\u00a0<code>challengeWindowSize<\/code>.\u00a0<\/p>\n<p>Set the\u00a0<code>challengeWindowSize<\/code>\u00a0to any of the following specifications:<\/p>\n<table style=\"width:100%;\"><colgroup><col style=\"width: 33%\"><col style=\"width: 66%\"><\/colgroup><thead><tr class=\"header\"><th>identifier<\/th><th>size<\/th><\/tr><\/thead><tbody><tr><td>\n<p>01<\/p>\n<\/td><td>\n<p>250px x 400px<\/p>\n<\/td><\/tr><tr><td>\n<p>02<\/p>\n<\/td><td>\n<p>390px x 400px<\/p>\n<\/td><\/tr><tr><td>\n<p>03<\/p>\n<\/td><td>\n<p>500px x 600px<\/p>\n<\/td><\/tr><tr><td>\n<p>04<\/p>\n<\/td><td>\n<p>600px x 400px<\/p>\n<\/td><\/tr><tr><td>\n<p>05<\/p>\n<\/td><td>\n<p>100% x 100%<\/p>\n<\/td><\/tr><\/tbody><\/table>\n<p>Next, base64url encode the <code>CReq<\/code> message, create an iframe, and to create a form that will send an HTTP POST to the <code>acsURL<\/code>.<\/p>\n<pre><code class=\"language-java\">const perform3DSChallenge = (responseData) =&gt;\n {\n    const challengeWindowSize = validateChallengeWindowSize('04');\/\/ Corresponds to a 600px x 400px iframe size\n\n    \/\/ Extract the ACS hosted url that will provide the content for the challenge iframe\n    const acsURL = ['acsURL'];\n\n    \/\/ Collate the data required to make a cReq\n    const cReqData = {\n        threeDSServerTransID : responseData.['threeDSServerTransID'],\n        acsTransID : responseData.['acsTransID'],\n        messageVersion : responseData.['messageVersion'],\n        messageType : 'CReq',\n        challengeWindowSize\n    };\n\n    const stringifiedDataObject = JSON.stringify(cReqData);\n\n    \/\/ Encode data\n    const base64URLencodedData = base64Url.encode(stringifiedDataObject);\n\n    const IFRAME_NAME = 'threeDSChallengeIframe';\n\n    const threedsContainer = document.getElementById('threedsContainer');\n\n    const iframeSizesArr = getChallengeWindowSize(challengeWindowSize);\n\n    \/\/ Create iframe with challenge window dimensions\n    const iframe = createIframe(threedsContainer, IFRAME_NAME, iframeSizesArr[0], iframeSizesArr[1]);\n\n    \/\/ Create a form that will use the iframe to POST data to the acsURL\n    const form =  createForm('cReqForm', acsURL, IFRAME_NAME, 'creq', base64URLencodedData);\n\n    threedsContainer.appendChild(form);\n\n    setTimeout( function () {\n        threedsContainer.removeChild( form );\n    }, 1000 );\n\n    form.submit();\n};<\/code><\/pre>\n<\/li>\n<li>\n<p>Wait for the issuer's response which will be posted to\u00a0<code>YOUR_3DS_NOTIFICATION_URL<\/code>\u00a0within 10 minutes from sending the HTTP POST. The response will contain the Challenge Response (<code>CRes<\/code>) in a base64url encoded format. If you do not get a response within 10 minutes, proceed to the next step.<\/p>\n<pre><code class=\"language-json\">{\"cres\":\"eyJtZXNzYWdlVHlwZSI6IkNSZXMiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI1ZWY2MzBiMC03NmQwLTRmY2It...\"}<\/code><\/pre>\n<p>Base64url decode the response and get the\u00a0<code>transStatus<\/code>\u00a0value.\u00a0<\/p>\n<pre><code class=\"language-json\">{\n  \"messageType\":\"CRes\",\n  \"messageVersion\":\"2.1.0\",\n  \"threeDSServerTransID\":\"5ef630b0-76d0-4fcb-8a17-c81ecc86cff7\",\n  \"acsTransID\":\"1f1bb4cc-05c9-49d0-a82c-e587c914a37b\",\n  \"acsUiType\":\"01\",\n  \"challengeCompletionInd\":\"Y\",\n  \"transStatus\":\"Y\"\n}<\/code><\/pre>\n<div class=\"sc-notice info\"><div>\n<p>To trigger your front end to remove the iframe after your notification URL receives a response or after 10 minutes has elapsed, see\u00a0<a href=\"#handling-notification-urls\">Handling the communication from notification URLs to your front end<\/a>.<\/p>\n<\/div><\/div>\n<\/li>\n<li>\n<p>Make a POST\u00a0\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\/details\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments\/details<\/a>\u00a0request from your server and include the\u00a0<code>details<\/code>\u00a0and the\u00a0<code>paymentData<\/code>\u00a0objects as parameters.<\/p>\n<\/li>\n<\/ol>\n<ul>\n<li><code>threeds2.challengeResult<\/code>: Base64 encode the <code>transStatus<\/code> from the previous step and pass it to this parameter. For example,\u00a0pass a base64 encoded\u00a0<code>{\"transStatus\": \"Y\"}<\/code>.<\/li>\n<li><code>paymentData<\/code>: This is the\u00a0<code>paymentData<\/code>\u00a0from the latest API\u00a0response, either\u00a0from the\u00a0<code>\/payments<\/code>\u00a0or from the\u00a0<code>\/payments\/details<\/code>\u00a0response\u00a0if you are proceeding from the device fingerprinting flow.<\/li>\n<\/ul>\n<div class=\"sc-notice note\"><div>\n<p>If you do not receive a response in\u00a0<code>YOUR_3DS_NOTIFICATION_URL<\/code>\u00a0within 10 minutes, assume that something went wrong or the shopper aborted the transaction. In this case, send\u00a0<code>{\"``transStatus\": \"U\"}<\/code>\u00a0 in a base64 encoded format to Adyen in order to order to finalize the payment.<\/p>\n<\/div><\/div>\n<h6>Request<\/h6>\n<pre><code class=\"language-json\">{\n  \"details\": {\n    \"threeds2.challengeResult\": \"base64urlencoded_transStatus\"\n  },\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}<\/code><\/pre>\n<h6>Response<\/h6>\n<p>You'll receive\u00a0<strong>Authorised<\/strong>\u00a0as the\u00a0<code>resultCode<\/code>\u00a0if the payment was successful.<\/p>\n<pre><code class=\"language-json\">{\n    \"pspReference\": \"8535516988037431\",\n    \"resultCode\": \"Authorised\"\n}<\/code><\/pre>\n<h2 id=\"handling-notification-urls\">Handling the communication from notification URLs to your front end<\/h2>\n<p>The notification URLs\u00a0<code>YOUR_3DS_METHOD_NOTIFICATION_URL<\/code>\u00a0and\u00a0<code>YOUR_METHOD_NOTIFICATION_URL<\/code>\u00a0on your server are the ideal places from where you should perform the next\u00a0 <a href=\"https:\/\/docs.adyen.com\/api-explorer\/Checkout\/latest\/post\/payments\/details\" class=\"codeLabel  external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">\/payments\/details<\/a>\u00a0request. However, you may want to communicate with your front end after performing the device fingerprinting or after presenting a challenge\u00a0in order to hide the iframes and to perform other actions if needed.<\/p>\n<p>In case you do not have an existing implementation for your front end and back end communication, our recommended implementation is to:<\/p>\n<ul>\n<li>Use the\u00a0<code>message<\/code>\u00a0event on the front end to listen to a\u00a0<code>window.postMessage<\/code>\u00a0method from the pages running the iframes at the notification URLs. See sample codes below:<\/li>\n<\/ul>\n<p><strong><br \/>\n<\/strong><\/p>\n<p>Add this in the notification URLs, running within the iframe:<\/p>\n<pre><code class=\"language-js\">&lt;script type=\"text\/javascript\"&gt;\n \/\/ For IdentifyShopper (3DSMethod) flow\n \/\/ NOTE: This redirect of the iframe should have happened within 10 seconds of POST-ing the form to the\n \/\/ threeDSMethodURL otherwise threeDSCompInd should be set to 'N'\n     const data = {\n         type: 'identifyShopper',\n         threeDSCompInd: 'Y'\n     };\n \/\/ For ChallengeShopper flow\n \/\/ NOTE: This redirect of the iframe should have happened within 10 minutes of POST-ing the form\n \/\/ to the acsURL otherwise transStatus should be set to 'U'\n const data = {\n         type: 'challengeShopper',\n         transStatus: 'Y',\n threeDSServerTransID: threeDSServerTransID\n     };\n\n    window.parent.postMessage(data, YOUR_WEBSITE_DOMAIN);\n\n&lt;\/script&gt;<\/code><\/pre>\n<p>Add this in your website:<\/p>\n<pre><code class=\"language-js\">window.addEventListener(\"message\", (e) =&gt;\n{\n    if(e.origin === YOUR_HOSTED_DOMAIN_FOR_THE_NOTIFICATION_URLS){\n        const eventData = e.data;\n        \/\/ IdentifyShopper (3DSMethod) response\n        if(eventData.hasOwnProperty('threeDSCompInd')){\n\n            \/\/ If you haven't already performed the next \/payments\/details call from your notification URL this\n            \/\/ represents a good place to initiate the an API request\n            authorise3DS2RequestAfterIdentifyingShopper(eventData.threeDSCompInd);\n        }\n\n        \/\/ Challenge response\n        if(eventData.hasOwnProperty('transStatus') &amp;&amp; eventData.hasOwnProperty('threeDSServerTransID')){\n\n            \/\/ If you haven't already performed the next \/payments\/details call from your notification URL this\n            \/\/ represents a good place to initiate the an API request\n            authorise3DS2RequestAfterChallenge(eventData.transStatus, eventData.threeDSServerTransID);\n        }\n\n        \/\/ Run code to remove the iframe from the '#threedsContainer' element\n        hideIframe();\n    }\n});<\/code><\/pre>\n<h2 id=\"testing-3d-secure-2\">Testing 3D Secure 2<\/h2>\n<p>To test how your integration handles different 3D Secure 2 authentication scenarios, you need to use a card number for the specific flow.<\/p>\n<p>When prompted for 3D Secure 2 text challenges, use the following credentials to authenticate:<\/p>\n<ul>\n<li>For native mobile integrations, use password: <strong>1234<\/strong><\/li>\n<li>For web and mobile browser integrations, use password: <strong>password<\/strong><\/li>\n<\/ul>\n<p>Depending on the <a href=\"\/pt\/online-payments\/3d-secure\/#implementation-options\">authentication option<\/a>, you can receive the following result codes:<\/p>\n<ul>\n<li><strong>RedirectShopper<\/strong>: you receive this result code if you are using the <a href=\"\/pt\/online-payments\/3d-secure\/redirect-3ds2\">Redirect authentication<\/a> flow.<\/li>\n<li><strong>IdentifyShopper<\/strong>: you receive this result code if you are using the <a href=\"\/pt\/online-payments\/3d-secure\/native-3ds2\/\">Native authentication<\/a> flow.<\/li>\n<li><strong>ChallengeShopper<\/strong>: you receive this result code after you submit the 3D Secure 2 device fingerprinting result in a Native authentication, unless you specify a <a href=\"\/pt\/online-payments\/3d-secure\/#frictionless-flow\">frictionless<\/a> flow.<\/li>\n<\/ul>\n<p>Depending on your integration, use the following test cards to simulate different authentication flows.<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Card Type<\/th>\n<th style=\"text-align: left;\">Card Number<\/th>\n<th style=\"text-align: left;\">Expiry Date<\/th>\n<th style=\"text-align: center;\">Security Code (CVC\/CVV\/CID)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">American Express<\/td>\n<td style=\"text-align: left;\">3714 4963 5398 431<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">7373<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Bancontact \/ Maestro<\/td>\n<td style=\"text-align: left;\">6703 4444 4444 4449<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Bancontact \/ Visa<\/td>\n<td style=\"text-align: left;\">4871 0499 9999 9910<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Cartes Bancaires \/ Visa Debit<\/td>\n<td style=\"text-align: left;\">4035 5014 2814 6300<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Cartes Bancaires<\/td>\n<td style=\"text-align: left;\">4360 0000 0100 0005<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">China UnionPay (Credit)<\/td>\n<td style=\"text-align: left;\">6250 9470 0000 0014<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">123<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">China UnionPay (Debit)<\/td>\n<td style=\"text-align: left;\">6250 9460 0000 0016<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">123<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Diners<\/td>\n<td style=\"text-align: left;\">3056 9309 0259 04<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Discover<\/td>\n<td style=\"text-align: left;\">6011 1111 1111 1117<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Maestro<\/td>\n<td style=\"text-align: left;\">5000 5500 0000 0029<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\"><em>n\/a<\/em><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Mastercard<\/td>\n<td style=\"text-align: left;\">5454 5454 5454 5454<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Mastercard Credit<\/td>\n<td style=\"text-align: left;\">2222 4000 1000 0008<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Visa<\/td>\n<td style=\"text-align: left;\">4917 6100 0000 0000<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">Visa Classic<\/td>\n<td style=\"text-align: left;\">4166 6766 6766 6746<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Challenge without fingerprint<\/h4>\n<p>To test the web-based flow where the device fingerprinting step is skipped (because the issuer's ACS has not configured a <code>threeDSMethodURL<\/code>), and you get a <strong>ChallengeShopper<\/strong> <code>resultCode<\/code> <em>immediately<\/em> after submitting the payment request, use the following card:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Card Type<\/th>\n<th style=\"text-align: left;\">Card Number<\/th>\n<th style=\"text-align: left;\">Expiry Date<\/th>\n<th style=\"text-align: center;\">Security Code (CVC\/CVV\/CID)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">Visa<\/td>\n<td style=\"text-align: left;\">4212 3456 7891 0006<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: center;\">737<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Fingerprint without challenge<\/h4>\n<p>To test the <a href=\"\/pt\/online-payments\/3d-secure\/#frictionless-flow\">frictionless flow<\/a>, in which you perform a fingerprint but no challenge, use the following test card number:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Card number<\/th>\n<th style=\"text-align: left;\">Expiry Date<\/th>\n<th style=\"text-align: left;\">Security Code (CVC\/CVV\/CID)<\/th>\n<th style=\"text-align: left;\">Authentication scenario<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">5201 2815 0512 9736<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Fingerprint but no challenge<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4 id=\"app-based-integration\">Native authentication<\/h4>\n<p>To test authentication scenarios for native mobile (app-based) integrations, use the following test cards:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Card number<\/th>\n<th style=\"text-align: left;\">Expiry Date<\/th>\n<th style=\"text-align: left;\">Security Code (CVC\/CVV\/CID)<\/th>\n<th style=\"text-align: left;\">Authentication scenario<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">5201 2855 6567 2311<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Basic text authentication<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">5201 2874 9905 2008<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Basic single select<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">5201 2815 9233 1633<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Basic multi select<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">5201 2888 2269 6974<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Basic out-of-band (OOB) authentication<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">5201 2895 0084 3268<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">HTML out-of-band (OOB) authentication<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">5201 2861 5377 1465<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">App single select then text authentication<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">4917 6100 0000 0042<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Advanced: ACS sends an empty Challenge Response (<code>CRes<\/code>)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">4917 6100 0000 0067<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Advanced: Invalid content in the <code>acsSignedContent<\/code> field in Authentication Response (<code>ARes<\/code>)<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left;\">4917 6100 0000 0059<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Advanced: Challenge Response (<code>CRes<\/code>) timeout<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Technical error<\/h4>\n<p>To test simulate an error due to a timeout during the 3D Secure 2 authentication on the issuer side, use the following test card:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: left;\">Card number<\/th>\n<th style=\"text-align: left;\">Expiry Date<\/th>\n<th style=\"text-align: left;\">Security Code (CVC\/CVV\/CID)<\/th>\n<th style=\"text-align: left;\">Scenario<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: left;\">5201 2829 9900 5515<\/td>\n<td style=\"text-align: left;\">03\/2030<\/td>\n<td style=\"text-align: left;\">737<\/td>\n<td style=\"text-align: left;\">Depending on your configuration, the transaction might still proceed to a successful authorization.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>","url":"https:\/\/docs.adyen.com\/pt\/checkout-build-your-own-3ds2\/checkout-api-helper-functions","articleFields":{"description":"Simplify your 3D Secure 2 API implementation with our helper functions.","home_description":"","id":"47485981","type":"page","_expandable":{"operations":""},"status":"current","last_edit_on":"27-05-2019 18:00"},"algolia":{"url":"https:\/\/docs.adyen.com\/pt\/checkout-build-your-own-3ds2\/checkout-api-helper-functions","title":"Helper functions","content":"Use our helper functions to:\n\nCollect browser info and store data in properties required in the EMVCo specifications.\nPerform base64url encoding and decoding.\nCreate an iframe with an onload event listener for the 3D Secure 2 device fingerprinting and challenge results.\nCreate a form with a target attribute to send the issuer requests for 3D Secure 2 device fingerprinting and the challenge.\nConfigure the challenge window size according to the EMVCo specifications.\n\nBefore\u00a0you begin\nBefore you begin to integrate, make sure you have followed the Get started with Adyen guide to:\n\nGet an overview of the steps needed to accept live payments.\nCreate your test account.\n\nAfter you have created your test account:\n\n\nGet your API Key. Save a copy\u00a0as you'll need it for API calls you make to the Adyen payments platform.\n\n\nInstall one of our\u00a0Libraries\u00a0to connect with the Adyen APIs. For more information on these steps, refer to\u00a0Get started with Adyen.\n\n\nRead and understand the\u00a0API-only integration guide. You should already know how to collect shopper information, either with the\u00a0Card component\u00a0or with your\u00a0own payment form implementation.\n\n\nSet up your notification URLs. The issuer will send an HTTP POST containing the 3D Secure 2 device fingerprinting process and the challenge result to these URLs.\n\nYOUR_3DS_METHOD_NOTIFICATION_URL: Absolute URL\u00a0to where the issuer can post the result of the 3D Secure device fingerprinting process.\u00a0\nYOUR_3DS_NOTIFICATION_URL: Absolute URL to where the issuer can post a base64url encoded Challenge Response (CRes)\u00a0message, containing the challenge result.\n\n\n\nImport our helper functions by:\n\n\nCloning our repository from\u00a0https:\/\/github.com\/Adyen\/adyen-3ds2-js-utils\u00a0and importing the files into your project.\u00a0\nimport collectBrowserInfo from \".\/browser\";\nimport base64Url from \".\/base64url\";\nimport createIframe from \".\/iframe\";\nimport createForm from \".\/form\";\nimport {validateChallengeWindowSize, getChallengeWindowSize} from \".\/config.js\";\n\n\nOr by building the file, hosting it, and then embedding it in your page.\u00a0\n&lt;script type=\"text\/javascript\" src=\"YOUR_PATH\/threeds2-js-utils.js\"&gt;\n\n\n\n\nCollect the shopper's browser information\nThe\u00a0browserInfo\u00a0object is required when submitting a 3D Secure 2 payment request. To get the required values for the transaction, use the\u00a0collectBrowserInfo\u00a0function. Pass on the values to your server.\nconst browserInf = collectBrowserInfo();\nconst requestObj =\n{\n    browserInfo         : {\n        \"acceptHeader\"  : \"TO BE ADDED BY SERVER\",\n        \"colorDepth\"    : browserInf.colorDepth,\n        \"javaEnabled\"   : browserInf.javaEnabled,\n        \"language\"      : browserInf.language,\n        \"screenHeight\"  : browserInf.screenHeight,\n        \"screenWidth\"   : browserInf.screenWidth,\n        \"timeZoneOffset\": browserInf.timeZoneOffset,\n        \"userAgent\"     : browserInf.userAgent\n};\nSubmit a payment request\nSubmit a payment request with a POST\u00a0 \/payments\u00a0call. Include the\u00a0following\u00a0to indicate that you are ready to accept 3D Secure 2 payments:\n\nchannel: web\nauthenticationData.threeDSRequestData.nativeThreeDS:\u00a0preferred\nbrowserInfo: Collect information about your shopper's browser.\nthreeDS2RequestData.notificationURL:\u00a0YOUR_3DS_NOTIFICATION_URL\n\n\nTo increase the likelihood of achieving a frictionless flow and higher authorisation rates, we also recommend that you send additional parameters in this list.\n\nRequest\ncurl https:\/\/checkout-test.adyen.com\/v66\/payments \\\n-H 'X-API-key: [Your API Key here]' \\\n-H 'content-type: application\/json' \\\n-d '{\n   \"amount\":{\n      \"currency\":\"EUR\",\n      \"value\":1500\n   },\n   \"merchantAccount\":\"YOUR_MERCHANT_ACCOUNT\",\n   \"reference\":\"TEST\",\n   \"channel\": \"web\",\n   \"threeDS2RequestData\": {\n      \"notificationURL\":\"YOUR_3DS_NOTIFICATION_URL\"\n   },\n   \"authenticationData\": {\n      \"threeDSRequestData\": {\n        \"nativeThreeDS\": \"preferred\"\n      }\n   },\n   \"returnUrl\":\"https:\/\/your-company.example.com\/checkout\/\",\n   \"browserInfo\":{\n      \"userAgent\":\"Mozilla\\\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\\\/537.36 (KHTML, like Gecko) Chrome\\\/70.0.3538.110 Safari\\\/537.36\",\n      \"acceptHeader\":\"text\\\/html,application\\\/xhtml+xml,application\\\/xml;q=0.9,image\\\/webp,image\\\/apng,*\\\/*;q=0.8\",\n      \"language\":\"en\",\n      \"colorDepth\":24,\n      \"screenHeight\":723,\n      \"screenWidth\":1536,\n      \"timeZoneOffset\":0,\n      \"javaEnabled\":false\n  },\n   \"paymentMethod\":{\n      \"type\":\"scheme\",\n      \"encryptedCardNumber\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedExpiryMonth\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedExpiryYear\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\",\n      \"encryptedSecurityCode\":\"adyenjs_0_1_18$MT6ppy0FAMVMLH...\"\n  },\n  \"reference\":\"YOUR_ORDER_NUMBER\"\n}'\nResponse\nYou'll receive a response containing:\n\nresultCode:\u00a0IdentifyShopper\u00a0or\u00a0ChallengeShopper. Perform the corresponding\u00a03D Secure 2 device fingerprinting\u00a0or\u00a0Present a challenge\u00a0flows.\u00a0If the transaction is exempted from 3D Secure 2, you might get an\u00a0Authorised\u00a0resultCode.\u00a0\nthreeds2.fingerprintToken\u00a0or\u00a0threeds2.challengeToken: Use this to start the\u00a0corresponding\u00a0Identify the shopper\u00a0or\u00a0Challenge the shopper\u00a0flows.\u00a0\npaymentData: Use this for your succeeding POST\u00a0 \/paymentsrequest.\n\n\u00a0For other possible\u00a0resultCodes, and the actions that you need to take, see\u00a0the\u00a0Result codes.\n{\n  \"resultCode\": \"IdentifyShopper\",\n  \"authentication\": {\n    \"threeds2.fingerprintToken\": \"eyJ0aHJlZURTTWV0aG9kVXJsIjoiaHR0cHM6XC9cL...\"\n  },\n  \"details\": [\n    {\n      \"key\": \"threeds2.fingerprint\",\n      \"type\": \"text\"\n    }\n  ],\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}\nGet the 3D Secure 2 device fingerprint\nIf your server receives an\u00a0 IdentifyShopper resultCode,\u00a0you are required to perform the 3D Secure 2 device fingerprinting.\n\n\nBase64 decode the\u00a0threeds2.fingerprintToken\u00a0from the\u00a0 \/payments\u00a0response.\u00a0\n{\n   \"threeDSMethodUrl\":\"https:\\\/\\\/pal-test.adyen.com\\\/threeds2simulator\\\/acs\\\/startMethod.shtml\",\n   \"threeDSServerTransID\":\"c9f82ec0-9e24-4f79-834d-6f8282de92fa\"\n}\n\n\nCreate objects and pass on the values of\u00a0threeDSServerTransID\u00a0and\u00a0YOUR_3DS_METHOD_NOTIFICATION_URL. Next, use helper functions to base64url encode the data, create an iframe, and create a form that will send an HTTP POST to the\u00a0threeDSMethodURL.\nconst perform3DSDeviceFingerprint = (responseData) =&gt;\n{\n    const serverTransactionID = responseData.['threeDSServerTransID'];\n    const threeDSMethodURL = responseData.['threeDSMethodURL'];\n    const threedsContainer = document.getElementById('threedsContainer');\n    const dataObj = {\n        threeDSServerTransID : serverTransactionID,\n        threeDSMethodNotificationURL : YOUR_3DS_METHOD_NOTIFICATION_URL\n    };\n    const stringifiedDataObject = JSON.stringify(dataObj);\n    \/\/ Encode data\n    const base64URLencodedData = base64Url.encode(stringifiedDataObject);\n    const IFRAME_NAME = 'threeDSMethodIframe';\n\n    \/\/ Create hidden iframe\n    const iframe = createIframe(threedsContainer, IFRAME_NAME, '0', '0');\n    \/\/ Create a form that will use the iframe to POST data to the threeDSMethodURL\n    const form =  createForm('threedsMethodForm', threeDSMethodURL, IFRAME_NAME, 'threeDSMethodData', base64URLencodedData);\n    threedsContainer.appendChild(form);\n    setTimeout( function () {\n        threedsContainer.removeChild( form );\n    }, 1000 );\n    form.submit();\n};\n\n\nWait for the issuer's response posted in your\u00a0YOUR_3DS_METHOD_NOTIFICATION_URL\u00a0within 10 seconds from sending the HTTP POST. If do not get any response within 10 seconds, proceed to the next step.\n {\"threeDSServerTransID\":\"f8062b92-66e9-4c5a-979a-f465e66a6e48\"}\n\nTo trigger your front end to remove the iframe after your notification URL receives a response or after 10 seconds has elapsed, see Handling the communication from notification URLs to your front end.\n\n\n\nMake a POST\u00a0\u00a0 \/payments\/details\u00a0request from your server and include the\u00a0threeds2.fingerprint\u00a0and the\u00a0paymentData\u00a0objects as parameters.\n\nthreeds2.fingerprint: Pass a base64 encoded\u00a0{\"threeDSCompInd\":\"Y\"}.\npaymentData:\u00a0Pass the\u00a0paymentData\u00a0from the\u00a0initial payment response.\n\n\nIf you received a response to\u00a0YOUR_3DS_METHOD_NOTIFICATION_URL\u00a0within 10 seconds, send {\"threeDSCompInd\": \"Y\"} in a base64url encoded format. Otherwise, send {\"threeDSCompInd\": \"N\"}.\n\n\n\nRequest\n{\n  \"details\": {\n    \"threeds2.fingerprint\": \"base64urlencoded_threeDSCompInd\"\n  },\n  \"paymentData\": \"YOUR_PAYMENT_DATA...\"\n}\nResponse\nYou'll receive a response containing a\u00a0resultCode:\n\nAuthorised\u00a0\u2013\u00a0Indicates that the\u00a03D Secure 2 authentication was frictionless, and the payment authorisation was successfully completed. This state serves as an indicator to proceed with the delivery of goods and services.\u00a0\nChallengeShopper\u00a0\u2013 The issuer has requested further verification of the shopper. See\u00a0Challenge flow.\n\nFor other possible\u00a0resultCodes\u00a0and the actions that you need to take, see\u00a0Result codes.\n{\n  \"resultCode\": \"ChallengeShopper\",\n  \"authentication\": {\n    \"threeds2.challengeToken\": \"eyJ0aH...\"\n  },\n  \"details\": [\n    {\n      \"key\": \"threeds2.challengeResult\",\n      \"type\": \"text\"\n    }\n  ],\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}\nPresent a challenge\nIf your server receives a\u00a0ChallengeShopper\u00a0resultCode,\u00a0this means that the issuer would like to perform additional checks in order to verify that the shopper is indeed the cardholder.\n\n\nBase64 decode the\u00a0threeds2.challengeToken\u00a0from the\u00a0 \/payments\u00a0response.\n{\n  \"acsReferenceNumber\":\"ADYEN-ACS-SIMULATOR\",\n  \"acsTransID\":\"c9051915-57b0-4079-816c-6bbf1e29acc9\",\n  \"acsURL\":\"https:\\\/\\\/pal-test.adyen.com\\\/threeds2simulator\\\/acs\\\/challenge.shtml\",\n  \"messageVersion\":\"2.1.0\",\n  \"threeDSNotificationURL\":\"https:\\\/\\\/test.com\",\n  \"threeDSServerTransID\":\"24f8457e-dac9-404a-86dc-5c5b8b76d831\"\n}\n\n\nCreate a\u00a0cReqData\u00a0object and pass on the values of\u00a0threeDSServerTransID,\u00a0acsTransID,\u00a0messageVersion, and\u00a0challengeWindowSize.\u00a0\nSet the\u00a0challengeWindowSize\u00a0to any of the following specifications:\nidentifiersize\n01\n\n250px x 400px\n\n02\n\n390px x 400px\n\n03\n\n500px x 600px\n\n04\n\n600px x 400px\n\n05\n\n100% x 100%\n\nNext, base64url encode the CReq message, create an iframe, and to create a form that will send an HTTP POST to the acsURL.\nconst perform3DSChallenge = (responseData) =&gt;\n {\n    const challengeWindowSize = validateChallengeWindowSize('04');\/\/ Corresponds to a 600px x 400px iframe size\n\n    \/\/ Extract the ACS hosted url that will provide the content for the challenge iframe\n    const acsURL = ['acsURL'];\n\n    \/\/ Collate the data required to make a cReq\n    const cReqData = {\n        threeDSServerTransID : responseData.['threeDSServerTransID'],\n        acsTransID : responseData.['acsTransID'],\n        messageVersion : responseData.['messageVersion'],\n        messageType : 'CReq',\n        challengeWindowSize\n    };\n\n    const stringifiedDataObject = JSON.stringify(cReqData);\n\n    \/\/ Encode data\n    const base64URLencodedData = base64Url.encode(stringifiedDataObject);\n\n    const IFRAME_NAME = 'threeDSChallengeIframe';\n\n    const threedsContainer = document.getElementById('threedsContainer');\n\n    const iframeSizesArr = getChallengeWindowSize(challengeWindowSize);\n\n    \/\/ Create iframe with challenge window dimensions\n    const iframe = createIframe(threedsContainer, IFRAME_NAME, iframeSizesArr[0], iframeSizesArr[1]);\n\n    \/\/ Create a form that will use the iframe to POST data to the acsURL\n    const form =  createForm('cReqForm', acsURL, IFRAME_NAME, 'creq', base64URLencodedData);\n\n    threedsContainer.appendChild(form);\n\n    setTimeout( function () {\n        threedsContainer.removeChild( form );\n    }, 1000 );\n\n    form.submit();\n};\n\n\nWait for the issuer's response which will be posted to\u00a0YOUR_3DS_NOTIFICATION_URL\u00a0within 10 minutes from sending the HTTP POST. The response will contain the Challenge Response (CRes) in a base64url encoded format. If you do not get a response within 10 minutes, proceed to the next step.\n{\"cres\":\"eyJtZXNzYWdlVHlwZSI6IkNSZXMiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI1ZWY2MzBiMC03NmQwLTRmY2It...\"}\nBase64url decode the response and get the\u00a0transStatus\u00a0value.\u00a0\n{\n  \"messageType\":\"CRes\",\n  \"messageVersion\":\"2.1.0\",\n  \"threeDSServerTransID\":\"5ef630b0-76d0-4fcb-8a17-c81ecc86cff7\",\n  \"acsTransID\":\"1f1bb4cc-05c9-49d0-a82c-e587c914a37b\",\n  \"acsUiType\":\"01\",\n  \"challengeCompletionInd\":\"Y\",\n  \"transStatus\":\"Y\"\n}\n\nTo trigger your front end to remove the iframe after your notification URL receives a response or after 10 minutes has elapsed, see\u00a0Handling the communication from notification URLs to your front end.\n\n\n\nMake a POST\u00a0\u00a0 \/payments\/details\u00a0request from your server and include the\u00a0details\u00a0and the\u00a0paymentData\u00a0objects as parameters.\n\n\n\nthreeds2.challengeResult: Base64 encode the transStatus from the previous step and pass it to this parameter. For example,\u00a0pass a base64 encoded\u00a0{\"transStatus\": \"Y\"}.\npaymentData: This is the\u00a0paymentData\u00a0from the latest API\u00a0response, either\u00a0from the\u00a0\/payments\u00a0or from the\u00a0\/payments\/details\u00a0response\u00a0if you are proceeding from the device fingerprinting flow.\n\n\nIf you do not receive a response in\u00a0YOUR_3DS_NOTIFICATION_URL\u00a0within 10 minutes, assume that something went wrong or the shopper aborted the transaction. In this case, send\u00a0{\"``transStatus\": \"U\"}\u00a0 in a base64 encoded format to Adyen in order to order to finalize the payment.\n\nRequest\n{\n  \"details\": {\n    \"threeds2.challengeResult\": \"base64urlencoded_transStatus\"\n  },\n  \"paymentData\": \"YOUR_PAYMENT_DATA\"\n}\nResponse\nYou'll receive\u00a0Authorised\u00a0as the\u00a0resultCode\u00a0if the payment was successful.\n{\n    \"pspReference\": \"8535516988037431\",\n    \"resultCode\": \"Authorised\"\n}\nHandling the communication from notification URLs to your front end\nThe notification URLs\u00a0YOUR_3DS_METHOD_NOTIFICATION_URL\u00a0and\u00a0YOUR_METHOD_NOTIFICATION_URL\u00a0on your server are the ideal places from where you should perform the next\u00a0 \/payments\/details\u00a0request. However, you may want to communicate with your front end after performing the device fingerprinting or after presenting a challenge\u00a0in order to hide the iframes and to perform other actions if needed.\nIn case you do not have an existing implementation for your front end and back end communication, our recommended implementation is to:\n\nUse the\u00a0message\u00a0event on the front end to listen to a\u00a0window.postMessage\u00a0method from the pages running the iframes at the notification URLs. See sample codes below:\n\n\n\nAdd this in the notification URLs, running within the iframe:\n&lt;script type=\"text\/javascript\"&gt;\n \/\/ For IdentifyShopper (3DSMethod) flow\n \/\/ NOTE: This redirect of the iframe should have happened within 10 seconds of POST-ing the form to the\n \/\/ threeDSMethodURL otherwise threeDSCompInd should be set to 'N'\n     const data = {\n         type: 'identifyShopper',\n         threeDSCompInd: 'Y'\n     };\n \/\/ For ChallengeShopper flow\n \/\/ NOTE: This redirect of the iframe should have happened within 10 minutes of POST-ing the form\n \/\/ to the acsURL otherwise transStatus should be set to 'U'\n const data = {\n         type: 'challengeShopper',\n         transStatus: 'Y',\n threeDSServerTransID: threeDSServerTransID\n     };\n\n    window.parent.postMessage(data, YOUR_WEBSITE_DOMAIN);\n\n&lt;\/script&gt;\nAdd this in your website:\nwindow.addEventListener(\"message\", (e) =&gt;\n{\n    if(e.origin === YOUR_HOSTED_DOMAIN_FOR_THE_NOTIFICATION_URLS){\n        const eventData = e.data;\n        \/\/ IdentifyShopper (3DSMethod) response\n        if(eventData.hasOwnProperty('threeDSCompInd')){\n\n            \/\/ If you haven't already performed the next \/payments\/details call from your notification URL this\n            \/\/ represents a good place to initiate the an API request\n            authorise3DS2RequestAfterIdentifyingShopper(eventData.threeDSCompInd);\n        }\n\n        \/\/ Challenge response\n        if(eventData.hasOwnProperty('transStatus') &amp;&amp; eventData.hasOwnProperty('threeDSServerTransID')){\n\n            \/\/ If you haven't already performed the next \/payments\/details call from your notification URL this\n            \/\/ represents a good place to initiate the an API request\n            authorise3DS2RequestAfterChallenge(eventData.transStatus, eventData.threeDSServerTransID);\n        }\n\n        \/\/ Run code to remove the iframe from the '#threedsContainer' element\n        hideIframe();\n    }\n});\nTesting 3D Secure 2\nTo test how your integration handles different 3D Secure 2 authentication scenarios, you need to use a card number for the specific flow.\nWhen prompted for 3D Secure 2 text challenges, use the following credentials to authenticate:\n\nFor native mobile integrations, use password: 1234\nFor web and mobile browser integrations, use password: password\n\nDepending on the authentication option, you can receive the following result codes:\n\nRedirectShopper: you receive this result code if you are using the Redirect authentication flow.\nIdentifyShopper: you receive this result code if you are using the Native authentication flow.\nChallengeShopper: you receive this result code after you submit the 3D Secure 2 device fingerprinting result in a Native authentication, unless you specify a frictionless flow.\n\nDepending on your integration, use the following test cards to simulate different authentication flows.\n\n\n\nCard Type\nCard Number\nExpiry Date\nSecurity Code (CVC\/CVV\/CID)\n\n\n\n\nAmerican Express\n3714 4963 5398 431\n03\/2030\n7373\n\n\nBancontact \/ Maestro\n6703 4444 4444 4449\n03\/2030\n\n\n\nBancontact \/ Visa\n4871 0499 9999 9910\n03\/2030\n737\n\n\nCartes Bancaires \/ Visa Debit\n4035 5014 2814 6300\n03\/2030\n737\n\n\nCartes Bancaires\n4360 0000 0100 0005\n03\/2030\n737\n\n\nChina UnionPay (Credit)\n6250 9470 0000 0014\n03\/2030\n123\n\n\nChina UnionPay (Debit)\n6250 9460 0000 0016\n03\/2030\n123\n\n\nDiners\n3056 9309 0259 04\n03\/2030\n737\n\n\nDiscover\n6011 1111 1111 1117\n03\/2030\n737\n\n\nMaestro\n5000 5500 0000 0029\n03\/2030\nn\/a\n\n\nMastercard\n5454 5454 5454 5454\n03\/2030\n737\n\n\nMastercard Credit\n2222 4000 1000 0008\n03\/2030\n737\n\n\nVisa\n4917 6100 0000 0000\n03\/2030\n737\n\n\nVisa Classic\n4166 6766 6766 6746\n03\/2030\n737\n\n\n\nChallenge without fingerprint\nTo test the web-based flow where the device fingerprinting step is skipped (because the issuer's ACS has not configured a threeDSMethodURL), and you get a ChallengeShopper resultCode immediately after submitting the payment request, use the following card:\n\n\n\nCard Type\nCard Number\nExpiry Date\nSecurity Code (CVC\/CVV\/CID)\n\n\n\n\nVisa\n4212 3456 7891 0006\n03\/2030\n737\n\n\n\nFingerprint without challenge\nTo test the frictionless flow, in which you perform a fingerprint but no challenge, use the following test card number:\n\n\n\nCard number\nExpiry Date\nSecurity Code (CVC\/CVV\/CID)\nAuthentication scenario\n\n\n\n\n5201 2815 0512 9736\n03\/2030\n737\nFingerprint but no challenge\n\n\n\nNative authentication\nTo test authentication scenarios for native mobile (app-based) integrations, use the following test cards:\n\n\n\nCard number\nExpiry Date\nSecurity Code (CVC\/CVV\/CID)\nAuthentication scenario\n\n\n\n\n5201 2855 6567 2311\n03\/2030\n737\nBasic text authentication\n\n\n5201 2874 9905 2008\n03\/2030\n737\nBasic single select\n\n\n5201 2815 9233 1633\n03\/2030\n737\nBasic multi select\n\n\n5201 2888 2269 6974\n03\/2030\n737\nBasic out-of-band (OOB) authentication\n\n\n5201 2895 0084 3268\n03\/2030\n737\nHTML out-of-band (OOB) authentication\n\n\n5201 2861 5377 1465\n03\/2030\n737\nApp single select then text authentication\n\n\n4917 6100 0000 0042\n03\/2030\n737\nAdvanced: ACS sends an empty Challenge Response (CRes)\n\n\n4917 6100 0000 0067\n03\/2030\n737\nAdvanced: Invalid content in the acsSignedContent field in Authentication Response (ARes)\n\n\n4917 6100 0000 0059\n03\/2030\n737\nAdvanced: Challenge Response (CRes) timeout\n\n\n\nTechnical error\nTo test simulate an error due to a timeout during the 3D Secure 2 authentication on the issuer side, use the following test card:\n\n\n\nCard number\nExpiry Date\nSecurity Code (CVC\/CVV\/CID)\nScenario\n\n\n\n\n5201 2829 9900 5515\n03\/2030\n737\nDepending on your configuration, the transaction might still proceed to a successful authorization.\n\n\n","type":"page","locale":"pt","boost":18,"hierarchy":{"lvl0":"Home","lvl1":"Build your own 3D Secure 2 implementation","lvl2":"Helper functions"},"hierarchy_url":{"lvl0":"https:\/\/docs.adyen.com\/pt","lvl1":"https:\/\/docs.adyen.com\/pt\/checkout-build-your-own-3ds2","lvl2":"\/pt\/checkout-build-your-own-3ds2\/checkout-api-helper-functions"},"levels":3,"category":"","category_color":"","tags":["Helper","functions"]}}
