--- title: "3D Secure 2 API integration" description: "Support 3D Secure 2 authentication for web and in-app transactions with your online payments integration." url: "https://docs.adyen.com/online-payments/3d-secure/native-3ds2/api-integration" source_url: "https://docs.adyen.com/online-payments/3d-secure/native-3ds2/api-integration.md" canonical: "https://docs.adyen.com/online-payments/3d-secure/native-3ds2/api-integration" last_modified: "2019-09-24T17:28:00+02:00" language: "en" --- # 3D Secure 2 API integration Support 3D Secure 2 authentication for web and in-app transactions with your online payments integration. [View source](/online-payments/3d-secure/native-3ds2/api-integration.md) This page describes 3D Secure 2 integration steps for version 46 or earlier of the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) endpoint. If you are using a later version, refer [Native 3D Secure 2 authentication](/online-payments/3d-secure/native-3ds2). ## How it works If you are using 3D Secure for PSD2 compliance, read our [comprehensive PSD2 SCA guide](/online-payments/psd2-sca-compliance-and-implementation-guide). A payment qualified for 3D Secure 2 can go through either a frictionless or a challenge authentication flow before it is authorised. To simplify your implementation, use our web, Android, or iOS 3D Secure 2 Component in addition to your existing API integration. Components are our pre-built modules that you can use to perform specific functions such as 3D Secure 2 authentication. To implement, submit API requests from your backend and then use our 3D Secure 2 Component to: * Handle the device fingerprinting and challenge flows, including the data exchange between your front end or client and the issuer's Access Control Server (ACS). * Return the device fingerprinting and the challenge flow result. If you do not want to use the 3D Secure 2 Component and want to build the web-based implementation on your own, see [Build your own 3D Secure 2 implementation](/checkout-build-your-own-3ds2). You can also choose to [prefetch 3D Secure 2 device fingerprinting keys](/checkout-build-your-own-3ds2#optional-prefetch-device-fingerprinting-keys) to reduce the number of calls for each transaction. For an app-based implementation, we recommend that you use our 3D Secure 2 Android or iOS Component. Both our Android and iOS 3D Secure 2 Component implementations are approved and certified by EMVCo. If you want to build your own 3D Secure 2 mobile implementation, you will need to get an EMVCo certification. 3D Secure 2 is supported from v41 and later of [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) and [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) endpoints. If you only want to perform a 3D Secure 2 authentication and then authorise the payment later, see the [Authentication-only](/online-payments/3d-secure/standalone-authentication) integration page. Here's a diagram for a 3D Secure 2 full implementation with the 3D Secure 2 Component: ![3D Secure 2 authentication flow diagram showing the payment request, device fingerprinting, and challenge steps between shopper, merchant, Adyen, and issuer](/user/pages/docs/02.online-payments/19.3d-secure/01.native-3ds2/10.api-integration/3ds2-checkout-api.png) * [Submit a payment request](#submit-a-payment-request) with the required 3D Secure 2 objects to start the authentication process. Build your implementation depending on the `resultCode` returned in the response. * [Get the 3D Secure 2 device fingerprint](#get-the-3d-secure-2-device-fingerprint). If you receive an **IdentifyShopper** `resultCode`, you need to get the shopper's 3D Secure 2 device fingerprint. Initialize the 3D Secure 2 Component for device fingerprinting and submit the result to Adyen. If after submitting the result you get a response with an **Authorised** `resultCode`, this indicates that the transaction was authenticated in a **frictionless flow**, and the payment was successfully completed. * [Present a challenge to the shopper](#present-a-challenge). If you receive **ChallengeShopper** `resultCode`, this means that the issuer requires further shopper interaction and is initiating a **challenge flow**. In a web-based integration, this result code can be returned after you submit a payment request or after you submit the device fingerprint result to Adyen, depending on the logic on the issuer's side. To handle a challenge flow, initialize the 3D Secure 2 Component for the challenge flow and submit the result to Adyen. Based on issuer performance, Adyen's [Authentication Engine](https://www.adyen.com/knowledge-hub/psd2-simplified-with-our-new-authentication-engine) might also route payments to the 3D Secure 2 redirect flow. This is indicated by a **RedirectShopper** `resultCode` response. For more information, refer to [Payments routed to 3D Secure 1](/online-payments/3d-secure/native-3ds2#payments-routed-to-redirect-flow). For a complete list of `resultCode` values and the actions that you need to take, see [Result codes](/checkout/payment-result-codes). ## Before you begin Before you begin to integrate, make sure you have followed the [Get started with Adyen guide](/get-started-with-adyen) to: * Get an overview of the steps needed to accept live payments. * Create your test account. After you have created your test account: 1. [Get your API Key](/development-resources/api-credentials#generate-api-key). Save a copy as you'll need it for API calls you make to the Adyen payments platform. 2. Read and understand the [Components integration](/online-payments/build-your-integration/sessions-flow) guide. You should already know how to collect shopper information, either with the [Card component](/payment-methods/cards) or with your [own payment form](/online-payments/build-your-integration/advanced-flow) implementation. 3. Install the 3D Secure Component depending on your current integration: * If you are using **Adyen iOS and Adyen Android version 3.0.0 and later**: Use the 3D Secure 2 Action Components for [iOS](/online-payments/3d-secure/native-3ds2) or [Android](/online-payments/3d-secure/native-3ds2). * If you are using **Adyen iOS and Adyen Android version 2.x.x and earlier**: Use the 3D Secure 2 Components described on this page. ### Install 3D Secure 2 Component for Adyen iOS version 2.6.0 to 2.8.4 Import the iOS 3D Secure 2 Component to your project using either CocoaPods or Carthage: **CocoaPods** 1. Add `pod 'Adyen'` to your `Podfile`. 2. Run `pod install`. **Carthage** 1. Add `github "adyen/adyen-ios"` to your `Cartfile`. 2. Run `carthage update`. 3. Link the framework with your target as described in [Carthage Readme](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application). ### Install 3D Secure 2 Component for Adyen Android version 2.4.0 to 2.4.5  Import the Android 3D Secure 2 Component by adding this line to your **build.gradle** file. ``` implementation "com.adyen.checkout:threeds:" ``` ## Integration steps 1. Collect the shopper's card payment details with your existing [Cards integration](/payment-methods/cards#how-do-you-want-to-integrate) - whether through Drop-in, Card Component, or your own UI for the API-only integration. 2. Proceed to [submit a payment request](#submit-a-payment-request).  3. Use the `resultCode` from the response to determine your next action. For example, to complete a 3D Secure 2 authentication flow, you might need to [get the 3D Secure 2 device fingerprint](#get-the-3d-secure-2-device-fingerprint), or [present a challenge](#present-a-challenge) to the shopper, or both. Choose the integration steps for web, Android, or iOS. 4. [Submit the 3D Secure device fingerprinting result](#submit-the-3d-secure-2-device-fingerprinting-result) and in case of a challenge flow, [submit the challenge result](#submit-the-challenge-result). To test your integration, see [Testing 3D Secure 2](#testing-3d-secure-2). ## Step 1: Submit a payment request Submit a payment request with a POST  [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) call containing the shopper's card details. Include the following parameters to indicate that you are ready to accept 3D Secure 2 authenticated payments: | Parameter name | Required | Description | | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [paymentMethod](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-paymentMethod) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Object that contains the shopper's card details. Include the cardholder's name. If you are [fully PCI compliant](/development-resources/pci-dss-compliance-guide) you can [pass raw card](/payment-methods/cards/raw-card-data) data instead. | | [channel](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-channel) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Specify platform that you are using. Use **Web**, **iOS**, or **Android**. | | `authenticationData.threeDSRequestData.nativeThreeDS` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Set to **preferred**. Indicates that your payment page can handle 3D Secure 2 transactions natively. | | [browserInfo](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-browserInfo) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | Object that contains information about the shopper's browser.- Full object required is for `channel` **web**. - For mobile integrations (`channel` **iOS** and **Android**), the `userAgent` and `acceptHeader` fields are required to indicate that your integration can handle [3D Secure 2 redirect authentication](/online-payments/3d-secure/redirect-3ds2). If your mobile integration is unable to generate this information, you can send the same data as in the code samples below. | | [returnUrl](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-returnUrl) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | In case of a 3D Secure 1 flow, this is the URL where the shopper will be redirected back to after completing 3D Secure 1 authentication. This URL can have a maximum of 1024 characters. See [Return URL formats](#return-url-formats) for each channel. | | [origin](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-origin) | | Required for `channel` **Web**. The URL of the page where you are loading the 3D Secure 2 Component from. The `origin` should not include subdirectories and a trailing slash. You can also get this by opening the browser console and calling `window.location.origin`. | | [shopperIP](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-shopperIP) | | The shopper's IP address. | | [billingAddress](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-billingAddress) | | The cardholder's billing address. | | [shopperEmail](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-shopperEmail) | | The cardholder's email address. | #### Return URL formats * For **Web**, the URL should include the protocol: `http://` or `https://`. For example, `https://your-company.example.com/checkout/`. * For **iOS**, use the custom URL for your app. For example, `my-app://`. For more information on setting custom URL schemes, refer to the [Apple Developer documentation](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app). * For **Android**, if you are using the Android SDK, get the URL from `CheckoutSetupParameters.getReturnUrl()`. Otherwise, use a custom URL handled by an Activity on your app. You can configure it with an [intent filter](https://developer.android.com/guide/components/intents-filters). For example, configure `my-app://your.package.name`, and then add that to your `manifest.xml` file. ```xml ``` We recommend that you provide all available information to increase the likelihood of achieving a frictionless flow and a higher authorisation rate. In addition to the regular parameters you provide to Adyen, send additional parameters in [this list](/online-payments/3d-secure/api-reference#3d-secure-2-additional-data-objects). #### Request **Sample payment request for web** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount":{ "currency":"EUR", "value":1000 }, "reference":"YOUR_ORDER_NUMBER", "paymentMethod":{ "type":"scheme", "encryptedCardNumber":"adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedExpiryMonth":"adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedExpiryYear":"adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedSecurityCode":"adyenjs_0_1_18$MT6ppy0FAMVMLH...", "holderName": "S. Hopper" }, "authenticationData": { "threeDSRequestData": { "nativeThreeDS": "preferred" } }, "browserInfo":{ "userAgent":"Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36", "acceptHeader":"text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8", "language":"nl-NL", "colorDepth":24, "screenHeight":723, "screenWidth":1536, "timeZoneOffset":0, "javaEnabled": true }, "shopperIP": "192.0.2.1", "channel" : "web", "origin" : "https://your-company.example.com/", "returnUrl" : "https://your-company.example.com/checkout/", "merchantAccount":"YOUR_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v26.3.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the live environment, additionally include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) ThreeDSRequestData threeDSRequestData = new ThreeDSRequestData() .nativeThreeDS(ThreeDSRequestData.NativeThreeDSEnum.PREFERRED); AuthenticationData authenticationData = new AuthenticationData() .threeDSRequestData(threeDSRequestData); Amount amount = new Amount() .currency("EUR") .value(1000L); CardDetails cardDetails = new CardDetails() .encryptedCardNumber("adyenjs_0_1_18$MT6ppy0FAMVMLH...") .holderName("S. Hopper") .encryptedSecurityCode("adyenjs_0_1_18$MT6ppy0FAMVMLH...") .encryptedExpiryYear("adyenjs_0_1_18$MT6ppy0FAMVMLH...") .encryptedExpiryMonth("adyenjs_0_1_18$MT6ppy0FAMVMLH...") .type(CardDetails.TypeEnum.SCHEME); BrowserInfo browserInfo = new BrowserInfo() .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") .screenWidth(1536) .javaEnabled(true) .screenHeight(723) .timeZoneOffset(0) .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36") .language("nl-NL") .colorDepth(24); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .authenticationData(authenticationData) .amount(amount) .merchantAccount("YOUR_MERCHANT_ACCOUNT") .origin("https://your-company.example.com/") .channel(PaymentRequest.ChannelEnum.WEB) .paymentMethod(new CheckoutPaymentMethod(cardDetails)) .shopperIP("192.0.2.1") .returnUrl("https://your-company.example.com/checkout/") .browserInfo(browserInfo); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php // Adyen PHP API Library v18.2.1 use Adyen\Client; use Adyen\Environment; use Adyen\Model\Checkout\ThreeDSRequestData; use Adyen\Model\Checkout\AuthenticationData; use Adyen\Model\Checkout\Amount; use Adyen\Model\Checkout\CheckoutPaymentMethod; use Adyen\Model\Checkout\BrowserInfo; use Adyen\Model\Checkout\PaymentRequest; use Adyen\Service\Checkout\PaymentsApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); // For the live environment, additionally include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $threeDSRequestData = new ThreeDSRequestData(); $threeDSRequestData ->setNativeThreeDS("preferred"); $authenticationData = new AuthenticationData(); $authenticationData ->setThreeDSRequestData($threeDSRequestData); $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(1000); $checkoutPaymentMethod = new CheckoutPaymentMethod(); $checkoutPaymentMethod ->setEncryptedCardNumber("adyenjs_0_1_18\$MT6ppy0FAMVMLH...") ->setHolderName("S. Hopper") ->setEncryptedSecurityCode("adyenjs_0_1_18\$MT6ppy0FAMVMLH...") ->setEncryptedExpiryYear("adyenjs_0_1_18\$MT6ppy0FAMVMLH...") ->setEncryptedExpiryMonth("adyenjs_0_1_18\$MT6ppy0FAMVMLH...") ->setType("scheme"); $browserInfo = new BrowserInfo(); $browserInfo ->setAcceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") ->setScreenWidth(1536) ->setJavaEnabled(true) ->setScreenHeight(723) ->setTimeZoneOffset(0) ->setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36") ->setLanguage("nl-NL") ->setColorDepth(24); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAuthenticationData($authenticationData) ->setAmount($amount) ->setMerchantAccount("YOUR_MERCHANT_ACCOUNT") ->setOrigin("https://your-company.example.com/") ->setChannel("web") ->setPaymentMethod($checkoutPaymentMethod) ->setShopperIP("192.0.2.1") ->setReturnUrl("https://your-company.example.com/checkout/") ->setBrowserInfo($browserInfo); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v17.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the live environment, additionally include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) ThreeDSRequestData threeDSRequestData = new ThreeDSRequestData { NativeThreeDS = ThreeDSRequestData.NativeThreeDSEnum.Preferred }; AuthenticationData authenticationData = new AuthenticationData { ThreeDSRequestData = threeDSRequestData }; Amount amount = new Amount { Currency = "EUR", Value = 1000 }; CardDetails cardDetails = new CardDetails { EncryptedCardNumber = "adyenjs_0_1_18$MT6ppy0FAMVMLH...", HolderName = "S. Hopper", EncryptedSecurityCode = "adyenjs_0_1_18$MT6ppy0FAMVMLH...", EncryptedExpiryYear = "adyenjs_0_1_18$MT6ppy0FAMVMLH...", EncryptedExpiryMonth = "adyenjs_0_1_18$MT6ppy0FAMVMLH...", Type = CardDetails.TypeEnum.Scheme }; BrowserInfo browserInfo = new BrowserInfo { AcceptHeader = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", ScreenWidth = 1536, JavaEnabled = true, ScreenHeight = 723, TimeZoneOffset = 0, UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", Language = "nl-NL", ColorDepth = 24 }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", AuthenticationData = authenticationData, Amount = amount, MerchantAccount = "YOUR_MERCHANT_ACCOUNT", Origin = "https://your-company.example.com/", Channel = PaymentRequest.ChannelEnum.Web, PaymentMethod = new CheckoutPaymentMethod(cardDetails), ShopperIP = "192.0.2.1", ReturnUrl = "https://your-company.example.com/checkout/", BrowserInfo = browserInfo }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v17.3.0 // Require the parts of the module you want to use const { Client, CheckoutAPI } = require('@adyen/api-library'); // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 1000 }, reference: "YOUR_ORDER_NUMBER", paymentMethod: { type: "scheme", encryptedCardNumber: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryMonth: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryYear: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedSecurityCode: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", holderName: "S. Hopper" }, authenticationData: { threeDSRequestData: { nativeThreeDS: "preferred" } }, browserInfo: { userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", acceptHeader: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", language: "nl-NL", colorDepth: 24, screenHeight: 723, screenWidth: 1536, timeZoneOffset: 0, javaEnabled: true }, shopperIP: "192.0.2.1", channel: "web", origin: "https://your-company.example.com/", returnUrl: "https://your-company.example.com/checkout/", merchantAccount: "YOUR_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v10.4.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/checkout" ) // For the live environment, additionally include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) threeDSRequestData := checkout.ThreeDSRequestData{ NativeThreeDS: common.PtrString("preferred"), } authenticationData := checkout.AuthenticationData{ ThreeDSRequestData: &threeDSRequestData, } amount := checkout.Amount{ Currency: "EUR", Value: 1000, } cardDetails := checkout.CardDetails{ EncryptedCardNumber: common.PtrString("adyenjs_0_1_18$MT6ppy0FAMVMLH..."), HolderName: common.PtrString("S. Hopper"), EncryptedSecurityCode: common.PtrString("adyenjs_0_1_18$MT6ppy0FAMVMLH..."), EncryptedExpiryYear: common.PtrString("adyenjs_0_1_18$MT6ppy0FAMVMLH..."), EncryptedExpiryMonth: common.PtrString("adyenjs_0_1_18$MT6ppy0FAMVMLH..."), Type: common.PtrString("scheme"), } browserInfo := checkout.BrowserInfo{ AcceptHeader: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", ScreenWidth: 1536, JavaEnabled: true, ScreenHeight: 723, TimeZoneOffset: 0, UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", Language: "nl-NL", ColorDepth: 24, } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", AuthenticationData: &authenticationData, Amount: amount, MerchantAccount: "YOUR_MERCHANT_ACCOUNT", Origin: common.PtrString("https://your-company.example.com/"), Channel: common.PtrString("web"), PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(&cardDetails), ShopperIP: common.PtrString("192.0.2.1"), ReturnUrl: "https://your-company.example.com/checkout/", BrowserInfo: &browserInfo, } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.5.1 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 1000 }, "reference": "YOUR_ORDER_NUMBER", "paymentMethod": { "type": "scheme", "encryptedCardNumber": "adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedExpiryMonth": "adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedExpiryYear": "adyenjs_0_1_18$MT6ppy0FAMVMLH...", "encryptedSecurityCode": "adyenjs_0_1_18$MT6ppy0FAMVMLH...", "holderName": "S. Hopper" }, "authenticationData": { "threeDSRequestData": { "nativeThreeDS": "preferred" } }, "browserInfo": { "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", "acceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "nl-NL", "colorDepth": 24, "screenHeight": 723, "screenWidth": 1536, "timeZoneOffset": 0, "javaEnabled": True }, "shopperIP": "192.0.2.1", "channel": "web", "origin": "https://your-company.example.com/", "returnUrl": "https://your-company.example.com/checkout/", "merchantAccount": "YOUR_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v9.5.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the live environment, additionally include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 1000 }, :reference => 'YOUR_ORDER_NUMBER', :paymentMethod => { :type => 'scheme', :encryptedCardNumber => 'adyenjs_0_1_18$MT6ppy0FAMVMLH...', :encryptedExpiryMonth => 'adyenjs_0_1_18$MT6ppy0FAMVMLH...', :encryptedExpiryYear => 'adyenjs_0_1_18$MT6ppy0FAMVMLH...', :encryptedSecurityCode => 'adyenjs_0_1_18$MT6ppy0FAMVMLH...', :holderName => 'S. Hopper' }, :authenticationData => { :threeDSRequestData => { :nativeThreeDS => 'preferred' } }, :browserInfo => { :userAgent => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36', :acceptHeader => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', :language => 'nl-NL', :colorDepth => 24, :screenHeight => 723, :screenWidth => 1536, :timeZoneOffset => 0, :javaEnabled => true }, :shopperIP => '192.0.2.1', :channel => 'web', :origin => 'https://your-company.example.com/', :returnUrl => 'https://your-company.example.com/checkout/', :merchantAccount => 'YOUR_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v17.3.0 // Require the parts of the module you want to use import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // Initialize the client object // For the live environment, additionally include your liveEndpointUrlPrefix. const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const threeDSRequestData: Types.checkout.ThreeDSRequestData = { nativeThreeDS: Types.checkout.ThreeDSRequestData.NativeThreeDSEnum.Preferred }; const authenticationData: Types.checkout.AuthenticationData = { threeDSRequestData: threeDSRequestData }; const amount: Types.checkout.Amount = { currency: "EUR", value: 1000 }; const cardDetails: Types.checkout.CardDetails = { encryptedCardNumber: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", holderName: "S. Hopper", encryptedSecurityCode: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryYear: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", encryptedExpiryMonth: "adyenjs_0_1_18$MT6ppy0FAMVMLH...", type: Types.checkout.CardDetails.TypeEnum.Scheme }; const browserInfo: Types.checkout.BrowserInfo = { acceptHeader: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", screenWidth: 1536, javaEnabled: true, screenHeight: 723, timeZoneOffset: 0, userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", language: "nl-NL", colorDepth: 24 }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", authenticationData: authenticationData, amount: amount, merchantAccount: "YOUR_MERCHANT_ACCOUNT", origin: "https://your-company.example.com/", channel: Types.checkout.PaymentRequest.ChannelEnum.Web, paymentMethod: cardDetails, shopperIP: "192.0.2.1", returnUrl: "https://your-company.example.com/checkout/", browserInfo: browserInfo }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Response You'll receive a response containing: * `resultCode`: **IdentifyShopper** or **ChallengeShopper**. Perform the corresponding [3D Secure device fingerprinting](#get-the-3d-secure-2-device-fingerprint) or [present a challenge](#present-a-challenge) flows. If the transaction is exempted from 3D Secure 2, you might get an **Authorised** `resultCode`.  * `threeds2.fingerprintToken` or `threeds2.challengeToken`: Use this to initiate the 3D Secure 2 Component. If you want to know the contents of the encoded string, see [payload structure](/online-payments/3d-secure/api-reference#payload-structure). * `paymentData`: Use this for your next POST  [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request. For other possible `resultCode` values and the actions that you need to take, see [Result codes](/checkout/payment-result-codes).  **Sample response with IdentifyShopper resultCode** ```json { "resultCode": "IdentifyShopper", "authentication": { "threeds2.fingerprintToken": "eyJ0aH..." }, "details": [ { "key": "threeds2.fingerprint", "type": "text" } ], "paymentData": "Ab02b4c0!..." } ``` ## Step 2: Get the 3D Secure 2 device fingerprint If your server receives an **IdentifyShopper** `resultCode`, perform the 3D Secure 2 device fingerprinting. Follow the 3D Secure device fingerprinting procedure for [web](#collect-the-3d-secure-2-device-fingerprint-from-the-browser), [iOS](#collect-the-3d-secure-2-device-fingerprint-from-an-ios-app), or [Android](#collect-the-3d-secure-2-device-fingerprint-from-an-android-app). ### Collect the 3D Secure 2 device fingerprint with the Web Component If you are using v49 of our APIs with Adyen JS version 3.1.0 and later, use `createFromAction` to load the [3D Secure 2 Component](/online-payments/build-your-integration/sessions-flow) instead. 1. Make sure that you have already added the [Components JavaScript file and the required configuration](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=Components#add) on your payments page. 2. Create a DOM element. ```
``` 3. Initiate the 3D Secure 2 Component with the `threeds2.fingerprintToken` you received from the  [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response, assign a function to handle the `onComplete` and `onError` events, and mount the 3D Secure 2 Component. ```js const threeDS2IdentifyShopper = checkout .create('threeDS2DeviceFingerprint', { fingerprintToken: resultObject.authentication['threeds2.fingerprintToken'], onComplete: function() {}, // Called whenever a result is available, regardless if the outcome is successful or not. onError: function() {} // Gets triggered on error. }) .mount('#threeDS2'); ``` 4. When the `onComplete` event is triggered, get the result and proceed to submit the [3D Secure 2 device fingerprinting result](#submit-the-3d-secure-2-device-fingerprinting-result). If the 3D Secure 2 device fingerprinting failed, both `onComplete` and `onError` will be called. **Sample \onComplete\ event handler** ```java function onComplete(fingerprintData) { fingerprintResult = fingerprintData.data.details["threeds2.fingerprint"]; } ``` ### Collect the 3D Secure 2 device fingerprint from an iOS app If you are using v49 of our APIs with Adyen iOS version 3.0.0 and later, use the [3D Secure 2 Action Component](/online-payments/3d-secure/native-3ds2) instead. 1. Create a `Card3DS2Authenticator` instance.  ```swift let authenticator = Card3DS2Authenticator() ``` 2. Create a fingerprint with the `threeds2.fingerprintToken` you received from the   [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response.  ```swift authenticator.createFingerprint(usingToken: fingerprintToken) { result in switch result { case let .success(fingerprint): // Submit fingerprint case let .failure(error): // Handle error } } ``` 3. If the `success` event is triggered, proceed to [submit the 3D Secure 2 device fingerprinting result](#submit-the-3d-secure-2-device-fingerprinting-result) with the value passed in `success`. Otherwise, handle the `failure` event. The `failure` event will be triggered in case of a timeout, user cancellation, or system failures such as a certificate validation error or an invalid response from the issuer.  ### Collect the 3D Secure 2 device fingerprint from an Android app If you are using v49 of our APIs with Adyen Android version 3.0.0 and later, use the [3D Secure 2 Action Component](/online-payments/3d-secure/native-3ds2) instead. 1. Create a `Card3DS2Authenticator` instance and pass the current context. ```java mCard3DS2Authenticator = new Card3DS2Authenticator(/* Activity */ this); ``` 2. Create a fingerprint with the `threeds2.fingerprintToken` you received from the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response. ```java mCard3DS2Authenticator.createFingerprint(fingerprintToken, new Card3DS2Authenticator.FingerprintListener() { @Override public void onSuccess(@NonNull String fingerprint) { // Submit fingerprint } @Override public void onFailure(@NonNull ThreeDS2Exception e) { mCard3DS2Authenticator.release(); // Handle error } }); ``` 3. If the `onSuccess` event is triggered, proceed to [submit the 3D Secure 2 device fingerprinting result](#submit-the-3d-secure-2-device-fingerprinting-result). Otherwise, handle the `onFailure` event. The `onFailure` event will be triggered in case of a timeout, user cancellation, or system failures such as a certificate validation error or an invalid response from the issuer. ## Step 3: Submit the 3D Secure 2 device fingerprinting result Make a POST   [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request from your server with the `details` object and the `paymentData` as parameters. * `threeds2.fingerprint`: Pass the `fingerprintResult` from the `onComplete` event handler for web, `success` from iOS, or `onSuccess` for Android event handler.  * `paymentData`: Pass the `paymentData` from the [initial payment response](#submit-a-payment-request). ###### Request ```json { "details": { "threeds2.fingerprint": "eyJ0aHJlZURTQ29tcEluZCI6ICJZIn0=" }, "paymentData": "YOUR_PAYMENT_DATA..." } ``` ###### Response You'll receive a response containing any of the following `resultCode`: * **Authorised** – This indicates that the transaction was authenticated in a **frictionless flow**, and the payment was successfully completed. This state serves as an indicator to proceed with the delivery of goods and services.  * **ChallengeShopper** – The issuer has requested further shopper interaction and is initiating a **challenge flow**. You will also get the `threeds2.challengeToken` and the `paymentData` which you will need in the challenge flow. If you want to know the contents of the encoded `threeds2.challengeToken` string, see [payload structure](/online-payments/3d-secure/api-reference#payload-structure). For other possible `resultCode` values and the actions that you need to take, see [Result codes](/checkout/payment-result-codes). ```json { "resultCode": "ChallengeShopper", "authentication": { "threeds2.challengeToken": "eyJ0aH..." }, "details": [ { "key": "threeds2.challengeResult", "type": "text" } ], "paymentData": "Ab02b4c0!..." } ``` ## Step 4: Present a challenge If your server receives a **ChallengeShopper** `resultCode`, this means that the issuer would like to perform additional checks in order to verify that the shopper is indeed the cardholder. Follow the challenge flow procedure for [web](#present-a-challenge-in-the-browser), [Android](#present-a-challenge-in-an-android-app), or [iOS](#present-a-challenge-in-an-ios-app). ### Present a challenge with the Web Component If you are using v49 of our APIs with Adyen JS version 3.1.0 and later, use `createFromAction` to load the [3D Secure 2 Component](/online-payments/build-your-integration/sessions-flow) instead. 1. Make sure that you have already added the [Components JavaScript file and the required configuration](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=Components#add) on your payments page. 2. Create a DOM element, or reuse the existing one if you are proceeding from the device fingerprinting flow. ```
``` 3. Initiate the 3D Secure 2 Component with the `threeds2.challengeToken` you received from  [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) response or from  [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) if you are proceeding from the device fingerprinting flow. Assign a function to handle the `onComplete` and `onError` events, set the challenge window size, and then mount the 3D Secure 2 Component. ```js const threeDS2Challenge = checkout .create('threeDS2Challenge', { challengeToken: resultObject.authentication['threeds2.challengeToken'], onComplete: function() {}, // Called whenever a result is available, regardless if the outcome is successful or not. onError: function() {}, // Gets triggered on error. challengeWindowSize: '05' // Defaults to '02' }) .mount('#threeDS2'); ``` Set the `challengeWindowSize` to any of the following identifiers: | identifier | size | | ---------- | ------------- | | 01 | 250px x 400px | | 02 | 390px x 400px | | 03 | 500px x 600px | | 04 | 600px x 400px | | 05 | 100% x 100% | 4. When the `onComplete` event is triggered, always get the result and proceed to [submit the challenge result](#submit-the-challenge-result). If the challenge flow failed, both `onComplete` and `onError` will be called. **Sample \onComplete\ event handler** ```java function onComplete(challengeData) { challengeResult = challengeData.data.details["threeds2.challengeResult"]; } ``` ### Present a challenge in an iOS app If you are using v49 of our APIs with Adyen iOS version 3.0.0 and later, use the [3D Secure 2 Action Component](/online-payments/3d-secure/native-3ds2) instead. 1. Use the same `Card3DS2Authenticator` instance from the 3D Secure device fingerprinting flow. Pass the `threeds2.challengeToken` you received from  [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) to the `presentChallenge()` function.  ```swift authenticator.presentChallenge(usingToken: challengeToken) { result in switch result { case let .success(challengeResult): let payload = challengeResult.payload // Submit challenge result payload case let .failure(error): // Handle error } } ``` 2. If the `success` event is triggered, proceed to [submit the challenge result](#submit-the-challenge-result) with the `payload` value passed in the `challengeResult` of the `success` event. Otherwise, handle the `failure` event. The `failure` event will be triggered in case of a timeout, user cancellation, or system failures such as a certificate validation error or an invalid response from the issuer.  ### Present a challenge in an Android app If you are using v49 of our APIs with Adyen Android version 3.0.0 and later, use the [3D Secure 2 Action Component](/online-payments/3d-secure/native-3ds2) instead. 1. Pass the `threeds2.challengeToken` you received from the  [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) to the `Card3DS2Authenticator`.  ```java mCard3DS2Authenticator.presentChallenge(challengeToken, new Card3DS2Authenticator.SimpleChallengeListener() { @Override public void onSuccess(@NonNull ChallengeResult challengeResult) { mCard3DS2Authenticator.release(); String payload = challengeResult.getPayload(); // Pass the challenge result payload } @Override public void onFailure(@NonNull ThreeDS2Exception e) { mCard3DS2Authenticator.release(); // Handle error } }); ``` 2. If the `onSuccess` event is triggered, proceed to [submit the challenge result](#submit-the-challenge-result) with the `payload` value passed in the `challengeResult` of the `onSuccess` event. Otherwise, handle the `onFailure` event. The `onFailure` event will be triggered in case of a timeout, user cancellation, or system failures such as a certificate validation error or an invalid response from the issuer. ## Step 5: Submit the challenge result Make a POST   [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) request from your server and include `details` and the `paymentData` as parameters. * `threeds2.challengeResult`: Pass the result from the `challengeResult` from the `onComplete` event handler for web, `onSuccess` for Android, or the `payload` value in the `challengeResult` of the `success` iOS event handler.  * `paymentData`: This is the `paymentData` from the latest API response, either from the  [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) or from the  [/payments/details](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments/details) response if you are proceeding from the device fingerprinting flow. #### Request ```json { "details": { "threeds2.challengeResult": "eyJ0cmFuc1N0YXR1cyI6IlkifQ==" }, "paymentData": "YOUR_PAYMENT_DATA" } ``` #### Response You'll receive **Authorised** as the `resultCode` if the payment was successful. ```json { "pspReference": "V4HZ4RBFJGXXGN82", "resultCode": "Authorised" } ``` ## UI customizations for apps ### Customizing iOS UI The 3D Secure 2 Component for Adyen iOS version 2.x.x inherits your app's theme to ensure the UI of the challenge flow fits your app's look and feel. If you require further UI customizations, the Component provides some customization options through the `ADYAppearanceConfiguration` class. To customize your UI, create an instance of `ADYAppearanceConfiguration`, configure the desired properties, and pass it during initialization of the `Card3DS2Authenticator`. ```swift let appearanceConfiguration = ADYAppearanceConfiguration() // Customize properties of appearanceConfiguration. let authenticator = Card3DS2Authenticator(appearanceConfiguration: appearanceConfiguration) ``` For a complete list of customizable properties, see the [ADYAppearanceConfiguration](https://adyen.github.io/adyen-3ds2-ios/2.3.1/documentation/adyen3ds2/adyappearanceconfiguration) class reference documentation. ### Customizing Android UI #### Customize the SDK theme The 3D Secure 2 Component for Adyen Android version 2.x.x inherits your app's theme to ensure the UI of the challenge flow fits your app's look and feel. You can override the default SDK theme to inherit from one of AppCompat's theme variants. To do this, add the following XML snippet to your `styles.xml` file. ```xml ``` #### Using UiCustomization class If you require further UI customizations, the 3D Secure 2 Component for Adyen Android version 2.x.x provides some customization options through the `UiCustomization` class. To use the `UiCustomization` class, create an instance of `UiCustomization`, configure the desired properties, and pass it during initialization of the `Card3DS2Authenticator`. ```java mCard3DS2Authenticator = new Card3DS2Authenticator(/* Activity */ this, uiCustomization); ``` For a complete list of customizable properties, see the [UiCustomization](https://adyen.github.io/adyen-3ds2-android/com/adyen/threeds2/customization/UiCustomization.html) class reference documentation. ## Testing 3D Secure 2 To test how your integration handles different 3D Secure 2 authentication scenarios, you need to use a card number for the specific flow. When prompted for 3D Secure 2 text challenges, use the following credentials to authenticate: * For native mobile integrations, use password: **1234** * For web and mobile browser integrations, use password: **password** Depending on the [authentication option](/online-payments/3d-secure/#implementation-options), you can receive the following result codes: * **RedirectShopper**: you receive this result code if you are using the [Redirect authentication](/online-payments/3d-secure/redirect-3ds2) flow. * **IdentifyShopper**: you receive this result code if you are using the [Native authentication](/online-payments/3d-secure/native-3ds2/) flow. * **ChallengeShopper**: you receive this result code after you submit the 3D Secure 2 device fingerprinting result in a Native authentication, unless you specify a [frictionless](/online-payments/3d-secure/#frictionless-flow) flow. Depending on your integration, use the following test cards to simulate different authentication flows. | Card Type | Card Number | Expiry Date | Security Code (CVC/CVV/CID) | | ----------------------------- | ------------------- | ----------- | --------------------------- | | American Express | 3714 4963 5398 431 | 03/2030 | 7373 | | Bancontact / Maestro | 6703 4444 4444 4449 | 03/2030 | | | Bancontact / Visa | 4871 0499 9999 9910 | 03/2030 | 737 | | Cartes Bancaires / Visa Debit | 4035 5014 2814 6300 | 03/2030 | 737 | | Cartes Bancaires | 4360 0000 0100 0005 | 03/2030 | 737 | | China UnionPay (Credit) | 6250 9470 0000 0014 | 03/2030 | 123 | | China UnionPay (Debit) | 6250 9460 0000 0016 | 03/2030 | 123 | | Diners | 3056 9309 0259 04 | 03/2030 | 737 | | Discover | 6011 1111 1111 1117 | 03/2030 | 737 | | Maestro | 5000 5500 0000 0029 | 03/2030 | *n/a* | | Mastercard | 5454 5454 5454 5454 | 03/2030 | 737 | | Mastercard Credit | 2222 4000 1000 0008 | 03/2030 | 737 | | Visa | 4917 6100 0000 0000 | 03/2030 | 737 | | Visa Classic | 4166 6766 6766 6746 | 03/2030 | 737 | #### Challenge without fingerprint To 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: | Card Type | Card Number | Expiry Date | Security Code (CVC/CVV/CID) | | --------- | ------------------- | ----------- | --------------------------- | | Visa | 4212 3456 7891 0006 | 03/2030 | 737 | #### Fingerprint without challenge To test the [frictionless flow](/online-payments/3d-secure/#frictionless-flow), in which you perform a fingerprint but no challenge, use the following test card number: | Card number | Expiry Date | Security Code (CVC/CVV/CID) | Authentication scenario | | ------------------- | ----------- | --------------------------- | ---------------------------- | | 5201 2815 0512 9736 | 03/2030 | 737 | Fingerprint but no challenge | #### Native authentication To test authentication scenarios for native mobile (app-based) integrations, use the following test cards: | Card number | Expiry Date | Security Code (CVC/CVV/CID) | Authentication scenario | | ------------------- | ----------- | --------------------------- | --------------------------------------------------------------------------------------------- | | 5201 2855 6567 2311 | 03/2030 | 737 | Basic text authentication | | 5201 2874 9905 2008 | 03/2030 | 737 | Basic single select | | 5201 2815 9233 1633 | 03/2030 | 737 | Basic multi select | | 5201 2888 2269 6974 | 03/2030 | 737 | Basic out-of-band (OOB) authentication | | 5201 2895 0084 3268 | 03/2030 | 737 | HTML out-of-band (OOB) authentication | | 5201 2861 5377 1465 | 03/2030 | 737 | App single select then text authentication | | 4917 6100 0000 0042 | 03/2030 | 737 | Advanced: ACS sends an empty Challenge Response (`CRes`) | | 4917 6100 0000 0067 | 03/2030 | 737 | Advanced: Invalid content in the `acsSignedContent` field in Authentication Response (`ARes`) | | 4917 6100 0000 0059 | 03/2030 | 737 | Advanced: Challenge Response (`CRes`) timeout | #### Technical error To test simulate an error due to a timeout during the 3D Secure 2 authentication on the issuer side, use the following test card: | Card number | Expiry Date | Security Code (CVC/CVV/CID) | Scenario | | ------------------- | ----------- | --------------------------- | --------------------------------------------------------------------------------------------------- | | 5201 2829 9900 5515 | 03/2030 | 737 | Depending on your configuration, the transaction might still proceed to a successful authorization. | ## See also * [Web Component integration](/online-payments/build-your-integration/sessions-flow) * [3D Secure 2 payload structure](/online-payments/3d-secure/api-reference#payload-structure)