From 73716fc8b5a9541fed9aeb3b8b292803bd3c4dfc Mon Sep 17 00:00:00 2001 From: ChiragKV-Juspay Date: Mon, 15 Sep 2025 14:37:41 +0530 Subject: [PATCH] added trident integration and made changes to the api lib --- app/build.gradle.kts | 6 +- .../io/hyperswitch/demo_app/MainActivity.kt | 592 +++++++++++++----- app/src/main/res/layout/activity_main.xml | 55 ++ .../hyperswitch/modular_3ds/ThreeDSManager.kt | 81 ++- .../api/AuthenticationConfiguration.kt | 13 + .../api/AuthenticationRequestParameters.kt | 13 + .../modular_3ds/api/AuthenticationResult.kt | 10 + .../modular_3ds/api/ChallengeEvents.kt | 40 ++ .../api/ThreeDSAuthenticationSession.kt | 87 +++ .../modular_3ds/api/ThreeDSSession.kt | 55 ++ .../modular_3ds/api/ThreeDSTransaction.kt | 82 +++ .../callbacks/AuthParametersCallback.kt | 24 + .../callbacks/ChallengeCallback.kt | 12 +- .../callbacks/TransactionCallback.kt | 24 + .../modular_3ds/models/ChallengeParameters.kt | 6 +- .../models/ThreeDSConfiguration.kt | 3 - .../modular_3ds/models/TransactionRequest.kt | 49 ++ .../modular_3ds/provider/ThreeDSProvider.kt | 26 +- .../modular_3ds/mock/MockThreeDSProvider.kt | 17 +- .../netcetera/NetceteraThreeDSProvider.kt | 125 +++- .../trident/TridentConfigurator.kt | 28 + .../trident/TridentThreeDSProvider.kt | 464 ++++++++++---- 22 files changed, 1499 insertions(+), 313 deletions(-) create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/AuthenticationConfiguration.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/AuthenticationRequestParameters.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/AuthenticationResult.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/ChallengeEvents.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/ThreeDSAuthenticationSession.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/ThreeDSSession.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/api/ThreeDSTransaction.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/callbacks/AuthParametersCallback.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/callbacks/TransactionCallback.kt create mode 100644 modular-3ds-api/src/main/java/io/hyperswitch/modular_3ds/models/TransactionRequest.kt create mode 100644 modular-3ds-trident/src/main/java/io/hyperswitch/modular_3ds/trident/TridentConfigurator.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 85ffa99..4865e71 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -41,8 +41,12 @@ dependencies { // modular 3DS library implementation(project(":modular-3ds-api")) // implementation(project(":modular-3ds-mock")) - implementation(project(":modular-3ds-netcetera")) + implementation(project(":modular-3ds-trident")) // UI dependencies for demo implementation(libs.androidx.appcompat) + + // HTTP client for API calls + implementation("com.squareup.okhttp3:okhttp:4.12.0") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") } diff --git a/app/src/main/java/io/hyperswitch/demo_app/MainActivity.kt b/app/src/main/java/io/hyperswitch/demo_app/MainActivity.kt index b51bd71..a03cbac 100644 --- a/app/src/main/java/io/hyperswitch/demo_app/MainActivity.kt +++ b/app/src/main/java/io/hyperswitch/demo_app/MainActivity.kt @@ -1,198 +1,488 @@ package io.hyperswitch.demo_app +import android.app.Activity import android.os.Bundle import android.util.Log -import android.view.Gravity -import android.view.ViewGroup import android.widget.Button -import android.widget.LinearLayout import android.widget.TextView -import android.widget.Toast -import androidx.appcompat.app.AppCompatActivity -import io.hyperswitch.modular_3ds.ThreeDSManager -import io.hyperswitch.modular_3ds.callbacks.AuthenticationCallback -import io.hyperswitch.modular_3ds.callbacks.InitializationCallback -import io.hyperswitch.modular_3ds.models.* -import io.hyperswitch.modular_3ds.netcetera.NetceteraProviderFactory +import io.hyperswitch.modular_3ds.models.ThreeDSEnvironment +import io.hyperswitch.modular_3ds.models.UiCustomization import io.hyperswitch.modular_3ds.provider.ProviderRegistry +import io.hyperswitch.modular_3ds.trident.TridentProviderFactory +import io.hyperswitch.modular_3ds.api.* +import io.hyperswitch.modular_3ds.models.ChallengeParameters +import okhttp3.* +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody.Companion.toRequestBody +import org.json.JSONObject +import java.io.IOException + +class MainActivity : Activity() { -class MainActivity : AppCompatActivity() { - private lateinit var statusText: TextView - private lateinit var initButton: Button - private lateinit var authButton: Button - private lateinit var providersButton: Button + private var publishKey: String = "" + private var paymentIntentClientSecret: String = "" + + // New merchant-facing API objects + private lateinit var authenticationSession: ThreeDSAuthenticationSession + private var session: ThreeDSSession? = null + private var transaction: ThreeDSTransaction? = null + private var aReqParams: AuthenticationRequestParameters? = null + private var challengeParameters: ChallengeParameters? = null + + // API credentials and data + private val apiKey = "" + private val profileId = "" + private val baseUrl = "https://sandbox.hyperswitch.io" + private var authenticationId: String? = null - private val threeDSManager = ThreeDSManager.getInstance() + // Eligibility response data + private var threeDsServerTransactionId: String? = null + private var messageVersion: String? = null + private var directoryServerId: String? = null + // HTTP client - use singleton to avoid creating multiple instances + private val httpClient by lazy { + OkHttpClient.Builder() + .connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS) + .readTimeout(15, java.util.concurrent.TimeUnit.SECONDS) + .writeTimeout(15, java.util.concurrent.TimeUnit.SECONDS) + .build() + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - // Register mock provider for testing - ProviderRegistry.registerProvider(NetceteraProviderFactory()) - - setupUI() + setContentView(R.layout.activity_main) + + statusText = findViewById(R.id.statusText) + + // Register providers for testing + ProviderRegistry.registerProvider(TridentProviderFactory()) + + // Initialize ThreeDSAuthenticationSession using the new unified 3DS library + authenticationSession = ThreeDSAuthenticationSession(this, publishKey) + + setupButtons() } - - private fun setupUI() { - val layout = LinearLayout(this).apply { - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - orientation = LinearLayout.VERTICAL - gravity = Gravity.CENTER - setPadding(32, 32, 32, 32) - } - - val titleText = TextView(this).apply { - text = "Modular 3DS Demo" - textSize = 24f - gravity = Gravity.CENTER + + override fun onDestroy() { + super.onDestroy() + // Clean up resources to prevent memory leaks + session = null + transaction = null + aReqParams = null + challengeParameters = null + + Log.d("ThreeDSTest", "Cleared activity references") + + // Cancel any pending HTTP calls + try { + httpClient.dispatcher.executorService.shutdown() + } catch (e: Exception) { + Log.w("ThreeDSTest", "Error shutting down HTTP client: ${e.message}") } - - statusText = TextView(this).apply { - text = "Ready to test 3DS authentication" - textSize = 16f - gravity = Gravity.CENTER - setPadding(0, 32, 0, 32) + } + + private fun setupButtons() { + findViewById