{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","br"]},"type":"markdown"},"seo":{"title":"3DS transactions","description":"Transform your commerce with PXP's unified platform—seamless payments, real-time insights, and global growth in one powerful integration.","lang":"en-UK","siteUrl":"https://developer.pxp.io","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"3ds-transactions","__idx":0},"children":["3DS transactions"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Integrate 3D Secure (3DS) into your checkout."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["By implementing 3DS authentication into your payment flow, you benefit from:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Additional security:"]}," 3DS adds multiple layers of authentication and risk assessment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Liability shift:"]}," Successful 3DS authentication typically shifts fraud liability from merchant to card issuer"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Higher success rate:"]}," Banks are more likely to approve 3DS-authenticated transactions"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["However, the 3DS payment flow is longer than the non-3DS one due to the additional authentication steps. It may also require active customer participation if a challenge is presented."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"payment-flow","__idx":2},"children":["Payment flow"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The 3D Secure flow is made up of nine key steps."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-submission","__idx":3},"children":["Step 1: Submission"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The customer taps the submit button or the payment is triggered programmatically. The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["submit()"]}," method in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CardSubmitComponent"]}," is invoked and validation occurs inside it. If validation passes, the method continues with the payment processing. If it fails, the method exits early and doesn't proceed with the transaction."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-card-tokenisation","__idx":4},"children":["Step 2: Card tokenisation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If it's a new card, the SDK sends the card details to the tokenisation service. If it's a saved card, the SDK retrieves the existing token."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-3-evaluation","__idx":5},"children":["Step 3: Evaluation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK evaluates whether 3DS authentication is required. In this flow, 3DS is required based on factors like transaction amount, risk assessment, or regulatory requirements."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-4-pre-initiation","__idx":6},"children":["Step 4: Pre-initiation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is the initial step in the 3DS authentication flow. It establishes the authentication session by sending transaction and card details to the payment processor."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This step has two associated callbacks:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreInitiateAuthentication"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() -> PreInitiateIntegratedAuthenticationData?"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Returns configuration for the authentication setup."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateIntegratedAuthenticationData"]}," containing acquirer profile, provider ID, timeout, and authentication indicators."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return null:"]}," To skip 3DS authentication (e.g., for low-risk transactions)."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostInitiateAuthentication"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(AuthenticationResult) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Receives the result of the pre-initiation call."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationResult"]}," (either ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateSuccessAuthenticationResult"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedAuthenticationResult"]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Contains:"]}," Authentication ID, state, SCA mandate status, applicable exemptions."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-5-fingerprinting","__idx":7},"children":["Step 5: Fingerprinting"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["During this step, device information and browser characteristics are collected by the fingerprinting component. It creates a hidden iframe that submits transaction details to the issuer's fingerprint URL, enabling risk assessment based on the user's device profile."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-6-authentication","__idx":8},"children":["Step 6: Authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The 3DS server evaluates the transaction risk and determines the authentication path:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Frictionless flow:"]}," If the transaction is low-risk, authentication completes automatically without customer interaction."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Challenge flow:"]}," If additional verification is needed, the customer completes the 3DS authentication challenge (PIN entry, SMS code, biometric verification, etc.)"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The authentication step has two associated callbacks:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthentication"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(PreInitiateSuccessAuthenticationResult) -> InitiateIntegratedAuthenticationData?"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Configures the main authentication parameters."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateSuccessAuthenticationResult"]}," containing pre-initiation results."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["InitiateIntegratedAuthenticationData"]}," with challenge window size, timeout, callback URL."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return null:"]}," To abort the authentication process."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthentication"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(AuthenticationResult, ThreeDSAuthenticationData?) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Receives authentication results and challenge data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter 1:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationResult"]}," indicating success/failure status."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter 2:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ThreeDSAuthenticationData?"]}," containing CAVV, ECI, authentication ID, XID, and other 3DS data"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Contains:"]}," Complete authentication results for transaction processing."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-7-authentication-result","__idx":9},"children":["Step 7: Authentication result"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK receives the 3DS authentication result indicating whether authentication was successful, failed, or requires additional action."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-8-authorisation","__idx":10},"children":["Step 8: Authorisation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This is the final step of the 3DS authentication flow. You receive the transaction data along with the 3DS authentication results and decide whether to proceed. At this point, you can still add additional data or cancel the transaction entirely. The SDK then sends the authorisation request to the payment gateway, including the 3DS authentication data."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The authorisation step has two associated callbacks:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(PreAuthorisationData) -> TransactionInitiationData?"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Provides final transaction data, including 3DS authentication results. This is your last chance to modify the transaction before authorisation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreAuthorisationData"]}," containing authentication results, transaction details, and 3DS data."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TransactionInitiationData"]}," with SCA exemption data, additional transaction parameters."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return null:"]}," To proceed with default authorisation settings."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthorisation"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(SubmitResult) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Receives the final transaction result from the payment gateway."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SubmitResult"]}," (one of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthorisedSubmitResult"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CapturedSubmitResult"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RefusedSubmitResult"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedSubmitResult"]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Contains:"]}," Final transaction status, provider response, authentication confirmation, transaction reference."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Handle payment success/failure, navigate to appropriate screens, update UI state."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-9-authorisation-result","__idx":11},"children":["Step 9: Authorisation result"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You receive the final authorisation response from the payment gateway. The transaction is either approved or declined and final transaction details are available, along with 3DS authentication confirmation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"additional-3ds-callbacks","__idx":12},"children":["Additional 3DS callbacks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Beyond the core flow callbacks, the SDK provides additional callbacks for monitoring specific 3DS events:"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"authentication-status-callbacks","__idx":13},"children":["Authentication status callbacks"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onAuthenticationStarted"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called when 3DS authentication begins."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Show loading indicators, update UI state."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onAuthenticationCompleted"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called when 3DS authentication ends (success or failure)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Hide loading indicators, reset UI state."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onAuthenticationSuccess"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(ThreeDSAuthenticationData) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called specifically for successful authentication."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," Complete ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ThreeDSAuthenticationData"]}," with all 3DS fields."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Log successful authentication, track analytics."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onAuthenticationFailure"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(String, String?) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called specifically for failed authentication."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter 1:"]}," Error message describing the failure."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter 2:"]}," Optional error code for categorising failures."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Handle authentication errors, display appropriate user messages."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"challenge-flow-callbacks","__idx":14},"children":["Challenge flow callbacks"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onChallengeStarted"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["() -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called when a 3DS challenge begins."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Prepare UI for challenge presentation."]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onChallengeCompleted"]},": ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(Boolean) -> Unit"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Purpose:"]}," Called when a 3DS challenge ends."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameter:"]}," Boolean indicating whether challenge was successful."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Usage:"]}," Handle challenge results, update payment flow state."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"implementation","__idx":15},"children":["Implementation"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"before-you-start","__idx":16},"children":["Before you start"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To use 3D Secure in your application, you first need to enable it in the Unity Portal:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["In the ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://portal.pxp.io","target":"_blank"},"children":["Unity Portal"]},", go to ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Merchant setup > Merchant groups"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Select a merchant group."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click the ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Services"]}," tab."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Edit"]}," in the ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["Card service"]}," row."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Configure modules"]}," in the top right."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Click the toggle next to ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["ThreeD secure service"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You'll also need to get the following from your payment processor:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["acquirerProfileId"]},": Your acquirer profile identifier."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["providerId"]},": Your 3DS provider identifier."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Test credentials for the sandbox environment."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-configure-your-sdk","__idx":17},"children":["Step 1: Configure your SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To start, set up your ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PxpSdkConfig"]}," to include the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["shopper"]}," object."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val sdkConfig = PxpSdkConfig(\n    environment = Environment.TEST,\n    session = SessionConfig(\n        sessionId = \"your_session_id\",\n        sessionData = \"your_session_data\"\n    ),\n    transactionData = TransactionData(\n        amount = 99.99,\n        currency = CurrencyType.USD,\n        entryType = EntryType.ECOM,\n        intent = IntentType.AUTHORISATION,\n        merchantTransactionId = \"order-123\",\n        merchantTransactionDate = { Instant.now().toString() },\n        // Include 3DS-friendly data\n        shopper = Shopper(\n            email = \"customer@example.com\",\n            firstName = \"John\",\n            lastName = \"Doe\"\n        )\n    ),\n    clientId = \"your_client_id\",\n    ownerId = \"Unity\",\n    ownerType = \"MerchantGroup\",\n    merchantShopperId = \"shopper-123\"\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-implement-callbacks","__idx":18},"children":["Step 2: Implement callbacks"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Next, implement your chosen callbacks. Note that some are required."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val cardSubmitConfig = CardSubmitComponentConfig(\n    // REQUIRED: Provide 3DS configuration\n    onPreInitiateAuthentication = {\n        PreInitiateIntegratedAuthenticationData(\n            acquirerProfileId = \"your_acquirer_profile_id\",\n            providerId = \"your_3ds_provider_id\",\n            requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.PAYMENT_TRANSACTION,\n            timeout = 120\n        )\n    },\n\n    // OPTIONAL: Handle the pre-initiation result\n    onPostInitiateAuthentication = { result ->\n        Log.d(\"3DS\", \"3DS pre-initiation completed: $result\")\n        when (result) {\n            is PreInitiateSuccessAuthenticationResult -> {\n                Log.d(\"3DS\", \"3DS setup successful\")\n            }\n            is FailedAuthenticationResult -> {\n                Log.e(\"3DS\", \"3DS setup failed: ${result.errorReason}\")\n            }\n        }\n    },\n    \n    // REQUIRED: Configure main authentication\n    onPreAuthentication = { preInitResult ->\n        Log.d(\"3DS\", \"Configuring 3DS authentication: $preInitResult\")\n        \n        InitiateIntegratedAuthenticationData(\n            merchantCountryNumericCode = \"840\",\n            merchantLegalName = \"Your company name\",\n            challengeWindowSize = \"04\",\n            requestorChallengeIndicator = \"01\",\n            challengeCallbackUrl = \"https://your-domain.com/3ds-callback\",\n            timeout = 300\n        )\n    },\n\n    // OPTIONAL: Handle the authentication result\n    onPostAuthentication = { authResult, threeDSData ->\n        Log.d(\"3DS\", \"3DS authentication completed: $authResult\")\n        Log.d(\"3DS\", \"3DS data: $threeDSData\")\n        \n        when (authResult) {\n            is InitiateIntegratedSuccessAuthenticationResult -> {\n                Log.d(\"3DS\", \"Authentication successful\")\n            }\n            is FailedAuthenticationResult -> {\n                Log.e(\"3DS\", \"Authentication failed or challenged\")\n            }\n        }\n    },\n    \n    // REQUIRED: Final transaction approval\n    onPreAuthorisation = { preAuthData ->\n        Log.d(\"3DS\", \"Pre-authorisation data: $preAuthData\")\n        \n        // Return transaction initiation data with risk screening\n        TransactionInitiationData(\n            psd2Data = null, // Set to Psd2Data(scaExemption = ...) if needed\n            riskScreeningData = RiskScreeningData(\n                performRiskScreening = true,\n                excludeDeviceData = false,\n                userIp = \"192.168.1.100\",\n                account = RiskScreeningAccount(\n                    id = \"user_12345678\",\n                    creationDateTime = \"2024-01-15T10:30:00.000Z\"\n                ),\n                items = listOf(\n                    RiskScreeningItem(\n                        price = 89.99,\n                        quantity = 1,\n                        category = \"Electronics\",\n                        sku = \"CARD-PROD-001\"\n                    )\n                ),\n                fulfillments = listOf(\n                    RiskScreeningFulfillment(\n                        type = FulfillmentType.SHIPPED,\n                        shipping = RiskScreeningShipping(\n                            shippingMethod = ShippingMethod.EXPRESS\n                        ),\n                        recipientPerson = RiskScreeningRecipientPerson(\n                            phoneNumber = \"+1234567890\",\n                            email = \"customer@example.com\"\n                        )\n                    )\n                )\n            )\n        )\n    },\n\n    // OPTIONAL: Handle the final result\n    onPostAuthorisation = { result ->\n        when (result) {\n            is AuthorizedSubmitResult -> {\n                Log.d(\"3DS\", \"Payment successful with 3DS!\")\n                Log.d(\"3DS\", \"Provider response: ${result.providerResponse.message}\")\n                // Navigate to success screen\n                navigateToSuccessScreen()\n            }\n            is CapturedSubmitResult -> {\n                Log.d(\"3DS\", \"Payment captured with 3DS!\")\n                Log.d(\"3DS\", \"Provider response: ${result.providerResponse.message}\")\n                navigateToSuccessScreen()\n            }\n            is RefusedSubmitResult -> {\n                Log.e(\"3DS\", \"Payment refused: ${result.stateData.message}\")\n                showError(\"Payment was declined: ${result.stateData.message}\")\n            }\n            is FailedSubmitResult -> {\n                Log.e(\"3DS\", \"Payment failed: ${result.errorReason}\")\n                showError(\"Payment failed: ${result.errorReason}\")\n            }\n            else -> {\n                Log.e(\"3DS\", \"Unknown result type: ${result::class.simpleName}\")\n                showError(\"Payment completed with unknown status\")\n            }\n        }\n    }\n)\n\nval cardSubmitComponent = pxpCheckout.createComponent<CardSubmitComponent, CardSubmitComponentConfig>(\n    ComponentType.CARD_SUBMIT,\n    cardSubmitConfig\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-3-handle-common-scenarios","__idx":19},"children":["Step 3: Handle common scenarios"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"conditional-3ds","__idx":20},"children":["Conditional 3DS"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the following snippet to only trigger 3DS transactions above a certain amount."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class Conditional3DSManager(private val transactionAmount: Double) {\n    \n    fun createCardSubmitConfig(): CardSubmitComponentConfig {\n        return CardSubmitComponentConfig(\nonPreInitiateAuthentication = {\n                if (transactionAmount > 100.0) {\n    PreInitiateIntegratedAuthenticationData(\n                        acquirerProfileId = \"your_profile\",\n                        providerId = \"your_provider\",\n                        requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.PAYMENT_TRANSACTION,\n                        timeout = 120\n                    )\n                } else {\n                    // Return null to skip 3DS for small amounts\n                    null\n                }\n            }\n        )\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"different-transaction-types","__idx":21},"children":["Different transaction types"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the following snippet to handle different types of transactions."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class TransactionType3DSManager {\n    \n    fun get3DSConfig(transactionType: TransactionType): PreInitiateIntegratedAuthenticationData {\n        val baseConfig = PreInitiateIntegratedAuthenticationData(\n            acquirerProfileId = \"your_profile\",\n            providerId = \"your_provider\",\n            timeout = 120\n        )\n\n        return when (transactionType) {\n            TransactionType.PAYMENT -> baseConfig.copy(\n                requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.PAYMENT_TRANSACTION\n            )\n            TransactionType.RECURRING -> baseConfig.copy(\n                requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.RECURRING_TRANSACTION\n            )\n            TransactionType.ADD_CARD -> baseConfig.copy(\n                requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.ADD_CARD\n            )\n        }\n    }\n    \n    fun createCardSubmitConfig(transactionType: TransactionType): CardSubmitComponentConfig {\n        return CardSubmitComponentConfig(\n            onPreInitiateAuthentication = {\n                get3DSConfig(transactionType)\n            }\n        )\n    }\n}\n\nenum class TransactionType {\n    PAYMENT, RECURRING, ADD_CARD\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-4-handle-errors","__idx":22},"children":["Step 4: Handle errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Lastly, make sure to implement proper error handling."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class ThreeDS3DSErrorHandler {\n    \n    fun createCardSubmitConfigWithErrorHandling(): CardSubmitComponentConfig {\n        return CardSubmitComponentConfig(\n            onSubmitError = { error ->\n                Log.e(\"3DS\", \"Payment error: $error\")\n                handleSubmitError(error)\n            },\n\n            onPostAuthentication = { authResult, threeDSData ->\n                // Handle authentication failures\n                when (authResult) {\n                    is FailedAuthenticationResult -> {\n                        Log.e(\"3DS\", \"Authentication failed: ${authResult.errorReason}\")\n                        // Don't proceed to authorisation\n                        return@CardSubmitComponentConfig\n                    }\n                    is InitiateIntegratedSuccessAuthenticationResult -> {\n                        // Check 3DS status\n                        if (threeDSData?.state == \"AuthenticationFailed\") {\n                            showError(\"Card authentication failed\")\n                            return@CardSubmitComponentConfig\n                        }\n                        Log.d(\"3DS\", \"Authentication successful, proceeding to payment\")\n                    }\n                }\n            }\n        )\n    }\n    \n    private fun handleSubmitError(error: PaymentError) {\n        // Handle specific 3DS errors\n        when (error.code) {\n            \"AUTHENTICATION_FAILED\" -> {\n                showError(\"Payment authentication failed. Please try again.\")\n            }\n            \"CHALLENGE_TIMEOUT\" -> {\n                showError(\"Authentication timed out. Please try again.\")\n            }\n            \"AUTHENTICATION_REJECTED\" -> {\n                showError(\"Payment was rejected by your bank.\")\n            }\n            \"TOKEN_VAULT_EXCEPTION\" -> {\n                showError(\"Token vault exception.\")\n            }\n            \"VALIDATION_EXCEPTION\" -> {\n                showError(\"Validation failed.\")\n            }\n            \"TRANSACTION_AUTHENTICATION_REJECTED\" -> {\n                showError(\"Payment was rejected by your bank.\")\n            }\n            \"PRE_INITIATE_AUTHENTICATION_FAILED\" -> {\n                showError(\"Pre-initiate authentication failed.\")\n            }\n            \"TRANSACTION_AUTHENTICATION_REQUIRES_SCA_EXEMPTION\" -> {\n                showError(\"Transaction authentication requires SCA exemption.\")\n            }\n            \"TRANSACTION_AUTHENTICATION_INVALID\" -> {\n                showError(\"Transaction authentication is invalid.\")\n            }\n            \"NETWORK_SDK_EXCEPTION\" -> {\n                showError(\"Network error occurred. Please try again.\")\n            }\n            \"UNEXPECTED_SDK_EXCEPTION\" -> {\n                showError(\"Payment failed. Please try again.\")\n            }\n            else -> {\n                showError(\"Payment failed. Please try again.\")\n            }\n        }\n    }\n    \n    private fun showError(message: String) {\n        // Implementation depends on your UI framework\n        Log.e(\"3DS\", message)\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-example","__idx":23},"children":["Complete example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following example shows a simple 3DS implementation using the new card component in a complete Android Activity."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"class ThreeDSPaymentActivity : ComponentActivity() {\n    private lateinit var pxpCheckout: PxpCheckout\n    private lateinit var newCardComponent: NewCardComponent\n    private lateinit var errorHandler: ThreeDS3DSErrorHandler\n    \n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        \n        setupPxpCheckout()\n        setupComponents()\n        \n        setContent {\n                ThreeDSPaymentScreen()\n        }\n    }\n    \n    private fun setupPxpCheckout() {\n        val sdkConfig = PxpSdkConfig(\n            environment = Environment.TEST,\n            session = SessionConfig(\n                sessionId = \"session-${System.currentTimeMillis()}\",\n                sessionData = \"your_session_data\"\n            ),\n            transactionData = TransactionData(\n                amount = 99.99,\n                currency = CurrencyType.USD,\n                entryType = EntryType.ECOM,\n                intent = IntentType.AUTHORISATION,\n                merchantTransactionId = \"order-${System.currentTimeMillis()}\",\n                merchantTransactionDate = { Instant.now().toString() },\n                shopper = Shopper(\n                    email = \"customer@example.com\",\n                    firstName = \"John\",\n                    lastName = \"Doe\"\n                )\n            ),\n            clientId = \"your_client_id\",\n            ownerId = \"Unity\",\n            ownerType = \"MerchantGroup\",\n            merchantShopperId = \"shopper-123\"\n        )\n        \n        pxpCheckout = PxpCheckout.builder()\n            .withConfig(sdkConfig)\n            .withContext(this)\n            .withDebugMode(true)\n            .build()\n    }\n    \n    private fun setupComponents() {\n        errorHandler = ThreeDS3DSErrorHandler()\n        \n        val newCardConfig = NewCardComponentConfig(\n            submit = CardSubmitComponentConfig(\n                // Step 1: Set up 3DS\n                onPreInitiateAuthentication = {\n                    PreInitiateIntegratedAuthenticationData(\n                        acquirerProfileId = \"your_acquirer_profile_id\",\n                        providerId = \"your_3ds_provider_id\",\n                        requestorAuthenticationIndicator = RequestorAuthenticationIndicatorType.PAYMENT_TRANSACTION,\n                        timeout = 120\n                    )\n                },\n\n                // Step 2: Configure authentication\n                onPreAuthentication = { preInitResult ->\n                    InitiateIntegratedAuthenticationData(\n                        merchantCountryNumericCode = \"840\",\n                        merchantLegalName = \"Your Company Ltd\",\n                        challengeWindowSize = \"04\",\n                        requestorChallengeIndicator = \"01\",\n                        challengeCallbackUrl = \"https://your-domain.com/3ds-callback\",\n                        timeout = 300\n                    )\n                },\n\n                // Step 3: Handle final authorisation\n                onPreAuthorisation = { preAuthData ->\n                    Log.d(\"3DS\", \"Pre-authorisation data: $preAuthData\")\n                    TransactionInitiationData(\n                        psd2Data = null, // Set to Psd2Data(scaExemption = ...) if needed\n                        riskScreeningData = RiskScreeningData(\n                            performRiskScreening = true,\n                            userIp = \"192.168.1.100\",\n                            account = RiskScreeningAccount(\n                                id = \"user_12345678\",\n                                creationDateTime = \"2024-01-15T10:30:00.000Z\"\n                            ),\n                            fulfillments = listOf(\n                                RiskScreeningFulfillment(\n                                    type = FulfillmentType.SHIPPED,\n                                    recipientPerson = RiskScreeningRecipientPerson(\n                                        phoneNumber = \"+1234567890\"\n                                    )\n                                )\n                            )\n                        )\n                    )\n                },\n\n                // Step 4: Handle success/failure\n                onPostAuthorisation = { result ->\n                    when (result) {\n                        is AuthorizedSubmitResult -> {\n                            navigateToSuccessScreen()\n                        }\n                        is CapturedSubmitResult -> {\n                            navigateToSuccessScreen()\n                        }\n                        is RefusedSubmitResult -> {\n                            showError(\"Payment was declined: ${result.stateData.message}\")\n                        }\n                        else -> {\n                            showError(\"Payment failed\")\n                        }\n                    }\n                },\n\n                // Step 5: Error handling\n                onSubmitError = { error ->\n                    Log.e(\"3DS\", \"3DS Error: $error\")\n                    showError(\"Payment authentication failed\")\n                }\n            )\n        )\n        \n        newCardComponent = pxpCheckout.createComponent(ComponentType.NEW_CARD, newCardConfig)\n    }\n    \n    @Composable\n    private fun ThreeDSPaymentScreen() {\n        var isLoading by remember { mutableStateOf(false) }\n        var errorMessage by remember { mutableStateOf<String?>(null) }\n        var authenticationState by remember { mutableStateOf<String?>(null) }\n        \n        Column(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(16.dp)\n        ) {\n            Text(\n                text = \"3DS Secure Payment\",\n                style = MaterialTheme.typography.headlineMedium,\n                modifier = Modifier.padding(bottom = 16.dp)\n            )\n            \n            // Show authentication status\n            authenticationState?.let { state ->\n                Card(\n                    colors = CardDefaults.cardColors(containerColor = Color.Blue.copy(alpha = 0.1f)),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(bottom = 16.dp)\n                ) {\n            Text(\n                        text = \"Authentication Status: $state\",\n                        color = Color.Blue,\n                        modifier = Modifier.padding(16.dp)\n                    )\n                }\n            }\n            \n            // Show error message if any\n            errorMessage?.let { message ->\n                Card(\n                    colors = CardDefaults.cardColors(containerColor = Color.Red.copy(alpha = 0.1f)),\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(bottom = 16.dp)\n                ) {\n                    Text(\n                        text = message,\n                        color = Color.Red,\n                        modifier = Modifier.padding(16.dp)\n                    )\n                }\n            }\n            \n            // Render payment components\n            pxpCheckout.buildComponentView(\n                component = newCardComponent,\n                modifier = Modifier.fillMaxWidth()\n            )\n            \n            // Loading indicator\n            if (isLoading) {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    CircularProgressIndicator()\n                    Text(\n                        text = \"Processing 3DS Authentication...\",\n                        modifier = Modifier.padding(top = 60.dp)\n                    )\n                }\n            }\n        }\n    }\n    \n    private fun navigateToSuccessScreen(transactionId: String?) {\n        val intent = Intent(this, PaymentSuccessActivity::class.java).apply {\n            putExtra(\"transaction_id\", transactionId)\n            putExtra(\"payment_type\", \"3ds\")\n        }\n        startActivity(intent)\n        finish()\n    }\n    \n    private fun showError(message: String) {\n        AlertDialog.Builder(this)\n            .setTitle(\"3DS Payment Error\")\n            .setMessage(message)\n            .setPositiveButton(\"OK\") { dialog, _ ->\n                dialog.dismiss()\n            }\n            .show()\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"callback-data","__idx":24},"children":["Callback data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section describes the data received by the different callbacks as part of the 3DS flow."]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreInitiateAuthentication"]}," callback doesn't receive anything so isn't included. Instead, it returns your 3DS configuration in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateAuthenticationData"]}," object."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpostinitiateauthentication","__idx":25},"children":["onPostInitiateAuthentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostInitiateAuthentication"]}," callback receives an authentication result (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationResult"]},") that can be either a success (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateSuccessAuthenticationResult"]},") or a failure (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedAuthenticationResult"]},")."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"success","__idx":26},"children":["Success"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When successful, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostInitiateAuthentication"]}," receives the following ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateSuccessAuthenticationResult"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"PreInitiateSuccessAuthenticationResult(\n    authenticationId = \"auth_12345\",\n    state = \"PendingClientData\",\n    scaMandated = true,\n    applicableExemptions = \"LVP\"\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authenticationId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The unique identifier for this 3DS session."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The state of the authentication.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationSuccessful"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationFailed"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationRejected"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationError"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PendingCustomerChallenge"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PendingClientData"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["scaMandated"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Whether Strong Customer Authentication (SCA) is required."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["applicableExemptions"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The list of exemptions that apply to this transaction.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["LVP"]},": Low-value payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TRA"]},": Transaction risk analysis"]}]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's an example of what to do with this data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPostInitiateAuthentication = { result ->\n    when (result) {\n        is FailedAuthenticationResult -> {\n            // This is a failure - ignore or log briefly\n            Log.w(\"3DS\", \"3DS pre-initiation failed - skipping processing\")\n            return@onPostInitiateAuthentication\n        }\n        is PreInitiateSuccessAuthenticationResult -> {\n            // This is a success - process it\n            Log.d(\"3DS\", \"3DS Authentication ID: ${result.authenticationId}\")\n            \n            // Check if SCA (Strong Customer Authentication) is mandated\n            if (result.scaMandated) {\n                Log.d(\"3DS\", \"SCA is required - 3DS must complete successfully\")\n                // Show user message: \"Additional verification required\"\n                showUserMessage(\"Additional verification required\")\n            }\n            \n            // Check available exemptions\n            when (result.applicableExemptions) {\n                \"LVP\" -> {\n                    Log.d(\"3DS\", \"Low value exemption available\")\n                    // You might skip 3DS for small amounts\n                }\n                \"TRA\" -> {\n                    Log.d(\"3DS\", \"Transaction risk analysis exemption available\")\n                }\n            }\n            \n            // Check the current state\n            when (result.state) {\n                \"PendingClientData\" -> {\n                    Log.d(\"3DS\", \"Waiting for client data collection\")\n                    updateAuthenticationState(\"Collecting device data...\")\n                }\n                \"AuthenticationSuccessful\" -> {\n                    Log.d(\"3DS\", \"Authentication already completed successfully\")\n                    updateAuthenticationState(\"Authentication successful\")\n                }\n                \"AuthenticationFailed\" -> {\n                    Log.d(\"3DS\", \"Authentication failed\")\n                    updateAuthenticationState(\"Authentication failed\")\n                }\n                \"PendingCustomerChallenge\" -> {\n                    Log.d(\"3DS\", \"Challenge required from customer\")\n                    updateAuthenticationState(\"Challenge required\")\n                }\n                else -> {\n                    Log.d(\"3DS\", \"Authentication state: ${result.state}\")\n                    updateAuthenticationState(result.state)\n                }\n            }\n        }\n    }\n}\n\nprivate fun showUserMessage(message: String) {\n    // Show user-friendly message\n    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()\n}\n\nprivate fun updateAuthenticationState(state: String) {\n    // Update UI with authentication state\n    Log.d(\"3DS\", \"Authentication state updated: $state\")\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"failure","__idx":27},"children":["Failure"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When unsuccessful, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostInitiateAuthentication"]}," receives the following ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedAuthenticationResult"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"FailedAuthenticationResult(\n    errorCode = \"3DS_001\",\n    errorReason = \"Invalid acquirer profile\",\n    correlationId = \"corr_98765\",\n    details = listOf(\n        \"The specified acquirer profile is not valid\",\n        \"Please check your configuration\"\n    ),\n    status = 400\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errorCode"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The error code."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errorReason"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The reason for the error."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["correlationId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The correlation ID."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["details"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Additional details about the error."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["status"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The HTTP status code."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpreauthentication","__idx":28},"children":["onPreAuthentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthentication"]}," callback receives a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PreInitiateSuccessAuthenticationResult"]}," (from the pre-initiate step) and should return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["InitiateIntegratedAuthenticationData"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's an example of what to do with this data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPreAuthentication = { preInitResult ->\n    Log.d(\"3DS\", \"Received pre-initiation data: $preInitResult\")\n    \n    // Use the authentication ID to track this transaction\n    val authId = preInitResult.authenticationId\n    Log.d(\"3DS\", \"Proceeding with authentication ID: $authId\")\n    \n    // Check if SCA is mandated to adjust challenge preference\n    val challengeIndicator = when {\n        preInitResult.scaMandated -> {\n            Log.d(\"3DS\", \"SCA mandated - requesting challenge\")\n            \"03\" // Challenge mandated\n        }\n        preInitResult.applicableExemptions == \"LVP\" -> {\n            Log.d(\"3DS\", \"Low value exemption - requesting no challenge\")\n            \"04\" // No challenge requested\n        }\n        preInitResult.applicableExemptions == \"TRA\" -> {\n            Log.d(\"3DS\", \"TRA exemption - requesting no challenge\")\n            \"04\" // No challenge requested\n        }\n        else -> {\n            \"01\" // No preference\n        }\n    }\n    \n    val timeout = if (preInitResult.scaMandated) 600 else 300\n    \n    InitiateIntegratedAuthenticationData(\n        merchantCountryNumericCode = \"840\",\n        merchantLegalName = \"Your company name\",\n        challengeWindowSize = \"04\",\n        requestorChallengeIndicator = challengeIndicator,\n        challengeCallbackUrl = \"https://your-domain.com/3ds-callback\",\n        timeout = timeout\n    )\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpostauthentication","__idx":29},"children":["onPostAuthentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthentication"]}," callback receives:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["An authentication result (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationResult"]},"). This can be either a success (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["InitiateIntegratedSuccessAuthenticationResult"]},") or a failure (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedAuthenticationResult"]},")."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The 3DS authentication data (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ThreeDSAuthenticationData"]},") if a challenge occurred."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"3ds-authentication-details","__idx":30},"children":["3DS Authentication Details"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"ThreeDSAuthenticationData(\n    authenticationId = \"auth_12345\",\n    state = \"AuthenticationSuccessful\",\n    threeDSecureVersion = \"2.2.0\",\n    directoryServerTransactionId = \"ds_trans_id\",\n    cardHolderAuthenticationVerificationValue = \"cavv_value_here\",\n    electronicCommerceIndicator = \"05\"\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authenticationId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The unique identifier for this 3DS session."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The state of the authentication.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationSuccessful"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationFailed"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationRejected"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthenticationError"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["threeDSecureVersion"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The 3DS secure version."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["directoryServerTransactionId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The transaction ID assigned by the Directory Server."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardHolderAuthenticationVerificationValue"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The cardholder authentication verification value (CAVV)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["electronicCommerceIndicator"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The Electronic Commerce Indicator (ECI).",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["01"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["02"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["05"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["06"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["07"]}]}]}]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"authentication-result","__idx":31},"children":["Authentication result"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":5,"id":"success-1","__idx":32},"children":["Success"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"InitiateIntegratedSuccessAuthenticationResult(\n    uniqueId = \"unique_12345\",\n    state = \"completed\",\n    transactionStatus = \"Y\", // AuthenticationVerificationSuccessful\n    electronicCommerceIndicator = \"05\", // 3DS authenticated\n    exemptionGranted = false,\n    exemptionGrantedByIssuer = \"79\", // NoExemptionApplied\n    acsUrl = null, // No challenge needed\n    challengeData = null, // No challenge needed\n    stateData = StateData(\n        code = \"success\",\n        reason = \"Authentication completed successfully\"\n    ),\n    cardholderInfo = null\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["uniqueId"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The unique identifier for this 3DS session."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The state of the authentication."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionStatus"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The status of the transaction.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Y"]},": Authentication verification successful"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["N"]},": Not authenticated / not verified"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["U"]},": Authentication couldn't be performed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["A"]},": Attempts processing performed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["C"]},": Challenge required"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["R"]},": Authentication rejected"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["I"]},": Informational only"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["electronicCommerceIndicator"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The Electronic Commerce Indicator (ECI).",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["01"]},": 3DS not available (non-3DS transaction)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["02"]},": 3DS available but not used"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["05"]},": 3DS authentication successful (fully authenticated)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["06"]},": 3DS authentication attempted",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["07"]},": 3DS authentication failed but transaction allowed"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["exemptionGranted"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Whether an exemption was granted."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["exemptionGrantedByIssuer"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The type of exemption granted by the issuer.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["05"]},": Transaction risk analysis exemption"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["08"]},": Trust list exemption"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["10"]},": Low value exemption"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["11"]},": Secure corporate payments exemption"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["79"]},": No exemption applied"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["acsUrl"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The ACS URL."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["challengeData"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Base64 encoded challenge data."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["stateData"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the state."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardholderInfo"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Additional details about the cardholder."]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's an example of what to do with this data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPostAuthentication = { authResult, threeDSData ->\n    Log.d(\"3DS\", \"Authentication result: $authResult\")\n    Log.d(\"3DS\", \"3DS data: $threeDSData\")\n    \n    when (authResult) {\n        is FailedAuthenticationResult -> {\n            Log.e(\"3DS\", \"Authentication failed: ${authResult.errorReason}\")\n            showError(\"Card verification failed. Please try a different payment method.\")\n            return@onPostAuthentication // Stop the payment flow\n        }\n        is InitiateIntegratedSuccessAuthenticationResult -> {\n            // Check transaction status\n            when (authResult.transactionStatus) {\n                \"Y\" -> {\n                    Log.d(\"3DS\", \"Authentication successful - no challenge needed\")\n                    showMessage(\"Card verified successfully\")\n                }\n                \"C\" -> {\n                    Log.d(\"3DS\", \"Challenge completed - checking result...\")\n                    if (threeDSData?.state == \"AuthenticationSuccessful\") {\n                        Log.d(\"3DS\", \"Challenge completed successfully\")\n                        showMessage(\"Verification completed\")\n                    } else {\n                        Log.e(\"3DS\", \"Challenge failed\")\n                        showError(\"Verification failed. Please try again.\")\n                        return@onPostAuthentication // Stop payment\n                    }\n                }\n                \"N\" -> {\n                    Log.e(\"3DS\", \"Authentication failed\")\n                    showError(\"Card verification failed\")\n                    return@onPostAuthentication // Stop payment\n                }\n                \"R\" -> {\n                    Log.e(\"3DS\", \"Authentication rejected\")\n                    showError(\"Payment was rejected by your bank\")\n                    return@onPostAuthentication // Stop payment\n                }\n            }\n            \n            // Log important 3DS data for transaction\n            threeDSData?.let { data ->\n                Log.d(\"3DS\", \"ECI: ${data.electronicCommerceIndicator}\")\n                Log.d(\"3DS\", \"CAVV: ${data.cardHolderAuthenticationVerificationValue}\")\n                // These values prove successful 3DS authentication\n            }\n            \n            Log.d(\"3DS\", \"Proceeding to final authorisation...\")\n        }\n    }\n}\n\nprivate fun showMessage(message: String) {\n    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()\n}\n\nprivate fun showError(message: String) {\n    AlertDialog.Builder(this)\n        .setTitle(\"Authentication Error\")\n        .setMessage(message)\n        .setPositiveButton(\"OK\") { dialog, _ -> dialog.dismiss() }\n        .show()\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpreauthorisation","__idx":33},"children":["onPreAuthorisation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]}," callback receives:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Pre-authorisation data (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["preAuthData"]},"): Transaction data ready for authorisation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Error data (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},"): Any error that occurred during pre-authorisation."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The callback should return the final ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TransactionInitiationData"]}," to be used for authorisation."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"pre-authorisation-data","__idx":34},"children":["Pre-authorisation data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The pre-authorisation data includes transaction initiation data (for new cards) or card token data (for saved cards)."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"PreAuthorisationData(\n    transactionInitiationData = TransactionInitiationData(\n        psd2Data = PSD2Data(\n            scaExemption = null\n        ),\n        threeDSecureData = ThreeDSecureData(\n            threeDSecureVersion = \"2.2.0\",\n            electronicCommerceIndicator = \"05\",\n            cardHolderAuthenticationVerificationValue = \"jGvQIvG/5UhjAREALGYYemQLXPI=\",\n            directoryServerTransactionId = \"ds_trans_12345\",\n            threeDSecureTransactionStatus = \"Y\"\n        ),\n        identityVerification = IdentityVerification(\n            nameVerification = true\n        ),\n        addressVerification = AddressVerification(\n            countryCode = \"US\",\n            houseNumberOrName = \"123\",\n            postalCode = \"10001\"\n        )\n    )\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's an example of what to do with this data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPreAuthorisation = { preAuthData ->\n    Log.d(\"3DS\", \"Final authorisation data: $preAuthData\")\n    \n    // Create transaction initiation data with risk screening\n    // Note: TransactionInitiationData only supports psd2Data and riskScreeningData\n    TransactionInitiationData(\n        psd2Data = null, // Set to Psd2Data(scaExemption = ...) if needed\n        riskScreeningData = RiskScreeningData(\n            performRiskScreening = true,\n            excludeDeviceData = false,\n            userIp = \"192.168.1.100\",\n            account = RiskScreeningAccount(\n                id = \"user_12345678\",\n                creationDateTime = \"2024-01-15T10:30:00.000Z\"\n            ),\n            items = listOf(\n                RiskScreeningItem(\n                    price = 89.99,\n                    quantity = 1,\n                    category = \"Electronics\"\n                )\n            ),\n            fulfillments = listOf(\n                RiskScreeningFulfillment(\n                    type = FulfillmentType.SHIPPED,\n                    shipping = RiskScreeningShipping(\n                        shippingMethod = ShippingMethod.EXPRESS\n                    ),\n                    recipientPerson = RiskScreeningRecipientPerson(\n                        phoneNumber = \"+1234567890\",\n                        email = \"customer@example.com\"\n                    )\n                )\n            )\n        )\n    )\n}\n","lang":"kotlin"},"children":[]}]},"headings":[{"value":"3DS transactions","id":"3ds-transactions","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Payment flow","id":"payment-flow","depth":2},{"value":"Step 1: Submission","id":"step-1-submission","depth":3},{"value":"Step 2: Card tokenisation","id":"step-2-card-tokenisation","depth":3},{"value":"Step 3: Evaluation","id":"step-3-evaluation","depth":3},{"value":"Step 4: Pre-initiation","id":"step-4-pre-initiation","depth":3},{"value":"Step 5: Fingerprinting","id":"step-5-fingerprinting","depth":3},{"value":"Step 6: Authentication","id":"step-6-authentication","depth":3},{"value":"Step 7: Authentication result","id":"step-7-authentication-result","depth":3},{"value":"Step 8: Authorisation","id":"step-8-authorisation","depth":3},{"value":"Step 9: Authorisation result","id":"step-9-authorisation-result","depth":3},{"value":"Additional 3DS callbacks","id":"additional-3ds-callbacks","depth":2},{"value":"Authentication status callbacks","id":"authentication-status-callbacks","depth":3},{"value":"Challenge flow callbacks","id":"challenge-flow-callbacks","depth":3},{"value":"Implementation","id":"implementation","depth":2},{"value":"Before you start","id":"before-you-start","depth":3},{"value":"Step 1: Configure your SDK","id":"step-1-configure-your-sdk","depth":3},{"value":"Step 2: Implement callbacks","id":"step-2-implement-callbacks","depth":3},{"value":"Step 3: Handle common scenarios","id":"step-3-handle-common-scenarios","depth":3},{"value":"Conditional 3DS","id":"conditional-3ds","depth":4},{"value":"Different transaction types","id":"different-transaction-types","depth":4},{"value":"Step 4: Handle errors","id":"step-4-handle-errors","depth":3},{"value":"Complete example","id":"complete-example","depth":2},{"value":"Callback data","id":"callback-data","depth":2},{"value":"onPostInitiateAuthentication","id":"onpostinitiateauthentication","depth":3},{"value":"Success","id":"success","depth":4},{"value":"Failure","id":"failure","depth":4},{"value":"onPreAuthentication","id":"onpreauthentication","depth":3},{"value":"onPostAuthentication","id":"onpostauthentication","depth":3},{"value":"3DS Authentication Details","id":"3ds-authentication-details","depth":4},{"value":"Authentication result","id":"authentication-result","depth":4},{"value":"Success","id":"success-1","depth":5},{"value":"onPreAuthorisation","id":"onpreauthorisation","depth":3},{"value":"Pre-authorisation data","id":"pre-authorisation-data","depth":4}],"frontmatter":{"seo":{"title":"3DS transactions"}},"lastModified":"2026-06-12T11:56:36.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/card/3ds","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}