diff --git a/android/app/src/main/java/com/naviapp/analytics/deeplink/DeeplinkManager.kt b/android/app/src/main/java/com/naviapp/analytics/deeplink/DeeplinkManager.kt index f0fbbc875c..5aac8c0fea 100644 --- a/android/app/src/main/java/com/naviapp/analytics/deeplink/DeeplinkManager.kt +++ b/android/app/src/main/java/com/naviapp/analytics/deeplink/DeeplinkManager.kt @@ -329,12 +329,7 @@ class DeeplinkManager( } else if (ctaData != null) { navigateTo(activity, ctaData, bundle = bundle, finish = finish, clearTask = clearTask) } else if (bundle.getString(IS_UPI_DYNAMIC_DEEP_LINK) == TRUE) { - val ctaDataForUpiDeepLink = - if (NaviApplication.instance.naviPayManager.get().isUserOnboarded()) { - CtaData(url = url) - } else { - CtaData(url = bundle.getString(NAVI_PAY_HOME_PAGE_URL)) - } + val ctaDataForUpiDeepLink = CtaData(url = url) navigateTo( activity, ctaDataForUpiDeepLink, diff --git a/android/app/src/main/java/com/naviapp/common/helper/UpiSdkHelperImpl.kt b/android/app/src/main/java/com/naviapp/common/helper/UpiSdkHelperImpl.kt index ad954dee4f..73e83ec039 100644 --- a/android/app/src/main/java/com/naviapp/common/helper/UpiSdkHelperImpl.kt +++ b/android/app/src/main/java/com/naviapp/common/helper/UpiSdkHelperImpl.kt @@ -21,10 +21,6 @@ class UpiSdkHelperImpl(private val naviPayManagerProvider: Lazy) private val upiSdkAnalytics = UpiSdkAnalytics() - override fun isUserOnboarded(): Boolean { - return naviPayManagerProvider.get().isUserOnboarded() - } - override suspend fun getDataByType(type: UpiDataType): JSONObject { upiSdkAnalytics.onDataRequest(type) return naviPayManagerProvider.get().getDataByType(type) diff --git a/android/app/src/main/java/com/naviapp/launcher/helper/LaunchEventsTracker.kt b/android/app/src/main/java/com/naviapp/launcher/helper/LaunchEventsTracker.kt index daf5f7165d..eaa54cacd9 100644 --- a/android/app/src/main/java/com/naviapp/launcher/helper/LaunchEventsTracker.kt +++ b/android/app/src/main/java/com/naviapp/launcher/helper/LaunchEventsTracker.kt @@ -27,6 +27,9 @@ import com.naviapp.utils.APP_VERSION import com.naviapp.utils.toggleNaviPayIntentActivityState import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch class LaunchEventsTracker @Inject @@ -125,16 +128,20 @@ constructor( } private fun checkAndEnableNaviPayIntentActivity() { - val prevSessionVersion = PreferenceManager.getIntPreferenceApp(APP_VERSION) - val currentVersion = BuildConfig.VERSION_CODE - if (prevSessionVersion != currentVersion) { - val shouldEnableNaviPayIntentActivity = - FirebaseRemoteConfigHelper.getBoolean( - key = FirebaseRemoteConfigHelper.NAVI_PAY_INTENT_ACTIVITY_CHECK_ENABLED, - defaultValue = true, - ) - if (shouldEnableNaviPayIntentActivity && naviPayManager.isUserOnboarded()) { - toggleNaviPayIntentActivityState(shouldEnable = true) + CoroutineScope(Dispatchers.IO).launch { + val prevSessionVersion = PreferenceManager.getIntPreferenceApp(APP_VERSION) + val currentVersion = BuildConfig.VERSION_CODE + if (prevSessionVersion != currentVersion) { + val shouldEnableNaviPayIntentActivity = + FirebaseRemoteConfigHelper.getBoolean( + key = FirebaseRemoteConfigHelper.NAVI_PAY_INTENT_ACTIVITY_CHECK_ENABLED, + defaultValue = true, + ) + if ( + shouldEnableNaviPayIntentActivity && naviPayManager.isUserOnboardedForAnyPsp() + ) { + toggleNaviPayIntentActivityState(shouldEnable = true) + } } } } diff --git a/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkConstants.kt b/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkConstants.kt index a9bbd1077d..7e5c76b25c 100644 --- a/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkConstants.kt +++ b/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkConstants.kt @@ -24,7 +24,6 @@ const val NAVI_PAY_ACTION = "naviPayAction" const val DATA = "data" const val ERRORS = "errors" const val IS_ONBOARDED = "isOnboarded" -const val CUSTOMER_STATUS = "customerStatus" const val CONNECTED_ACCOUNTS = "connectedAccounts" const val BANK_ACCOUNT_ID = "bankAccountId" const val NAME = "name" diff --git a/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkHelper.kt b/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkHelper.kt index 7ef0a80424..7403fce8f6 100644 --- a/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkHelper.kt +++ b/android/navi-common/src/main/java/com/navi/common/upi/UpiSdkHelper.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2024 by Navi Technologies Limited + * * Copyright © 2024-2025 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -13,9 +13,6 @@ import androidx.activity.result.ActivityResultLauncher import org.json.JSONObject interface UpiSdkHelper { - - fun isUserOnboarded(): Boolean - suspend fun getDataByType(type: UpiDataType): JSONObject fun startAction(activity: Activity, launcher: ActivityResultLauncher, data: JSONObject) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt index d09d16236b..e9739c317b 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/analytics/NaviPayAnalytics.kt @@ -24,6 +24,7 @@ import com.navi.pay.common.model.view.DeviceData import com.navi.pay.common.model.view.DeviceDetails import com.navi.pay.common.model.view.NaviPayErrorConfig import com.navi.pay.common.model.view.NetworkProvider +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.SimInfo import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.utils.NaviPayCommonUtils.toGetSimInfo @@ -889,8 +890,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -902,8 +903,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -921,8 +922,8 @@ class NaviPayAnalytics private constructor() { Pair("no_of_credit_accounts", creditAccounts.toString()), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -936,8 +937,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -957,8 +958,8 @@ class NaviPayAnalytics private constructor() { "filteredLinkedAccounts" to filteredLinkedAccounts.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -979,7 +980,7 @@ class NaviPayAnalytics private constructor() { linkedAccountsScreenSource: LinkedAccountsScreenSource, linkedAccounts: List, filteredLinkedAccounts: List, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map, ) { NaviTrackEvent.trackEventOnClickStream( eventName = "NaviPay_NoLinkedAccountsScreen_Landed", @@ -988,35 +989,35 @@ class NaviPayAnalytics private constructor() { "linkedAccountsScreenSource" to linkedAccountsScreenSource.toString(), "linkedAccounts" to linkedAccounts.toString(), "filteredLinkedAccounts" to filteredLinkedAccounts.toString(), - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } fun onNoLinkedAccountsScreenAddAccountButtonClicked( linkedAccountsScreenSource: LinkedAccountsScreenSource, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map, ) { NaviTrackEvent.trackEventOnClickStream( eventName = "NaviPay_NoLinkedAccountsScreen_AddAccountButtonClicked", eventValues = mapOf( "linkedAccountsScreenSource" to linkedAccountsScreenSource.toString(), - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } fun onAddAccountClicked( linkedAccountsScreenSource: LinkedAccountsScreenSource, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map, ) { NaviTrackEvent.trackEventOnClickStream( eventName = "NaviPay_AddAccount_Clicked", eventValues = mapOf( "linkedAccountsScreenSource" to linkedAccountsScreenSource.toString(), - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } @@ -1367,8 +1368,8 @@ class NaviPayAnalytics private constructor() { Pair("isPermissionGranted", isPermissionGranted.toString()), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1381,8 +1382,8 @@ class NaviPayAnalytics private constructor() { "qrContent" to qrContent, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1398,8 +1399,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), eventName to eventValue, ), ) @@ -1412,8 +1413,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1431,8 +1432,8 @@ class NaviPayAnalytics private constructor() { Pair("qrCount", qrCount.toString()), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1450,8 +1451,8 @@ class NaviPayAnalytics private constructor() { Pair("Qr_type", qrType), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "uriType" to uriType.name, "isQrFromUploadImage" to isQrFromUploadImage.toString(), ), @@ -1466,8 +1467,8 @@ class NaviPayAnalytics private constructor() { Pair("isFlashOn", isFlashOn.toString()), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1508,8 +1509,8 @@ class NaviPayAnalytics private constructor() { Pair("streamState", streamState.name), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1521,8 +1522,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1538,8 +1539,8 @@ class NaviPayAnalytics private constructor() { "showRationale" to showRationale.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1551,8 +1552,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1601,8 +1602,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1618,8 +1619,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1633,8 +1634,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1646,8 +1647,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1659,8 +1660,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1679,8 +1680,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1699,8 +1700,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1737,8 +1738,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1760,8 +1761,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1783,8 +1784,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1801,8 +1802,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1818,8 +1819,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1833,8 +1834,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1851,8 +1852,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "isPermissionGranted" to isPermissionGranted.toString(), "isContactListEmpty" to isContactListEmpty.toString(), "isFrequentTransactionListEmpty" to isFrequentOrderListEmpty.toString(), @@ -1877,8 +1878,8 @@ class NaviPayAnalytics private constructor() { "fromFrequent" to isFromFrequentOrderList.toString(), "searchQuery" to currentSearchQuery, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "isPermissionGranted" to isPermissionGranted.toString(), "orderOfTransactionItem" to orderOfOrderItem.toString(), ), @@ -1899,8 +1900,8 @@ class NaviPayAnalytics private constructor() { naviPaySessionAttributes["naviPaySessionId"].orEmpty(), ), Pair( - "naviPayCustomerStatus", - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap", + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ), ) @@ -1917,8 +1918,8 @@ class NaviPayAnalytics private constructor() { "error_message" to errorMessage, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1930,8 +1931,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1947,8 +1948,8 @@ class NaviPayAnalytics private constructor() { "showRationale" to showRationale.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1960,8 +1961,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1977,8 +1978,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -1994,8 +1995,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -2004,13 +2005,13 @@ class NaviPayAnalytics private constructor() { inner class NaviPayUpiNumber { fun onUpiNumberScreenLanded( upiNumberLinkedAccounts: List, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Landed_v2", mapOf( "upiNumberAccountsLinked" to upiNumberLinkedAccounts.size.toString(), - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } @@ -2031,12 +2032,12 @@ class NaviPayAnalytics private constructor() { maskedAccountNumber: String, upiNumber: String, isPrimary: Boolean, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_LinkNow_Clicked_v2", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bacc" to maskedAccountNumber, "bankCode" to bankCode, @@ -2046,26 +2047,28 @@ class NaviPayAnalytics private constructor() { ) } - fun onAddNewUpiNumberBannerClick(naviPayCustomerStatus: NaviPayCustomerStatus) { + fun onAddNewUpiNumberBannerClick( + naviPayCustomerStatusMap: Map? + ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_ClickHere_Clicked_v2", - mapOf("naviPayCustomerStatus" to naviPayCustomerStatus.toString()), + mapOf("naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString()), ) } fun onAddNewUpiNumberMaximumLimitReachedClick( - naviPayCustomerStatus: NaviPayCustomerStatus + naviPayCustomerStatusMap: Map? ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Limit_Reached_BottomSheet_Landed", - mapOf("naviPayCustomerStatus" to naviPayCustomerStatus.toString()), + mapOf("naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString()), ) } - fun onHelpClick(naviPayCustomerStatus: NaviPayCustomerStatus) { + fun onHelpClick(naviPayCustomerStatusMap: Map?) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Help_Clicked_v2", - mapOf("naviPayCustomerStatus" to naviPayCustomerStatus.toString()), + mapOf("naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString()), ) } @@ -2082,12 +2085,12 @@ class NaviPayAnalytics private constructor() { maskedAccountNumber: String, upiNumber: String, isPrimary: Boolean, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_CopyUpiNumberClicked_v2", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bankCode" to bankCode, "bacc" to maskedAccountNumber, @@ -2103,12 +2106,12 @@ class NaviPayAnalytics private constructor() { maskedAccountNumber: String, upiNumber: String, isPrimary: Boolean, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_KebabMenuClicked_v2", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bacc" to maskedAccountNumber, "bankCode" to bankCode, @@ -2123,12 +2126,12 @@ class NaviPayAnalytics private constructor() { bankCode: String, maskedAccountNumber: String, upiNumber: String, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Confimation_BottomSheet_Landed", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bankCode" to bankCode, "bacc" to maskedAccountNumber, @@ -2142,12 +2145,12 @@ class NaviPayAnalytics private constructor() { bankCode: String, maskedAccountNumber: String, upiNumber: String, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Confimation_BottomSheet_Cancel_Clicked", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bankCode" to bankCode, "bacc" to maskedAccountNumber, @@ -2161,12 +2164,12 @@ class NaviPayAnalytics private constructor() { bankCode: String, maskedAccountNumber: String, upiNumber: String, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_Confimation_BottomSheet_Confirm_Clicked", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentMappedVpa" to currentMappedVpa, "bankCode" to bankCode, "bacc" to maskedAccountNumber, @@ -2176,14 +2179,14 @@ class NaviPayAnalytics private constructor() { } fun onLinkPhoneNumberRetryBottomSheetLanded( - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, bankCode: String, maskedAccountNumber: String, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_PortedOut_UnabletoFetch_CurrentUPIID_BottomSheet_Landed", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "bankCode" to bankCode, "bacc" to maskedAccountNumber, ), @@ -2191,14 +2194,14 @@ class NaviPayAnalytics private constructor() { } fun onLinkPhoneNumberRetryClicked( - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, maskedAccountNumber: String, bankCode: String, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_PortedOut_UnabletoFetch_CurrentUPIID_BottomSheet_Landed_Retry_Clicked", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "bankCode" to bankCode, "bacc" to maskedAccountNumber, ), @@ -2207,14 +2210,14 @@ class NaviPayAnalytics private constructor() { fun onActivateClick( upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, currentUpiNumber: UpiNumber, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_ActivateClicked_v2", mapOf( "bankCode" to upiNumberLinkedAccountEntity.bankCode, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "currentUpiNumber" to currentUpiNumber.toString(), ), ) @@ -2222,7 +2225,7 @@ class NaviPayAnalytics private constructor() { fun onActivateConfirmClick( upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, currentUpiNumber: String, ) { NaviTrackEvent.trackEventOnClickStream( @@ -2230,20 +2233,20 @@ class NaviPayAnalytics private constructor() { mapOf( "bankCode" to upiNumberLinkedAccountEntity.bankCode, "currentUpiNumber" to currentUpiNumber, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } fun onActivateCancelClick( upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_CancelActivateClicked_v2", mapOf( "bankCode" to upiNumberLinkedAccountEntity.bankCode, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } @@ -2252,38 +2255,41 @@ class NaviPayAnalytics private constructor() { NaviTrackEvent.trackEventOnClickStream("NaviPay_UpiNumber_DeleteUPINumber_Clicked_v2") } - fun onMenuOptionSelected(optionId: String, naviPayCustomerStatus: NaviPayCustomerStatus) { + fun onMenuOptionSelected( + optionId: String, + naviPayCustomerStatusMap: Map?, + ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_MenuOptionSelected_v2", mapOf( "optionId" to optionId, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } fun onMenuOptionCancelClicked( optionId: String, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_MenuOptionCancelClicked_v2", mapOf( "optionId" to optionId, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } fun onLinkToOtherBankClick( newBankCode: String, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_UpiNumber_LinkToOtherBankClicked_v2", mapOf( "newBankCode" to newBankCode, - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), ), ) } @@ -2792,8 +2798,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -2819,8 +2825,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -2950,8 +2956,8 @@ class NaviPayAnalytics private constructor() { "txnType" to txnType, "purposeCode" to purposeCode, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -2969,8 +2975,8 @@ class NaviPayAnalytics private constructor() { "txnType" to txnType, "purposeCode" to purposeCode, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -2989,8 +2995,8 @@ class NaviPayAnalytics private constructor() { "txnType" to txnType, "purposeCode" to purposeCode, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "ctaName" to ctaName, ), ) @@ -3011,8 +3017,8 @@ class NaviPayAnalytics private constructor() { "txnType" to txnType, "purposeCode" to purposeCode, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "orderReferenceId" to orderReferenceId, "ctaName" to ctaName, ), @@ -3098,8 +3104,8 @@ class NaviPayAnalytics private constructor() { "errorConfig" to errorConfig.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3119,8 +3125,8 @@ class NaviPayAnalytics private constructor() { "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "isActivityRecreated" to isActivityRecreated.toString(), ), ) @@ -3133,8 +3139,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3157,8 +3163,8 @@ class NaviPayAnalytics private constructor() { "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3180,8 +3186,8 @@ class NaviPayAnalytics private constructor() { "statusCode" to error?.code.orEmpty(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3204,8 +3210,8 @@ class NaviPayAnalytics private constructor() { "purposeCode" to purposeCode, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3228,8 +3234,8 @@ class NaviPayAnalytics private constructor() { "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3242,8 +3248,8 @@ class NaviPayAnalytics private constructor() { Pair("source", "Collect_request"), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3256,8 +3262,8 @@ class NaviPayAnalytics private constructor() { Pair("source", "Collect_request"), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3271,8 +3277,8 @@ class NaviPayAnalytics private constructor() { "upiRequestId" to upiRequestId, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3285,8 +3291,8 @@ class NaviPayAnalytics private constructor() { Pair("source", "Collect_request"), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3316,8 +3322,8 @@ class NaviPayAnalytics private constructor() { "bankAccountUniqueId" to selectedBankAccount.accountId, "bankUptimeStatus" to bankUptimeStatus, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "bankDetails" to bankDetails.toString(), ), ) @@ -3335,8 +3341,8 @@ class NaviPayAnalytics private constructor() { Pair("transactionType", transactionType.name), "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3364,8 +3370,8 @@ class NaviPayAnalytics private constructor() { "bankAccountUniqueId" to selectedBankAccount.accountId, "bankUptimeStatus" to bankUptimeStatus, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3412,8 +3418,8 @@ class NaviPayAnalytics private constructor() { "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3430,8 +3436,8 @@ class NaviPayAnalytics private constructor() { "bankAccountUniqueId" to selectedBankAccount.accountId, "bankUptimeStatus" to bankUptimeStatus, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3448,8 +3454,8 @@ class NaviPayAnalytics private constructor() { "bankAccountUniqueId" to selectedBankAccount.accountId, "bankUptimeStatus" to bankUptimeStatus, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3461,8 +3467,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3482,8 +3488,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "isNotesReadOnly" to isNotesReadOnly.toString(), ), ) @@ -3503,8 +3509,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3525,8 +3531,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3548,8 +3554,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "arcAttributes" to arcAttributes, ), ) @@ -3562,8 +3568,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3575,8 +3581,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3595,8 +3601,8 @@ class NaviPayAnalytics private constructor() { "source2" to source.asString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3608,8 +3614,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3626,8 +3632,8 @@ class NaviPayAnalytics private constructor() { sendMoneyAdditionalInfoRequest.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3639,8 +3645,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3661,8 +3667,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3674,8 +3680,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3687,8 +3693,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3700,8 +3706,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3723,8 +3729,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "bacc_unique_id" to linkedAccount.accountId, "bank_account_type" to AccountType.getAccountType(linkedAccount.accountType).name, @@ -3746,8 +3752,8 @@ class NaviPayAnalytics private constructor() { "source2" to (source?.asString() ?: ""), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "bacc_unique_id" to linkedAccount.accountId, "bank_account_type" to AccountType.getAccountType(linkedAccount.accountType).name, @@ -3804,8 +3810,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "attributeMap" to attributeMap, ), ) @@ -3823,8 +3829,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "isFromAccountSelectionBottomSheet" to isFromAccountSelectionBottomSheet.toString(), ), @@ -3865,8 +3871,8 @@ class NaviPayAnalytics private constructor() { "Lite Setup Done" to isUPILiteSetupDone.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "arcAttributes" to arcAttributes, ), ) @@ -3885,8 +3891,8 @@ class NaviPayAnalytics private constructor() { "Lite Setup Done" to isUPILiteSetupDone.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3899,8 +3905,8 @@ class NaviPayAnalytics private constructor() { "amount" to value, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3913,8 +3919,8 @@ class NaviPayAnalytics private constructor() { "source" to source, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -3948,8 +3954,8 @@ class NaviPayAnalytics private constructor() { "Source" to source, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "autoTopUp" to autoTopUp.toString(), "supportsAutoTopUp" to supportsAutoTopUp.toString(), "activeLiteAccountPresent" to activeLiteAccountPresent.toString(), @@ -3979,8 +3985,8 @@ class NaviPayAnalytics private constructor() { "Source" to source, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "autoTopUp" to autoTopUp.toString(), "supportsAutoTopUp" to supportsAutoTopUp.toString(), ), @@ -4009,8 +4015,8 @@ class NaviPayAnalytics private constructor() { "Source" to source, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "autoTopUp" to autoTopUp.toString(), "supportsAutoTopUp" to supportsAutoTopUp.toString(), ), @@ -4075,8 +4081,8 @@ class NaviPayAnalytics private constructor() { "Lite Setup Done" to isUpiLiteSetupDone.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4088,8 +4094,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4101,8 +4107,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4118,8 +4124,8 @@ class NaviPayAnalytics private constructor() { "Balance in Lite wallet" to isBalanceNonZero.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4131,8 +4137,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4157,8 +4163,8 @@ class NaviPayAnalytics private constructor() { "LoadMoney Type" to loadMoneyType, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4178,8 +4184,8 @@ class NaviPayAnalytics private constructor() { "Lite Setup Done" to isUPILiteSetupDone.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4194,8 +4200,8 @@ class NaviPayAnalytics private constructor() { mapOf( "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), "functionName" to functionName, ), ) @@ -4271,10 +4277,10 @@ class NaviPayAnalytics private constructor() { } inner class NaviPayAddNewUpiNumber { - fun onLanded(naviPayCustomerStatus: NaviPayCustomerStatus) { + fun onLanded(naviPayCustomerStatusMap: Map) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_AddNewUpiNumber_Landed_v2", - mapOf("naviPayCustomerStatus" to naviPayCustomerStatus.toString()), + mapOf("naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString()), ) } @@ -4283,14 +4289,14 @@ class NaviPayAnalytics private constructor() { } fun onLinkUpiNumberClick( - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map, selectedBankAccount: String, upiNumber: String, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_AddNewUpiNumber_LinktoNavi_Clicked", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "bacc" to selectedBankAccount, "upiNumber" to upiNumber, ), @@ -4298,13 +4304,13 @@ class NaviPayAnalytics private constructor() { } fun onDropDownClick( - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map, selectedBankAccount: String, ) { NaviTrackEvent.trackEventOnClickStream( "NaviPay_AddNewUpiNumber_BankDropDown_Clicked", mapOf( - "naviPayCustomerStatus" to naviPayCustomerStatus.toString(), + "naviPayCustomerStatusMap" to naviPayCustomerStatusMap.toString(), "bacc" to selectedBankAccount, ), ) @@ -4608,8 +4614,8 @@ class NaviPayAnalytics private constructor() { "tab" to tab, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4644,8 +4650,8 @@ class NaviPayAnalytics private constructor() { "from_saved" to fromSaved.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4663,8 +4669,8 @@ class NaviPayAnalytics private constructor() { "from_saved" to fromSaved.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4680,8 +4686,8 @@ class NaviPayAnalytics private constructor() { "tab" to tab, "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4697,8 +4703,8 @@ class NaviPayAnalytics private constructor() { "savedBeneficiaryEntity" to savedBeneficiaryEntity.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4714,8 +4720,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } @@ -4731,8 +4737,8 @@ class NaviPayAnalytics private constructor() { "numberOfOffers" to numberOfOffers.toString(), "naviPaySessionId" to naviPaySessionAttributes["naviPaySessionId"].orEmpty(), - "naviPayCustomerStatus" to - naviPaySessionAttributes["naviPayCustomerStatus"].orEmpty(), + "naviPayCustomerStatusMap" to + naviPaySessionAttributes["naviPayCustomerStatusMap"].orEmpty(), ), ) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/view/NaviPaySessionHelper.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/view/NaviPaySessionHelper.kt index 488fb72fad..5d2e7a4d10 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/view/NaviPaySessionHelper.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/view/NaviPaySessionHelper.kt @@ -1,24 +1,32 @@ /* * - * * Copyright © 2024 by Navi Technologies Limited + * * Copyright © 2024-2025 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ package com.navi.pay.common.model.view -import com.navi.pay.common.setup.NaviPayManager +import com.navi.pay.onboarding.binding.repository.NaviPayOnboardingRepository import java.util.UUID import javax.inject.Inject import javax.inject.Singleton @Singleton -class NaviPaySessionHelper @Inject constructor(private val naviPayManager: NaviPayManager) { +class NaviPaySessionHelper +@Inject +constructor(private val naviPayOnboardingRepository: NaviPayOnboardingRepository) { private val naviPaySessionAttributes: HashMap = hashMapOf() - fun createNewSessionId() { + suspend fun createNewSessionId() { naviPaySessionAttributes["naviPaySessionId"] = UUID.randomUUID().toString() - naviPaySessionAttributes["naviPayCustomerStatus"] = naviPayManager.getCustomerStatus().name + naviPaySessionAttributes["naviPayCustomerStatusMap"] = + naviPayOnboardingRepository + .getAllCustomerOnboardingData() + .associate { customerOnboardingEntity -> + customerOnboardingEntity.pspType to customerOnboardingEntity.customerStatus + } + .toString() } fun setCustomerStatus(customerStatus: String) { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/model/SettingResponse.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/model/SettingResponse.kt index b0b2bb0dac..2784f11032 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/model/SettingResponse.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/model/SettingResponse.kt @@ -10,15 +10,13 @@ package com.navi.pay.common.settingscreen.model import android.net.Uri import com.google.gson.annotations.SerializedName import com.navi.base.model.ActionData -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity data class SettingResponse( @SerializedName("qrList") val qrList: List? = null, @SerializedName("config") val config: SettingConfigContent? = null, @SerializedName("lastUpdatedTs") val lastUpdatedTs: Long = System.currentTimeMillis(), - @SerializedName("naviPayCustomerStatus") - val naviPayCustomerStatus: NaviPayCustomerStatus = NaviPayCustomerStatus.NOT_SET, + @SerializedName("isUserOnboardedForAnyPsp") val isUserOnboardedForAnyPsp: Boolean = false, ) data class SettingConfigContent( diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt index 5fffca3d43..c3f74c029f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/ui/UPISettingSDK.kt @@ -200,7 +200,7 @@ fun UPISettingSDK( action.actionData?.let { actionData -> settingSDKViewmodel.handleActionCta( actionData = actionData, - naviPayCustomerStatus = settingResponse.naviPayCustomerStatus, + isUserDeviceBoundForAnyPsp = settingResponse.isUserOnboardedForAnyPsp, ) } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/utils/SettingsSDKUtils.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/utils/SettingsSDKUtils.kt index 3a08e56b02..cee33a91db 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/utils/SettingsSDKUtils.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/utils/SettingsSDKUtils.kt @@ -25,7 +25,6 @@ import com.navi.common.upi.IS_ONBOARDING_REQUIRED import com.navi.common.utils.createBitmapFromView import com.navi.common.utils.log import com.navi.pay.common.settingscreen.model.QrDetails -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.utils.NaviPayNotificationHandler import com.navi.pay.databinding.LayoutShareQrBinding import com.navi.pay.onboarding.account.add.model.view.AccountType @@ -136,11 +135,8 @@ fun getFilteredLinkedAccounts( return filteredLinkedAccountEntity } -fun isOnboardingRequired( - naviPayCustomerStatus: NaviPayCustomerStatus, - actionData: ActionData?, -): Boolean { - if (naviPayCustomerStatus == NaviPayCustomerStatus.LINKED_VPA) return false +fun isOnboardingRequired(isUserDeviceBoundForAnyPsp: Boolean, actionData: ActionData?): Boolean { + if (isUserDeviceBoundForAnyPsp) return false val metadata = actionData?.parameters?.firstOrNull { it.key == IS_ONBOARDING_REQUIRED } return metadata?.value == "true" diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt index a0bdfc0bb0..ce927290b1 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/settingscreen/viewmodel/SettingSDKViewmodel.kt @@ -21,7 +21,6 @@ import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.settingscreen.model.SettingResponse import com.navi.pay.common.settingscreen.utils.isOnboardingRequired import com.navi.pay.common.setup.NaviPayManager -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.utils.NaviPayOnboardingNavigator import com.navi.pay.common.viewmodel.NaviPayBaseVM @@ -212,12 +211,12 @@ constructor( screenLifecycleState = state } - fun handleActionCta(actionData: ActionData, naviPayCustomerStatus: NaviPayCustomerStatus) { + fun handleActionCta(actionData: ActionData, isUserDeviceBoundForAnyPsp: Boolean) { viewModelScope.launch(Dispatchers.IO) { naviSettingSDKAnalytics.onCtaClicked(actionData) if ( isOnboardingRequired( - naviPayCustomerStatus = naviPayCustomerStatus, + isUserDeviceBoundForAnyPsp = isUserDeviceBoundForAnyPsp, actionData = actionData, ) ) { @@ -225,7 +224,7 @@ constructor( naviPayFlowType = NaviPayFlowType.DEVICE_BINDING, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp != null) { + if (pspEvaluationResult.onboardingDataEntity != null) { _navigateToCtaUrl.emit(actionData) } }, diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayCustomerStatusHandler.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayCustomerStatusHandler.kt index 12bed75584..f16c70a2d3 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayCustomerStatusHandler.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayCustomerStatusHandler.kt @@ -9,51 +9,84 @@ package com.navi.pay.common.setup import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.pay.common.model.view.NaviPaySessionHelper -import com.navi.pay.common.repository.SharedPreferenceRepository +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.utils.toggleNaviPayIntentActivityEnableState -import com.navi.pay.utils.KEY_CUSTOMER_STATUS +import com.navi.pay.onboarding.binding.repository.NaviPayOnboardingRepository import javax.inject.Inject class NaviPayCustomerStatusHandler @Inject constructor( - private val sharedPreferenceRepository: SharedPreferenceRepository, + private val naviPayOnboardingRepository: NaviPayOnboardingRepository, private val naviPaySessionHelper: NaviPaySessionHelper, ) { - suspend fun updateCustomerStatusAndHandleNaviPayIntentActivityState(customerStatus: String) { - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_CUSTOMER_STATUS, - value = customerStatus, + + suspend fun getAllCustomerOnboardingData() = + naviPayOnboardingRepository.getAllCustomerOnboardingData() + + suspend fun getCustomerStatus(pspType: PspType): NaviPayCustomerStatus { + val customerOnboardingEntity = + naviPayOnboardingRepository.getCustomerOnboardingEntity(pspType = pspType) + return customerOnboardingEntity?.customerStatus ?: NaviPayCustomerStatus.NOT_SET + } + + suspend fun isUserOnboarded(pspType: PspType): Boolean { + val customerOnboardingEntity = + naviPayOnboardingRepository.getCustomerOnboardingEntity(pspType = pspType) + return customerOnboardingEntity?.customerStatus == NaviPayCustomerStatus.LINKED_VPA + } + + suspend fun isUserOnboardedForAnyPsp(): Boolean { + val customerEntityList = naviPayOnboardingRepository.getAllCustomerOnboardingData() + + return customerEntityList.any { onboardingDataEntity -> + onboardingDataEntity.customerStatus == NaviPayCustomerStatus.LINKED_VPA + } + } + + suspend fun isUserDeviceBoundForAnyPsp(): Boolean { + val customerEntityList = naviPayOnboardingRepository.getAllCustomerOnboardingData() + + return customerEntityList.any { onboardingDataEntity -> + onboardingDataEntity.customerStatus.isBound + } + } + + suspend fun getCustomerStatusMap(): Map { + val customerEntityList = naviPayOnboardingRepository.getAllCustomerOnboardingData() + return customerEntityList.associate { it.pspType to it.customerStatus } + } + + suspend fun updateCustomerStatusAndHandleNaviPayIntentActivityState( + pspType: PspType, + customerStatus: NaviPayCustomerStatus, + ) { + naviPayOnboardingRepository.upsertCustomerOnboardingDataEntity( + pspType = pspType, + customerStatus = customerStatus, ) - naviPaySessionHelper.setCustomerStatus(customerStatus = customerStatus) - checkAndUpdateNaviPayIntentActivity(customerStatus) + naviPaySessionHelper.setCustomerStatus(customerStatus = customerStatus.name) + checkAndUpdateNaviPayIntentActivity() } - suspend fun getCustomerStatus(): NaviPayCustomerStatus { - val customerStatusString = sharedPreferenceRepository.getStringValue(KEY_CUSTOMER_STATUS) - return NaviPayCustomerStatus.entries.singleOrNull { - it.name.equals(customerStatusString, ignoreCase = true) - } ?: NaviPayCustomerStatus.NOT_SET - } - - fun getCustomerStatusOnMainThread(): NaviPayCustomerStatus { - val customerStatusString = - sharedPreferenceRepository.getStringValueOnSameThread(KEY_CUSTOMER_STATUS) - return NaviPayCustomerStatus.entries.singleOrNull { - it.name.equals(customerStatusString, ignoreCase = true) - } ?: NaviPayCustomerStatus.NOT_SET - } - - suspend fun clearCustomerStatus() { - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_CUSTOMER_STATUS, - value = "", + suspend fun upsertCustomerOnboardingDataEntity( + pspType: PspType, + customerStatus: NaviPayCustomerStatus? = null, + merchantCustomerId: String? = null, + deviceFingerPrint: String? = null, + ) { + naviPayOnboardingRepository.upsertCustomerOnboardingDataEntity( + pspType = pspType, + customerStatus = customerStatus, + merchantCustomerId = merchantCustomerId, + deviceFingerPrint = deviceFingerPrint, ) + checkAndUpdateNaviPayIntentActivity() } - private fun checkAndUpdateNaviPayIntentActivity(customerStatus: String) { - if (customerStatus == NaviPayCustomerStatus.LINKED_VPA.name) { + private suspend fun checkAndUpdateNaviPayIntentActivity() { + if (isUserOnboardedForAnyPsp()) { toggleNaviPayIntentActivityEnableState(shouldEnable = true) } else if ( FirebaseRemoteConfigHelper.getBoolean( @@ -64,4 +97,7 @@ constructor( toggleNaviPayIntentActivityEnableState(shouldEnable = false) } } + + suspend fun getCustomerOnboardingEntity(pspType: PspType) = + naviPayOnboardingRepository.getCustomerOnboardingEntity(pspType) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayManager.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayManager.kt index 95d52a9739..b3bfdec6b5 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayManager.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPayManager.kt @@ -21,11 +21,14 @@ import com.navi.common.upi.TYPE import com.navi.common.upi.UpiDataType import com.navi.common.utils.CommonUtils.getDisplayableAmount import com.navi.pay.common.model.view.DeviceData +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.UpiLiteActiveAccountInfo import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.settingscreen.model.SettingResponse import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.setup.model.NaviPaySetupStatus +import com.navi.pay.common.setup.model.NaviPaySetupSuccessDetails +import com.navi.pay.common.usecase.ClearOnboardingAndDeviceDataUseCase import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.NaviPayConfigUseCase import com.navi.pay.common.usecase.RefreshGenericOffersUseCase @@ -41,7 +44,6 @@ import com.navi.pay.db.NaviPayAppEncryptedDatabase import com.navi.pay.management.lite.models.NaviPayUpiLiteConfig import com.navi.pay.network.di.NaviPayGsonBuilder import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity -import com.navi.pay.utils.DS_KEY_NAVI_PAY_CUSTOMER_STATUS import com.navi.pay.utils.KEY_UPI_LITE_ACTIVE_ACCOUNT_INFO import com.navi.pay.utils.KEY_UPI_PRIMARY_ACCOUNT_VPA import com.navi.pay.utils.RUPEE_SYMBOL @@ -79,6 +81,7 @@ constructor( private val refreshLinkedAccountsUseCase: Lazy, private val dataStoreHelper: Lazy, private val refreshGenericOffersUseCase: RefreshGenericOffersUseCase, + private val clearOnboardingAndDeviceDataUseCase: ClearOnboardingAndDeviceDataUseCase, @NaviPayGsonBuilder private val gson: Gson, ) { companion object { @@ -129,9 +132,6 @@ constructor( val currentSimInfoList = NaviPayCommonUtils.getCurrentSimInfoList(context) val currentDeviceId = BaseUtils.getDeviceId(context) - val performSimPresenceCheck = - false // SIM presence check is not required at app launch. It will be check - // before CL launch. val naviPaySetupStatus = naviPaySetupUseCase .get() @@ -139,14 +139,15 @@ constructor( currentSimInfoList = currentSimInfoList, currentDeviceId = currentDeviceId, packageName = context.packageName, - performSimPresenceCheck = performSimPresenceCheck, + performSimPresenceCheck = + false, // SIM presence check is not required at app launch. It + // will be checked before CL launch. performLocalDataValidationCheck = false, source = "NaviPayManager", ) if (naviPaySetupStatus is NaviPaySetupStatus.Success) { updateCustomerData( - merchantCustomerId = naviPaySetupStatus.merchantCustomerId, - customerStatus = naviPaySetupStatus.customerStatus, + setupSuccessDetailsMap = naviPaySetupStatus.naviPaySetupSuccessDetailsMap ) } sdkInitialized = true @@ -158,30 +159,27 @@ constructor( } } - private suspend fun updateCustomerData(merchantCustomerId: String, customerStatus: String) { + private suspend fun updateCustomerData( + setupSuccessDetailsMap: Map + ) { withContext(Dispatchers.Default) { launch { - naviPayCustomerStatusHandler - .get() - .updateCustomerStatusAndHandleNaviPayIntentActivityState( - customerStatus = customerStatus - ) - } - launch { - if (deviceInfoProvider.get().getMerchantCustomerId().isBlank()) { - deviceInfoProvider + PspType.entries.forEach { pspType -> + val customerStatus = + setupSuccessDetailsMap[pspType]?.customerStatus + ?: NaviPayCustomerStatus.NOT_SET + val merchantCustomerId = + setupSuccessDetailsMap[pspType]?.merchantCustomerId.orEmpty() + naviPayCustomerStatusHandler .get() - .saveMerchantCustomerId(merchantCustomerId = merchantCustomerId) - } - } - launch { - if (deviceInfoProvider.get().getPhoneNumber().isBlank()) { - val phoneNumber = BaseUtils.getPhoneNumberWithNinetyOneCode() - if (phoneNumber.isNotBlank()) { - deviceInfoProvider.get().savePhoneNumber(phoneNumber = phoneNumber) - } + .upsertCustomerOnboardingDataEntity( + pspType = pspType, + customerStatus = customerStatus, + merchantCustomerId = merchantCustomerId, + ) } } + launch { if (deviceInfoProvider.get().getDeviceId().isBlank()) { val deviceId = BaseUtils.getDeviceId(context) @@ -200,18 +198,14 @@ constructor( /** Removing all upi data */ fun triggerNaviPayHardLogout() { CoroutineScope(Dispatchers.IO).launch { - launch { naviPaySetupUseCase.get().clearNaviPayData() } - - launch { naviPayCustomerStatusHandler.get().clearCustomerStatus() } + launch { clearOnboardingAndDeviceDataUseCase.execute() } launch { naviPayAppDatabase.get().clearAllTables() } launch { naviPayAppEncryptedDatabase.get().clearAllTables() } - launch { - dataStoreHelper.get().delete(DS_KEY_NAVI_PAY_CUSTOMER_STATUS) - dataStoreHelper.get().delete(KEY_UPI_PRIMARY_ACCOUNT_VPA) - } + launch { dataStoreHelper.get().delete(KEY_UPI_PRIMARY_ACCOUNT_VPA) } + sdkInitialized = false toggleNaviPayIntentActivityEnableState(shouldEnable = false) } @@ -223,13 +217,16 @@ constructor( triggerNaviPayHardLogout() } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.get().getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA + suspend fun isUserOnboardedForAnyPsp(): Boolean { + return naviPayCustomerStatusHandler.get().isUserOnboardedForAnyPsp() } - fun getCustomerStatus(): NaviPayCustomerStatus { - return naviPayCustomerStatusHandler.get().getCustomerStatusOnMainThread() + suspend fun isUserDeviceBoundForAnyPsp(): Boolean { + return naviPayCustomerStatusHandler.get().isUserDeviceBoundForAnyPsp() + } + + suspend fun getCustomerStatusMap(): Map { + return naviPayCustomerStatusHandler.get().getCustomerStatusMap() } suspend fun getDataByType(type: UpiDataType): JSONObject { @@ -241,9 +238,7 @@ constructor( response = response, linkedAccountsEntity = linkedAccountsUseCase.get().execute(includeAllDetails = true).first(), - customerStatus = - naviPayCustomerStatusHandler.get().getCustomerStatusOnMainThread().name, - isUserOnboarded = isUserOnboarded(), + isUserOnboardedForAnyPsp = isUserOnboardedForAnyPsp(), ) } } @@ -316,8 +311,7 @@ constructor( refreshLinkedAccountsUseCase = refreshLinkedAccountsUseCase, vpaQRProvider = vpaQRCodeManager, naviPayConfigProvider = naviPayConfigUseCase, - naviPayCustomerStatus = - naviPayCustomerStatusHandler.get().getCustomerStatusOnMainThread(), + isUserOnboardedForAnyPsp = isUserOnboardedForAnyPsp(), screenName = screenName, ) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPaySetupUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPaySetupUseCase.kt index ba13a9e6de..d54b891d5a 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPaySetupUseCase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/NaviPaySetupUseCase.kt @@ -7,26 +7,48 @@ package com.navi.pay.common.setup +import com.navi.base.cache.model.NaviCacheEntity +import com.navi.base.cache.repository.NaviCacheRepository import com.navi.common.network.models.RepoResult import com.navi.common.network.models.isSuccessWithData import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.SimInfo -import com.navi.pay.common.model.view.isAnyEmpty import com.navi.pay.common.repository.CommonRepository import com.navi.pay.common.repository.SharedPreferenceRepository +import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.setup.model.NaviPaySetupFailureReason import com.navi.pay.common.setup.model.NaviPaySetupStatus +import com.navi.pay.common.setup.model.NaviPaySetupSuccessDetails +import com.navi.pay.common.usecase.ClearOnboardingAndDeviceDataUseCase +import com.navi.pay.common.usecase.ValidateLocalDeviceDataUseCase import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.onboarding.binding.model.network.CustomerRequest import com.navi.pay.onboarding.binding.model.network.CustomerResponse +import com.navi.pay.utils.KEY_CUSTOMER_STATUS +import com.navi.pay.utils.KEY_DEVICE_FINGERPRINT +import com.navi.pay.utils.KEY_DEVICE_ID +import com.navi.pay.utils.KEY_EXTERNAL_CUSTOMER_ID import com.navi.pay.utils.KEY_IS_FIRST_TRANSACTION_SUCCESSFUL -import com.navi.pay.utils.NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS -import com.navi.pay.utils.NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS +import com.navi.pay.utils.KEY_PACKAGE_NAME +import com.navi.pay.utils.KEY_PROVIDER_NAME +import com.navi.pay.utils.KEY_SIM_SLOT +import com.navi.pay.utils.KEY_SSID +import com.navi.pay.utils.NAVI_PAY_DEVICE_ID_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_ONBOARDING_DATA_MIGRATION_COMPLETED_KEY +import com.navi.pay.utils.NAVI_PAY_PACKAGE_NAME_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_PROVIDER_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_SLOT_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SSID_CACHE_KEY import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class NaviPaySetupUseCase @@ -35,6 +57,10 @@ constructor( private val commonRepository: CommonRepository, private val sharedPreferenceRepository: SharedPreferenceRepository, private val deviceInfoProvider: DeviceInfoProvider, + private val validateLocalDeviceDataUseCase: ValidateLocalDeviceDataUseCase, + private val clearOnboardingAndDeviceDataUseCase: ClearOnboardingAndDeviceDataUseCase, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, + private val naviCacheRepository: NaviCacheRepository, ) { private lateinit var getCustomerJob: Deferred> private val naviPayAnalytics: NaviPayAnalytics.SetupUseCaseEvents = @@ -50,9 +76,10 @@ constructor( onboardingSource: String? = null, naviPaySessionAttributes: Map? = null, ): NaviPaySetupStatus { + migrateOnboardingDataIfRequired() val isLocalDataValid = if (performLocalDataValidationCheck) - fetchAndValidatePreferenceData( + validateLocalDeviceDataUseCase.execute( currentSimInfoList = currentSimInfoList, currentDeviceId = currentDeviceId, packageName = packageName, @@ -94,35 +121,6 @@ constructor( } } - private suspend fun fetchAndValidatePreferenceData( - currentSimInfoList: List, - currentDeviceId: String, - packageName: String, - performSimPresenceCheck: Boolean, - ): Boolean { - return withContext(Dispatchers.IO) { - val savedDeviceData = deviceInfoProvider.getDeviceData() - - if (savedDeviceData.isAnyEmpty()) return@withContext false - - if (savedDeviceData.provider.ssid.isBlank()) return@withContext false - - if ( - performSimPresenceCheck && - savedDeviceData.provider.ssid !in currentSimInfoList.map { it.subscriptionId } - ) - return@withContext false - - if (savedDeviceData.deviceId != currentDeviceId) return@withContext false - - if (savedDeviceData.packageName != packageName) return@withContext false - - if (deviceInfoProvider.getMerchantCustomerId().isBlank()) return@withContext false - - return@withContext true - } - } - private suspend fun onLocalDataValid( onboardingSource: String? = null, naviPaySessionAttributes: Map? = null, @@ -154,24 +152,150 @@ constructor( value = it, ) } + + // TODO: Multibank - Return psp level data after multi-bank integration NaviPaySetupStatus.Success( - customerStatus = customerResponse?.customerStatus.orEmpty(), - merchantCustomerId = customerResponse?.merchantCustomerId.orEmpty(), + naviPaySetupSuccessDetailsMap = + mapOf( + PspType.JUSPAY to + NaviPaySetupSuccessDetails( + customerStatus = + NaviPayCustomerStatus.fromString( + customerResponse?.customerStatus.orEmpty() + ), + merchantCustomerId = customerResponse?.merchantCustomerId.orEmpty(), + ) + ) ) } } private suspend fun onLocalDataInvalid(): NaviPaySetupStatus { return withContext(Dispatchers.IO) { - clearNaviPayData() + clearOnboardingAndDeviceDataUseCase.execute() NaviPaySetupStatus.Failure(NaviPaySetupFailureReason.LocalDataInvalid) } } - suspend fun clearNaviPayData() { - sharedPreferenceRepository.clearKeyBasedSessionPreferenceData( - encryptedDataKeys = NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS, - nonEncryptedDataKeys = NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS, - ) + private suspend fun migrateOnboardingDataIfRequired() { + withContext(Dispatchers.IO) { + val isMigrationDone = + naviCacheRepository + .get(key = NAVI_PAY_ONBOARDING_DATA_MIGRATION_COMPLETED_KEY) + ?.value == true.toString() + if (isMigrationDone) { + return@withContext + } + val taskList = mutableListOf>() + + taskList.add(async { migrateCustomerOnboardingData() }) + taskList.add(async { migrateDeviceData() }) + taskList.awaitAll() + + deleteCustomerDataPostMigration() + } + } + + private fun deleteCustomerDataPostMigration() { + CoroutineScope(Dispatchers.IO).launch { + sharedPreferenceRepository.removeKey(key = KEY_CUSTOMER_STATUS, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_EXTERNAL_CUSTOMER_ID, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_DEVICE_FINGERPRINT, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_SIM_SLOT, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_PROVIDER_NAME, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_PACKAGE_NAME, encrypt = true) + + sharedPreferenceRepository.removeKey(key = KEY_SSID, encrypt = true) + + naviCacheRepository.save( + NaviCacheEntity( + key = NAVI_PAY_ONBOARDING_DATA_MIGRATION_COMPLETED_KEY, + value = true.toString(), + version = 1, + clearOnLogout = false, + ) + ) + } + } + + private suspend fun migrateCustomerOnboardingData() { + val customerStatus = + sharedPreferenceRepository.getStringValue(KEY_CUSTOMER_STATUS, encrypt = true) + + val merchantCustomerId = + sharedPreferenceRepository.getStringValue( + key = KEY_EXTERNAL_CUSTOMER_ID, + encrypt = true, + ) + + val deviceFingerPrint = + sharedPreferenceRepository.getStringValue(key = KEY_DEVICE_FINGERPRINT, encrypt = true) + + if (merchantCustomerId.isNotEmpty()) { + naviPayCustomerStatusHandler.upsertCustomerOnboardingDataEntity( + pspType = PspType.JUSPAY, + customerStatus = NaviPayCustomerStatus.fromString(customerStatus), + merchantCustomerId = merchantCustomerId, + deviceFingerPrint = deviceFingerPrint, + ) + } + } + + private suspend fun migrateDeviceData() { + coroutineScope { + launch { + migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey = KEY_SIM_SLOT, + naviCacheRepositoryKey = NAVI_PAY_SIM_SLOT_CACHE_KEY, + ) + } + + launch { + migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey = KEY_PROVIDER_NAME, + naviCacheRepositoryKey = NAVI_PAY_SIM_PROVIDER_CACHE_KEY, + ) + } + + launch { + migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey = KEY_PACKAGE_NAME, + naviCacheRepositoryKey = NAVI_PAY_PACKAGE_NAME_CACHE_KEY, + ) + } + + launch { + migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey = KEY_SSID, + naviCacheRepositoryKey = NAVI_PAY_SSID_CACHE_KEY, + ) + } + + launch { + migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey = KEY_DEVICE_ID, + naviCacheRepositoryKey = NAVI_PAY_DEVICE_ID_CACHE_KEY, + ) + } + } + } + + private suspend fun migrateSharedPrefDataToNaviCacheRepository( + sharedPreferenceKey: String, + naviCacheRepositoryKey: String, + ) { + val value = + sharedPreferenceRepository.getStringValue(key = sharedPreferenceKey, encrypt = true) + + if (value.isNotEmpty()) { + naviCacheRepository.save( + NaviCacheEntity(key = naviCacheRepositoryKey, value = value, version = 1) + ) + } } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/model/NaviPaySetupStatus.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/model/NaviPaySetupStatus.kt index 63df36debf..3e6df3646d 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/model/NaviPaySetupStatus.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/setup/model/NaviPaySetupStatus.kt @@ -9,11 +9,13 @@ package com.navi.pay.common.setup.model import com.navi.common.network.models.ErrorMessage import com.navi.common.network.models.GenericErrorResponse +import com.navi.pay.common.model.view.PspType sealed class NaviPaySetupStatus { - data class Success(val customerStatus: String, val merchantCustomerId: String) : - NaviPaySetupStatus() + data class Success( + val naviPaySetupSuccessDetailsMap: Map + ) : NaviPaySetupStatus() data class Failure(val failureReason: NaviPaySetupFailureReason) : NaviPaySetupStatus() } @@ -31,5 +33,17 @@ enum class NaviPayCustomerStatus(val isBound: Boolean) { REREGISTER(false), LINKED_VPA(true), DEVICE_BOUNDED(true), - DEREGISTERED(false), + DEREGISTERED(false); + + companion object { + fun fromString(value: String): NaviPayCustomerStatus { + return NaviPayCustomerStatus.entries.find { it.name.equals(value, ignoreCase = true) } + ?: NOT_SET + } + } } + +data class NaviPaySetupSuccessDetails( + val customerStatus: NaviPayCustomerStatus, + val merchantCustomerId: String, +) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/CheckUpiNumberAvailabilityUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/CheckUpiNumberAvailabilityUseCase.kt index d8ddeebde9..48930d45f2 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/CheckUpiNumberAvailabilityUseCase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/CheckUpiNumberAvailabilityUseCase.kt @@ -61,12 +61,11 @@ constructor( vpaEntityList = vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@evaluateAndOnboardPspForFlow + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow val vpaEntity = - getVpaEntityByPspType( - vpaEntityList = vpaEntityList, - pspType = pspEvaluationResult.psp, - ) + getVpaEntityByPspType(vpaEntityList = vpaEntityList, pspType = pspType) val response = fetchResponseFromNetwork( action = AVAILABILITY_ACTION_CHECK, diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ClearOnboardingAndDeviceDataUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ClearOnboardingAndDeviceDataUseCase.kt new file mode 100644 index 0000000000..fc53759747 --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ClearOnboardingAndDeviceDataUseCase.kt @@ -0,0 +1,70 @@ +/* + * + * * Copyright © 2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.common.usecase + +import com.navi.base.cache.repository.NaviCacheRepository +import com.navi.pay.common.repository.SharedPreferenceRepository +import com.navi.pay.onboarding.binding.repository.NaviPayOnboardingRepository +import com.navi.pay.utils.NAVI_PAY_DEVICE_ID_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS +import com.navi.pay.utils.NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS +import com.navi.pay.utils.NAVI_PAY_PACKAGE_NAME_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_PROVIDER_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_SLOT_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SSID_CACHE_KEY +import javax.inject.Inject +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.withContext + +class ClearOnboardingAndDeviceDataUseCase +@Inject +constructor( + private val sharedPreferenceRepository: SharedPreferenceRepository, + private val naviCacheRepository: NaviCacheRepository, + private val naviPayOnboardingRepository: NaviPayOnboardingRepository, +) { + suspend fun execute() { + withContext(Dispatchers.IO) { + val taskList = mutableListOf>() + taskList.add(async { clearSharedPrefData() }) + taskList.add(async { clearCacheRepositoryData() }) + + taskList.add(async { clearOnboardingRepositoryData() }) + taskList.awaitAll() + } + } + + private suspend fun clearCacheRepositoryData() { + coroutineScope { + listOf( + NAVI_PAY_SIM_SLOT_CACHE_KEY, + NAVI_PAY_SIM_PROVIDER_CACHE_KEY, + NAVI_PAY_PACKAGE_NAME_CACHE_KEY, + NAVI_PAY_SSID_CACHE_KEY, + NAVI_PAY_DEVICE_ID_CACHE_KEY, + ) + .map { key -> async(Dispatchers.IO) { naviCacheRepository.clear(key) } } + .awaitAll() + } + } + + private suspend fun clearSharedPrefData() { + sharedPreferenceRepository.clearKeyBasedSessionPreferenceData( + encryptedDataKeys = NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS, + nonEncryptedDataKeys = NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS, + ) + } + + private suspend fun clearOnboardingRepositoryData() { + naviPayOnboardingRepository.deleteAll() + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/LiteAccountSyncUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/LiteAccountSyncUseCase.kt index dc6fe631da..f5ed805f41 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/LiteAccountSyncUseCase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/LiteAccountSyncUseCase.kt @@ -19,7 +19,6 @@ import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.UpiLiteActiveAccountInfo import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.NaviPayCommonUtils import com.navi.pay.common.utils.getDateTimeStringWithYearOffset @@ -352,11 +351,8 @@ constructor( } } - private fun getCustomerStatus() = naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() - - private fun isUserOnboarded(psp: PspType): Boolean { - // TODO: Multibank - check onboarding at psp level - return getCustomerStatus() == NaviPayCustomerStatus.LINKED_VPA + private suspend fun isUserOnboarded(psp: PspType): Boolean { + return naviPayCustomerStatusHandler.isUserOnboarded(pspType = psp) } private suspend fun handlePendingActivationStatusAndPendingInitialTopUpCase( diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/UpdateCustomerStatusOnAccountRemovalUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/UpdateCustomerStatusOnAccountRemovalUseCase.kt new file mode 100644 index 0000000000..ba933dc5fe --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/UpdateCustomerStatusOnAccountRemovalUseCase.kt @@ -0,0 +1,77 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.common.usecase + +import com.navi.pay.common.model.view.PspType +import com.navi.pay.common.setup.NaviPayCustomerStatusHandler +import com.navi.pay.common.setup.model.NaviPayCustomerStatus +import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity +import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity +import javax.inject.Inject +import javax.inject.Singleton +import kotlinx.coroutines.flow.first + +@Singleton +class UpdateCustomerStatusOnAccountRemovalUseCase +@Inject +constructor( + private val linkedAccountsUseCase: LinkedAccountsUseCase, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, +) { + suspend fun execute(screenName: String) { + val linkedAccountEntityList = linkedAccountsUseCase.execute(screenName = screenName).first() + + val customerOnboardingEntityList = + naviPayCustomerStatusHandler.getAllCustomerOnboardingData() + + PspType.entries.forEach { pspType -> + val currentCustomerStatus = + getCurrentCustomerStatusForPspFromList( + customerOnboardingEntityList = customerOnboardingEntityList, + pspType = pspType, + ) + if ( + currentCustomerStatus == NaviPayCustomerStatus.LINKED_VPA && + isNoAccountLinkedOnPsp( + linkedAccountEntityList = linkedAccountEntityList, + pspType = pspType, + ) + ) { + naviPayCustomerStatusHandler + .updateCustomerStatusAndHandleNaviPayIntentActivityState( + pspType = pspType, + customerStatus = NaviPayCustomerStatus.DEVICE_BOUNDED, + ) + } + } + } + + private fun getCurrentCustomerStatusForPspFromList( + customerOnboardingEntityList: List, + pspType: PspType, + ): NaviPayCustomerStatus = + customerOnboardingEntityList + .firstOrNull { customerOnboardingEntity -> customerOnboardingEntity.pspType == pspType } + ?.customerStatus ?: NaviPayCustomerStatus.NOT_SET + + private fun isNoAccountLinkedOnPsp( + linkedAccountEntityList: List, + pspType: PspType, + ): Boolean = + linkedAccountEntityList.none { linkedAccountEntity -> + isAccountLinkedOnPsp(linkedAccountEntity = linkedAccountEntity, pspType = pspType) + } + + private fun isAccountLinkedOnPsp( + linkedAccountEntity: LinkedAccountEntity, + pspType: PspType, + ): Boolean = + linkedAccountEntity.vpaEntityList.any { vpaEntity -> + PspType.fromVpa(vpaEntity.vpa) == pspType + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ValidateLocalDeviceDataUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ValidateLocalDeviceDataUseCase.kt new file mode 100644 index 0000000000..68f012bb0b --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/ValidateLocalDeviceDataUseCase.kt @@ -0,0 +1,56 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.common.usecase + +import com.navi.pay.common.model.view.SimInfo +import com.navi.pay.common.model.view.isAnyEmpty +import com.navi.pay.common.setup.NaviPayCustomerStatusHandler +import com.navi.pay.common.utils.DeviceInfoProvider +import javax.inject.Inject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +class ValidateLocalDeviceDataUseCase +@Inject +constructor( + private val deviceInfoProvider: DeviceInfoProvider, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, +) { + + suspend fun execute( + currentSimInfoList: List, + currentDeviceId: String, + packageName: String, + performSimPresenceCheck: Boolean = true, + ): Boolean { + return withContext(Dispatchers.IO) { + val savedDeviceData = deviceInfoProvider.getDeviceData() + + if (savedDeviceData.isAnyEmpty()) return@withContext false + + if (savedDeviceData.provider.ssid.isBlank()) return@withContext false + + if ( + performSimPresenceCheck && + savedDeviceData.provider.ssid !in currentSimInfoList.map { it.subscriptionId } + ) + return@withContext false + + if (savedDeviceData.deviceId != currentDeviceId) return@withContext false + + if (savedDeviceData.packageName != packageName) return@withContext false + + val merchantCustomerIds = + naviPayCustomerStatusHandler.getAllCustomerOnboardingData().map { + it.merchantCustomerId + } + return@withContext !(merchantCustomerIds.isEmpty() || + merchantCustomerIds.all { it.isBlank() }) + } + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/DeviceInfoProvider.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/DeviceInfoProvider.kt index 753f315858..7102223446 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/DeviceInfoProvider.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/DeviceInfoProvider.kt @@ -8,36 +8,31 @@ package com.navi.pay.common.utils import com.navi.base.AppServiceManager +import com.navi.base.cache.model.NaviCacheEntity +import com.navi.base.cache.repository.NaviCacheRepository import com.navi.base.utils.BaseUtils import com.navi.pay.common.model.view.DeviceData import com.navi.pay.common.model.view.NetworkProvider -import com.navi.pay.common.repository.SharedPreferenceRepository -import com.navi.pay.utils.KEY_DEVICE_FINGERPRINT -import com.navi.pay.utils.KEY_DEVICE_ID -import com.navi.pay.utils.KEY_EXTERNAL_CUSTOMER_ID -import com.navi.pay.utils.KEY_PACKAGE_NAME -import com.navi.pay.utils.KEY_PHONE_NUMBER -import com.navi.pay.utils.KEY_PROVIDER_NAME -import com.navi.pay.utils.KEY_SIM_SLOT -import com.navi.pay.utils.KEY_SSID +import com.navi.pay.common.model.view.PspType +import com.navi.pay.common.setup.NaviPayCustomerStatusHandler +import com.navi.pay.utils.NAVI_PAY_DEVICE_ID_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_PACKAGE_NAME_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_PROVIDER_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SIM_SLOT_CACHE_KEY +import com.navi.pay.utils.NAVI_PAY_SSID_CACHE_KEY import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async -import kotlinx.coroutines.withContext +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope interface DeviceInfoProvider { suspend fun saveDeviceData(deviceData: DeviceData) suspend fun getDeviceData(): DeviceData - suspend fun getPhoneNumber(): String - suspend fun getDeviceId(): String - suspend fun saveMerchantCustomerId(merchantCustomerId: String) - - suspend fun savePhoneNumber(phoneNumber: String) - suspend fun saveDeviceId(deviceId: String) suspend fun getMerchantCustomerId(): String @@ -45,159 +40,95 @@ interface DeviceInfoProvider { class DeviceInfoImpl @Inject -constructor(private val sharedPreferenceRepository: SharedPreferenceRepository) : - DeviceInfoProvider { +constructor( + private val naviCacheRepository: NaviCacheRepository, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, +) : DeviceInfoProvider { override suspend fun saveDeviceData(deviceData: DeviceData) { - - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_SSID, - value = deviceData.provider.ssid, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_DEVICE_ID, - value = deviceData.deviceId, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_DEVICE_FINGERPRINT, - value = deviceData.deviceFingerPrint, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_SIM_SLOT, - value = deviceData.provider.simSlot, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_PHONE_NUMBER, - value = deviceData.provider.phoneNumber, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_PACKAGE_NAME, - value = deviceData.packageName, - encrypt = true, - ) - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_PROVIDER_NAME, - value = deviceData.provider.name, - encrypt = true, - ) + coroutineScope { + listOf( + NAVI_PAY_SSID_CACHE_KEY to deviceData.provider.ssid, + NAVI_PAY_DEVICE_ID_CACHE_KEY to deviceData.deviceId, + NAVI_PAY_SIM_SLOT_CACHE_KEY to deviceData.provider.simSlot, + NAVI_PAY_PACKAGE_NAME_CACHE_KEY to deviceData.packageName, + NAVI_PAY_SIM_PROVIDER_CACHE_KEY to deviceData.provider.name, + ) + .map { (key, value) -> + async(Dispatchers.IO) { + naviCacheRepository.save( + NaviCacheEntity(key = key, value = value, version = 1) + ) + } + } + .awaitAll() + } } - override suspend fun getDeviceData(): DeviceData = - withContext(Dispatchers.IO) { - val savedSSID = async { - sharedPreferenceRepository.getStringValue( - key = KEY_SSID, - defValue = "", - encrypt = true, - ) - } - - val savedDeviceFingerPrint = async { - sharedPreferenceRepository.getStringValue( - key = KEY_DEVICE_FINGERPRINT, - defValue = "", - encrypt = true, - ) - } - val savedSimSlot = async { - sharedPreferenceRepository.getStringValue( - key = KEY_SIM_SLOT, - defValue = "", - encrypt = true, - ) - } - val savedPackageName = async { - sharedPreferenceRepository.getStringValue( - key = KEY_PACKAGE_NAME, - defValue = "", - encrypt = true, - ) - } - val savedProviderName = async { - sharedPreferenceRepository.getStringValue( - key = KEY_PROVIDER_NAME, - defValue = "", - encrypt = true, - ) - } - val savedPhoneNumber = async { - val phoneNumber = getPhoneNumber() - phoneNumber.ifBlank { BaseUtils.getPhoneNumberWithNinetyOneCode() } - } - - val savedDeviceId = async { - val deviceId = - sharedPreferenceRepository.getStringValue( - key = KEY_DEVICE_ID, - defValue = "", - encrypt = true, - ) - deviceId.ifBlank { BaseUtils.getDeviceId(AppServiceManager.application) } - } - - return@withContext DeviceData( - deviceFingerPrint = savedDeviceFingerPrint.await(), - deviceId = savedDeviceId.await(), - packageName = savedPackageName.await(), - provider = - NetworkProvider( - ssid = savedSSID.await(), - phoneNumber = savedPhoneNumber.await(), - simSlot = savedSimSlot.await(), - name = savedProviderName.await(), - ), + override suspend fun getDeviceData() = coroutineScope { + val fingerPrintCacheKey = "fingerprintCacheKey" + val deferredResults = + listOf( + async(Dispatchers.IO) { + NAVI_PAY_SSID_CACHE_KEY to + naviCacheRepository.get(NAVI_PAY_SSID_CACHE_KEY)?.value.orEmpty() + }, + async(Dispatchers.IO) { + NAVI_PAY_DEVICE_ID_CACHE_KEY to + naviCacheRepository.get(NAVI_PAY_DEVICE_ID_CACHE_KEY)?.value.orEmpty() + }, + async(Dispatchers.IO) { + fingerPrintCacheKey to + naviPayCustomerStatusHandler + .getAllCustomerOnboardingData() + .firstOrNull { it.pspType == PspType.JUSPAY } + ?.deviceFingerPrint + .orEmpty() + }, + async(Dispatchers.IO) { + NAVI_PAY_SIM_SLOT_CACHE_KEY to + naviCacheRepository.get(NAVI_PAY_SIM_SLOT_CACHE_KEY)?.value.orEmpty() + }, + async(Dispatchers.IO) { + NAVI_PAY_PACKAGE_NAME_CACHE_KEY to + naviCacheRepository.get(NAVI_PAY_PACKAGE_NAME_CACHE_KEY)?.value.orEmpty() + }, + async(Dispatchers.IO) { + NAVI_PAY_SIM_PROVIDER_CACHE_KEY to + naviCacheRepository.get(NAVI_PAY_SIM_PROVIDER_CACHE_KEY)?.value.orEmpty() + }, ) - } - - override suspend fun getPhoneNumber(): String { - return sharedPreferenceRepository.getStringValue( - key = KEY_PHONE_NUMBER, - defValue = "", - encrypt = true, + val cacheResults = deferredResults.awaitAll().toMap() + DeviceData( + deviceFingerPrint = cacheResults[fingerPrintCacheKey].orEmpty(), + deviceId = + cacheResults[NAVI_PAY_DEVICE_ID_CACHE_KEY].orEmpty().ifBlank { + BaseUtils.getDeviceId(AppServiceManager.application) + }, + packageName = cacheResults[NAVI_PAY_PACKAGE_NAME_CACHE_KEY].orEmpty(), + provider = + NetworkProvider( + ssid = cacheResults[NAVI_PAY_SSID_CACHE_KEY].orEmpty(), + phoneNumber = BaseUtils.getPhoneNumberWithNinetyOneCode(), + simSlot = cacheResults[NAVI_PAY_SIM_SLOT_CACHE_KEY].orEmpty(), + name = cacheResults[NAVI_PAY_SIM_PROVIDER_CACHE_KEY].orEmpty(), + ), ) } override suspend fun getDeviceId(): String { - return sharedPreferenceRepository.getStringValue( - key = KEY_DEVICE_ID, - defValue = "", - encrypt = true, - ) - } - - override suspend fun saveMerchantCustomerId(merchantCustomerId: String) { - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_EXTERNAL_CUSTOMER_ID, - value = merchantCustomerId, - encrypt = true, - ) - } - - override suspend fun savePhoneNumber(phoneNumber: String) { - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_PHONE_NUMBER, - value = phoneNumber, - encrypt = true, - ) + return naviCacheRepository.get(NAVI_PAY_DEVICE_ID_CACHE_KEY)?.value.orEmpty() } override suspend fun saveDeviceId(deviceId: String) { - sharedPreferenceRepository.saveStringValueSynchronously( - key = KEY_DEVICE_ID, - value = deviceId, - encrypt = true, + naviCacheRepository.save( + NaviCacheEntity(key = NAVI_PAY_DEVICE_ID_CACHE_KEY, value = deviceId, version = 1) ) } override suspend fun getMerchantCustomerId(): String { - return sharedPreferenceRepository.getStringValue( - key = KEY_EXTERNAL_CUSTOMER_ID, - defValue = "", - encrypt = true, - ) + return naviPayCustomerStatusHandler + .getCustomerOnboardingEntity(pspType = PspType.JUSPAY) + ?.merchantCustomerId + .orEmpty() } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPayCommonUtils.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPayCommonUtils.kt index a7994334a0..ee450af84d 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPayCommonUtils.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPayCommonUtils.kt @@ -115,7 +115,6 @@ import com.navi.pay.utils.customHide import com.navi.pay.utils.getMaskedAccountNumber import java.security.MessageDigest import javax.crypto.KeyGenerator -import kotlin.Any import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPaySdkUtils.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPaySdkUtils.kt index b552447e94..fa53d0396f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPaySdkUtils.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/utils/NaviPaySdkUtils.kt @@ -20,7 +20,6 @@ import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.UPI_LITE_ import com.navi.common.upi.AMOUNT import com.navi.common.upi.BANK_ACCOUNT_ID import com.navi.common.upi.CONNECTED_ACCOUNTS -import com.navi.common.upi.CUSTOMER_STATUS import com.navi.common.upi.DATA import com.navi.common.upi.ERRORS import com.navi.common.upi.IS_ONBOARDED @@ -48,7 +47,6 @@ import com.navi.pay.common.settingscreen.model.QrDetails import com.navi.pay.common.settingscreen.model.SettingConfigContent import com.navi.pay.common.settingscreen.model.SettingResponse import com.navi.pay.common.settingscreen.utils.getFilteredLinkedAccounts -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.NaviPayConfigUseCase import com.navi.pay.common.usecase.RefreshLinkedAccountsUseCase import com.navi.pay.common.utils.NaviPayCommonUtils.getBackPressErrorConfig @@ -70,13 +68,11 @@ object NaviPaySdkUtils { fun buildConnectedBankAccountResponse( response: JSONObject, linkedAccountsEntity: List, - customerStatus: String, - isUserOnboarded: Boolean, + isUserOnboardedForAnyPsp: Boolean, ) { val linkedAccounts = addUpiLiteItem(linkedAccountsEntity) val data = JSONObject() - data.put(CUSTOMER_STATUS, customerStatus) - data.put(IS_ONBOARDED, isUserOnboarded) + data.put(IS_ONBOARDED, isUserOnboardedForAnyPsp) data.put(CONNECTED_ACCOUNTS, JSONArray(Gson().toJson(linkedAccounts).toString())) response.put(DATA, data) } @@ -281,7 +277,7 @@ object NaviPaySdkUtils { refreshLinkedAccountsUseCase: Lazy, vpaQRProvider: Lazy, naviPayConfigProvider: Lazy, - naviPayCustomerStatus: NaviPayCustomerStatus, + isUserOnboardedForAnyPsp: Boolean, screenName: String, ): SettingResponse { return withContext(Dispatchers.IO) { @@ -305,7 +301,7 @@ object NaviPaySdkUtils { SettingResponse( qrList = userVpaList, config = config, - naviPayCustomerStatus = naviPayCustomerStatus, + isUserOnboardedForAnyPsp = isUserOnboardedForAnyPsp, ) } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/db/NaviPayAppDatabase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/db/NaviPayAppDatabase.kt index 04f582873d..ed508ed5cd 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/db/NaviPayAppDatabase.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/db/NaviPayAppDatabase.kt @@ -26,10 +26,15 @@ import com.navi.pay.management.upinumber.list.model.view.UpiNumberEntity import com.navi.pay.management.upinumber.list.util.UpiNumberStatusConverter import com.navi.pay.onboarding.account.add.dao.BankDao import com.navi.pay.onboarding.account.add.model.view.BankEntity +import com.navi.pay.onboarding.binding.db.converter.CustomerStatusConverter +import com.navi.pay.onboarding.binding.db.converter.PspTypeConverter +import com.navi.pay.onboarding.binding.db.dao.NaviPayCustomerOnboardingDao +import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity import com.navi.pay.tstore.list.db.dao.OrderTagSummaryDao import com.navi.pay.tstore.list.model.view.OrderTagSummaryEntity import com.navi.pay.utils.NAVI_PAY_DATABASE_BANK_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_BANK_UPTIME_TABLE +import com.navi.pay.utils.NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_ORDER_TAG_SUMMARY_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_SYNC_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_UPI_NUMBERS_TABLE_NAME @@ -46,8 +51,9 @@ import com.navi.pay.utils.NAVI_PAY_SYNC_TABLE_TRANSACTION_HISTORY_KEY UpiNumberEntity::class, VpaTransactionsInsightEntity::class, OrderTagSummaryEntity::class, + NaviPayCustomerOnboardingEntity::class, ], - version = 12, + version = 13, exportSchema = false, ) @TypeConverters( @@ -55,6 +61,8 @@ import com.navi.pay.utils.NAVI_PAY_SYNC_TABLE_TRANSACTION_HISTORY_KEY DateTimeConverter::class, UpiNumberStatusConverter::class, VpaTransactionInfoListConverter::class, + PspTypeConverter::class, + CustomerStatusConverter::class, ) abstract class NaviPayAppDatabase : RoomDatabase() { abstract fun bankDao(): BankDao @@ -68,6 +76,8 @@ abstract class NaviPayAppDatabase : RoomDatabase() { abstract fun vpaTransactionInsightsDao(): VpaTransactionInsightsDao abstract fun orderTagSummaryDao(): OrderTagSummaryDao + + abstract fun customerOnboardingDao(): NaviPayCustomerOnboardingDao } val NAVI_PAY_APP_DATABASE_MIGRATION_1_2 = @@ -199,3 +209,12 @@ val NAVI_PAY_APP_DATABASE_MIGRATION_11_12 = ) } } + +val NAVI_PAY_APP_DATABASE_MIGRATION_12_13 = + object : Migration(12, 13) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL( + "CREATE TABLE IF NOT EXISTS $NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME (`pspType` TEXT PRIMARY KEY NOT NULL, `merchantCustomerId` TEXT NOT NULL, `customerStatus` TEXT NOT NULL, `deviceFingerPrint` TEXT NOT NULL)" + ) + } + } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/db/cleaner/NaviPayModuleTableCleaner.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/db/cleaner/NaviPayModuleTableCleaner.kt index cb7af8a4f5..8a657e9a48 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/db/cleaner/NaviPayModuleTableCleaner.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/db/cleaner/NaviPayModuleTableCleaner.kt @@ -14,6 +14,7 @@ import com.navi.pay.db.NaviPayAppEncryptedDatabase import com.navi.pay.utils.NAVI_PAY_DATABASE_ACCOUNTS_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_BANK_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_BANK_UPTIME_TABLE +import com.navi.pay.utils.NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_ORDER_TAG_SUMMARY_TABLE_NAME import com.navi.pay.utils.NAVI_PAY_DATABASE_SAVED_BENEFICIARY_TABLE import com.navi.pay.utils.NAVI_PAY_DATABASE_SYNC_TABLE_NAME @@ -51,6 +52,8 @@ constructor( naviPayAppDatabase.upiNumbersDao().deleteAll() NAVI_PAY_DATABASE_VPA_TRANSACTION_INSIGHTS_TABLE_NAME -> naviPayAppDatabase.vpaTransactionInsightsDao().deleteAll() + NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME -> + naviPayAppDatabase.customerOnboardingDao().deleteAll() NAVI_PAY_DATABASE_ORDER_TAG_SUMMARY_TABLE_NAME -> naviPayAppDatabase.orderTagSummaryDao().deleteAll() } @@ -86,6 +89,8 @@ constructor( naviPayAppDatabase.upiNumbersDao().deleteRows(sqlQuery) NAVI_PAY_DATABASE_VPA_TRANSACTION_INSIGHTS_TABLE_NAME -> naviPayAppDatabase.vpaTransactionInsightsDao().deleteRows(sqlQuery) + NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME -> + naviPayAppDatabase.customerOnboardingDao().deleteRows(sqlQuery) NAVI_PAY_DATABASE_ORDER_TAG_SUMMARY_TABLE_NAME -> naviPayAppDatabase.orderTagSummaryDao().deleteRows(sqlQuery) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayActivity.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayActivity.kt index 4eb6089fee..5c9741ef5c 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayActivity.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayActivity.kt @@ -154,21 +154,18 @@ class NaviPayActivity : BaseActivity() { window.decorView.setBackgroundColor(Color.WHITE) - launchOnboardingFlowIfRequired( - isNaviPayAccessible = naviPayAccessEligibility.isNaviPayAccessible - ) + lifecycleScope.launch { + launchMandatoryPermissionsCheckIfRequired( + isNaviPayAccessible = naviPayAccessEligibility.isNaviPayAccessible + ) + } } - private fun launchOnboardingFlowIfRequired(isNaviPayAccessible: Boolean) { + private suspend fun launchMandatoryPermissionsCheckIfRequired(isNaviPayAccessible: Boolean) { if (!isNaviPayAccessible || viewModel.isScreenAllowWithoutOnboarding(intent)) return - val isOnboarded = viewModel.isUserOnboarded() - if (isOnboarded) { + if (viewModel.isUserDeviceBoundForAnyPsp()) { checkOnboardedUserMandatoryPermissions() - } else { - if (viewModel.isCustomerStatusDeviceBounded()) { - checkOnboardedUserMandatoryPermissions() - } } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt index 0066ad2bf4..f8b0b79865 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt @@ -38,7 +38,6 @@ import com.navi.pay.common.model.view.NaviPayScreenType import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.NaviPayRouter -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.LiteAccountSyncUseCase import com.navi.pay.common.usecase.RefreshBankListUseCase import com.navi.pay.common.usecase.RefreshConfigUseCase @@ -166,18 +165,13 @@ constructor( initNudgeDetailsPoller() - if (isUserOnboarded()) { - initUpiLiteSync() - } + initUpiLiteSync() // Onboarding check is not required here } - private fun getCustomerStatus() = naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() - private fun initUpiLiteSync() { viewModelScope.launch(Dispatchers.IO) { - if (isUserOnboarded()) { - liteAccountSyncUseCase.execute(screenName = screenName) - } + // Onboarding check is not required here + liteAccountSyncUseCase.execute(screenName = screenName) } } @@ -203,12 +197,8 @@ constructor( return intent.getBooleanExtra(WITHOUT_ONBOARDING_FLOW, false) } - fun isUserOnboarded(): Boolean { - return getCustomerStatus() == NaviPayCustomerStatus.LINKED_VPA - } - - fun isCustomerStatusDeviceBounded(): Boolean { - return getCustomerStatus() == NaviPayCustomerStatus.DEVICE_BOUNDED + suspend fun isUserDeviceBoundForAnyPsp(): Boolean { + return naviPayCustomerStatusHandler.isUserDeviceBoundForAnyPsp() } private fun initFireStorePollerForBankUptime() { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt index 9db302dd9f..924db2fa5b 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt @@ -71,8 +71,6 @@ import com.navi.pay.common.model.view.NaviPayText import com.navi.pay.common.model.view.SimInfo import com.navi.pay.common.repository.CommonRepository import com.navi.pay.common.repository.SharedPreferenceRepository -import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.usecase.AccountListCheckBalanceUseCase import com.navi.pay.common.usecase.ArcNudgeUseCase @@ -261,7 +259,6 @@ constructor( private val naviPaySessionHelper: NaviPaySessionHelper, private val validateVpaUseCase: ValidateVpaUseCase, private val upiRequestIdUseCase: UpiRequestIdUseCase, - private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, private val upiLiteClHelper: UpiLiteClHelper, private val scratchCardNudgeHelper: ScratchCardNudgeHelper, private val accountEligibilityMerchantHelper: AccountEligibilityMerchantHelper, @@ -753,9 +750,9 @@ constructor( vpaEntityList = linkedAccount.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow naviPayAnalytics.onCheckBalanceClicked( source = source, naviPaySessionAttributes = getNaviPaySessionAttributes(), @@ -778,7 +775,7 @@ constructor( accountListCheckBalanceUseCase.onCheckBalanceClicked( linkedAccount = linkedAccount, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultReceived = { if (isAccountSelectionBottomSheetVisible) { updateBottomSheetUIState( @@ -820,11 +817,6 @@ constructor( delay(2.seconds) } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA - } - fun getNaviPaySessionAttributes(): Map { return naviPaySessionHelper.getNaviPaySessionAttributes() } @@ -999,9 +991,9 @@ constructor( vpaEntityList = selectedBankAccount.value?.vpaEntityList ?: return@launch, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow resetCheckBalanceStates() @@ -1009,7 +1001,7 @@ constructor( LinkedAccountVerifyScreenDestination( bankAccountUniqueId = selectedBankAccount.value?.accountId ?: "", actionName = ACTION_PIN_SET, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) ) }, @@ -1657,10 +1649,7 @@ constructor( payButtonSource: String, ) { var selectedBankAccount = selectedBankAccount.value ?: return - - if (pspEvaluationResult.psp == null) { - return - } + val pspType = pspEvaluationResult.onboardingDataEntity?.pspType ?: return if (pspEvaluationResult.isOnboardingTriggered) { showRedirectingBottomSheet() @@ -1770,7 +1759,7 @@ constructor( payeeEntity = payeeEntity.value, screenName = screenName, txnTimeStamp = txnTimeStamp, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultSuccess = { credBlock -> if (pspEvaluationResult.isOnboardingTriggered) { updateTriggerDismissBottomSheet() @@ -2806,9 +2795,9 @@ constructor( vpaEntity = vpaEntity, // TODO: Multibank - Test this screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForVpa - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForVpa if (pspEvaluationResult.isOnboardingTriggered) { showRedirectingBottomSheet() @@ -2885,7 +2874,7 @@ constructor( accountEntity = updatedBankAccount, payeeEntity = payeeEntity.value, upiRequestId = upiRequestId, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) naviPayAnalytics.onApproveClick( @@ -2945,7 +2934,7 @@ constructor( // TODO: as this is vpa specific flow check if this is correct screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { + if (pspEvaluationResult.onboardingDataEntity == null) { return@evaluateAndOnboardPspForVpa } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/utils/NaviPayPspManager.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/utils/NaviPayPspManager.kt index 8f0fc4d3c0..40ca4e2119 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/utils/NaviPayPspManager.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/utils/NaviPayPspManager.kt @@ -16,18 +16,17 @@ import com.navi.pay.common.model.view.NaviPayFlowType import com.navi.pay.common.model.view.NaviPayOnboardingRequest import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.NaviPayConfigUseCase import com.navi.pay.common.utils.NaviPayOnboardingNavigator import com.navi.pay.network.di.NaviPayGsonBuilder import com.navi.pay.onboarding.account.common.model.view.VpaEntity import com.navi.pay.onboarding.account.common.model.view.VpaStatus +import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity import com.navi.pay.onboarding.common.NaviPayOnboardingActionsType import com.navi.pay.utils.NAVI_PAY_PSP_ROUTING_BUCKETS_KEY import com.navi.pay.utils.UPI_PSP_SELECTION_CONFIG import dagger.hilt.android.scopes.ActivityRetainedScoped import javax.inject.Inject -import kotlin.collections.get import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -35,8 +34,7 @@ import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.withContext data class PspEvaluationResult( - val psp: PspType? = null, - val status: NaviPayCustomerStatus = NaviPayCustomerStatus.NOT_SET, + val onboardingDataEntity: NaviPayCustomerOnboardingEntity? = null, val isDeviceBindingTriggered: Boolean = false, val isVpaActivationTriggered: Boolean = false, ) { @@ -75,9 +73,8 @@ constructor( coroutineScope { this@NaviPayPspManager.screenName = screenName - // Fetch configuration and PSP statuses in parallel + // Fetch configuration in parallel val pspSelectionConfigDeferred = async { getPspSelectionConfig() } - val pspCustomerStatusMapDeferred = async { getPspCustomerStatusMap() } // Step 1: Get supported PSP List val pspSelectionConfig = pspSelectionConfigDeferred.await() @@ -92,12 +89,7 @@ constructor( } // Step 2: Get bound PSP list - val pspCustomerStatusMap = pspCustomerStatusMapDeferred.await() - val boundSupportedPspList = - getBoundPspList( - supportedPspList = supportedPspList, - pspCustomerStatusMap = pspCustomerStatusMap, - ) + val boundSupportedPspList = getBoundPspList(supportedPspList = supportedPspList) // Step 3: Evaluate PSP and handle onboarding val pspEvaluationResult = @@ -141,9 +133,8 @@ constructor( coroutineScope { this@NaviPayPspManager.screenName = screenName - // Fetch configuration and PSP statuses in parallel + // Fetch configuration in parallel val pspSelectionConfigDeferred = async { getPspSelectionConfig() } - val pspCustomerStatusMapDeferred = async { getPspCustomerStatusMap() } // Step 1: Get supported PSP List val pspSelectionConfig = pspSelectionConfigDeferred.await() @@ -158,19 +149,16 @@ constructor( } // Step 2: Get bound PSP list - val pspCustomerStatusMap = pspCustomerStatusMapDeferred.await() - val boundSupportedPspList = - getBoundPspList( - supportedPspList = supportedPspList, - pspCustomerStatusMap = pspCustomerStatusMap, - ) + val boundSupportedPspList = getBoundPspList(supportedPspList = supportedPspList) // Step 3: Evaluate PSP and handle onboarding val pspEvaluationResult = if (boundSupportedPspList.isNotEmpty()) { val psp = boundSupportedPspList.first() - val status = pspCustomerStatusMap[psp] ?: NaviPayCustomerStatus.NOT_SET - PspEvaluationResult(psp = boundSupportedPspList.first(), status = status) + PspEvaluationResult( + onboardingDataEntity = + naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = psp) + ) } else { val selectedPsp = determinePspByRoutingLogic( @@ -179,8 +167,6 @@ constructor( pspSelectionConfig = pspSelectionConfig, ) - val status = pspCustomerStatusMap[selectedPsp] ?: NaviPayCustomerStatus.NOT_SET - selectedPsp?.let { psp -> onOnboardingTriggered(NaviPayOnboardingActionsType.DEVICE_BINDING) val isOnboardingSuccess = @@ -191,8 +177,12 @@ constructor( ) PspEvaluationResult( - psp = if (isOnboardingSuccess) psp else null, - status = status, + onboardingDataEntity = + if (isOnboardingSuccess) + naviPayCustomerStatusHandler.getCustomerOnboardingEntity( + pspType = psp + ) + else null, isDeviceBindingTriggered = true, ) } ?: PspEvaluationResult() @@ -227,8 +217,7 @@ constructor( onPspEvaluated(PspEvaluationResult()) return } - val pspCustomerStatusMap = getPspCustomerStatusMap() - val pspStatus = pspCustomerStatusMap[psp] ?: NaviPayCustomerStatus.NOT_SET + val pspStatus = naviPayCustomerStatusHandler.getCustomerStatus(pspType = psp) // Step 2: Evaluate onboarding action val onboardingAction = @@ -245,11 +234,12 @@ constructor( val isOnboardingSuccess = onboardPsp(psp = psp, onboardingAction = onboardingAction, screenName = screenName) - val updatedStatus = getPspCustomerStatusMap()[psp] ?: NaviPayCustomerStatus.NOT_SET onPspEvaluated( PspEvaluationResult( - psp = if (isOnboardingSuccess) psp else null, - status = updatedStatus, + onboardingDataEntity = + if (isOnboardingSuccess) + naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = psp) + else null, isVpaActivationTriggered = onboardingAction == NaviPayOnboardingActionsType.ACCOUNT_ACTIVATION, isDeviceBindingTriggered = @@ -257,7 +247,11 @@ constructor( ) ) } else { - onPspEvaluated(PspEvaluationResult(psp = psp, status = pspStatus)) + onPspEvaluated( + PspEvaluationResult( + naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = psp) + ) + ) } } @@ -278,7 +272,6 @@ constructor( coroutineScope { this@NaviPayPspManager.screenName = screenName val pspSelectionConfigDeferred = async { getPspSelectionConfig() } - val pspCustomerStatusMapDeferred = async { getPspCustomerStatusMap() } // Step 1: Fetch supported PSP list for the ACCOUNT_ADDITION flow val pspSelectionConfig = pspSelectionConfigDeferred.await() @@ -293,12 +286,7 @@ constructor( } // Step 2: Check for bound PSP list - val pspCustomerStatusMap = pspCustomerStatusMapDeferred.await() - val boundSupportedPspList = - getBoundPspList( - supportedPspList = supportedPspList, - pspCustomerStatusMap = pspCustomerStatusMap, - ) + val boundSupportedPspList = getBoundPspList(supportedPspList = supportedPspList) // Step 3: Determine PSP using routing logic and notify val selectedPsp = @@ -331,9 +319,12 @@ constructor( ) onPspEvaluated( PspEvaluationResult( - psp = if (isOnboardingSuccess) selectedPsp else null, - status = - getPspCustomerStatusMap()[selectedPsp] ?: NaviPayCustomerStatus.NOT_SET, + onboardingDataEntity = + if (isOnboardingSuccess) + naviPayCustomerStatusHandler.getCustomerOnboardingEntity( + pspType = selectedPsp + ) + else null, isDeviceBindingTriggered = boundSupportedPspList.isEmpty(), ) ) @@ -398,17 +389,22 @@ constructor( onboardingAction = NaviPayOnboardingActionsType.ACCOUNT_ACTIVATION, screenName = screenName, ) - val selectedPspStatus = - getPspCustomerStatusMap()[selectedPsp] ?: NaviPayCustomerStatus.NOT_SET PspEvaluationResult( - psp = if (isOnboardingSuccess) psp else null, - status = selectedPspStatus, + onboardingDataEntity = + if (isOnboardingSuccess) + naviPayCustomerStatusHandler.getCustomerOnboardingEntity( + pspType = selectedPsp + ) + else null, isVpaActivationTriggered = true, ) } else { - val selectedPspStatus = - getPspCustomerStatusMap()[selectedPsp] ?: NaviPayCustomerStatus.NOT_SET - PspEvaluationResult(psp = psp, status = selectedPspStatus) + PspEvaluationResult( + onboardingDataEntity = + naviPayCustomerStatusHandler.getCustomerOnboardingEntity( + pspType = selectedPsp + ) + ) } } ?: PspEvaluationResult() } @@ -447,8 +443,12 @@ constructor( onboardPsp(psp = psp, onboardingAction = onboardingAction, screenName = screenName) PspEvaluationResult( - psp = if (isOnboardingSuccess) psp else null, - status = getPspCustomerStatusMap()[selectedPsp] ?: NaviPayCustomerStatus.NOT_SET, + onboardingDataEntity = + if (isOnboardingSuccess) + naviPayCustomerStatusHandler.getCustomerOnboardingEntity( + pspType = selectedPsp + ) + else null, isDeviceBindingTriggered = true, isVpaActivationTriggered = onboardingAction == NaviPayOnboardingActionsType.ACCOUNT_ACTIVATION, @@ -467,10 +467,9 @@ constructor( return mandatoryPspList } - private fun getBoundPspList( - supportedPspList: List, - pspCustomerStatusMap: Map, - ): List { + private suspend fun getBoundPspList(supportedPspList: List): List { + val pspCustomerStatusMap = naviPayCustomerStatusHandler.getCustomerStatusMap() + if (supportedPspList.isEmpty()) { return emptyList() } @@ -544,11 +543,6 @@ constructor( return null } - private suspend fun getPspCustomerStatusMap(): Map { - // TODO: Multibank - return map for all psps by fetching from db - return mapOf(PspType.JUSPAY to naviPayCustomerStatusHandler.getCustomerStatusOnMainThread()) - } - private suspend fun getPspSelectionConfig(): PspSelectionConfigContent { val naviPayDefaultAccountSelectionConfig = withContext(Dispatchers.IO) { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UPILiteScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UPILiteScreen.kt index 75a73c05b1..ae9807c53b 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UPILiteScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UPILiteScreen.kt @@ -283,7 +283,8 @@ fun UPILiteScreen( onDismissBottomSheet() }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@evaluateAndOnboardPspForLiteActions + if (pspEvaluationResult.onboardingDataEntity == null) + return@evaluateAndOnboardPspForLiteActions if (pspEvaluationResult.isOnboardingTriggered) { upiLiteViewModel.resetPreviousLinkedAccountsSize() upiLiteViewModel.getUpiLiteScreenInfo(shouldAutoInitTopUp = true) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UpiLiteBottomSheetContent.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UpiLiteBottomSheetContent.kt index a15c92bab7..6edde6974b 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UpiLiteBottomSheetContent.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/ui/UpiLiteBottomSheetContent.kt @@ -28,6 +28,8 @@ import com.navi.pay.common.ui.SuccessBottomSheetContent import com.navi.pay.management.lite.util.UpiLiteBottomSheetType import com.navi.pay.management.lite.util.getAnnotatedDescriptionForDisableUpiLite import com.navi.pay.management.lite.viewmodel.UpiLiteViewModel +import com.navi.rr.utils.rememberCoroutineScope +import kotlinx.coroutines.launch @Composable fun UpiLiteBottomSheetContent( @@ -46,6 +48,8 @@ fun UpiLiteBottomSheetContent( createMandateFlowForOnboardedUserWithBalanceGreaterThanThresholdAmount: () -> Unit, ) { + val scope = rememberCoroutineScope() + val upiLiteBalance by upiLiteViewModel.upiLiteBalance.collectAsStateWithLifecycle() val linkedAccountWithActiveLiteAccount by upiLiteViewModel.linkedAccountWithActiveLiteAccount.collectAsStateWithLifecycle() @@ -109,12 +113,14 @@ fun UpiLiteBottomSheetContent( primaryButton = stringResource(id = bottomSheetType.primaryButtonText), secondaryButton = "", onPrimaryButtonClicked = { - if (upiLiteViewModel.isUserOnboarded()) { - redirectToNaviPayHomeScreen() - } else { - if (bottomSheetType.checkForOnboarding) - triggerOnboardingAndSyncLiteBalance() - else redirectToNaviPayHomeScreen() + scope.launch { + if (upiLiteViewModel.isUserOnboarded()) { + redirectToNaviPayHomeScreen() + } else { + if (bottomSheetType.checkForOnboarding) + triggerOnboardingAndSyncLiteBalance() + else redirectToNaviPayHomeScreen() + } } }, onSecondaryButtonClicked = {}, diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/viewmodel/UpiLiteViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/viewmodel/UpiLiteViewModel.kt index a8333ee18e..73d7a929aa 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/viewmodel/UpiLiteViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/lite/viewmodel/UpiLiteViewModel.kt @@ -45,7 +45,6 @@ import com.navi.pay.common.model.view.SnackBarState import com.navi.pay.common.model.view.UpiLiteActiveAccountInfo import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.usecase.AccountListCheckBalanceUseCase import com.navi.pay.common.usecase.ArcNudgeUseCase @@ -1310,9 +1309,13 @@ constructor( UPI_LITE_TOP_UP_BACK_PRESS_BLOCK_TIME_MILLIS } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA + suspend fun isUserOnboarded(): Boolean { + val accountWithActiveUpiLite = linkedAccounts.value.singleOrNull { it.hasActiveLiteAccount } + val activeLiteAccountPsp = accountWithActiveUpiLite?.activeLiteAccountPsp + val pspType = + activeLiteAccountPsp + ?: PspType.JUSPAY // TODO: Remove hard coded Juspay after Multibank M3 + return naviPayCustomerStatusHandler.isUserOnboarded(pspType = pspType) } private fun updateLiteAccountBalanceAndUiIfPresentInPref(shouldAutoInitTopUp: Boolean) { @@ -1630,7 +1633,9 @@ constructor( vpaEntityList = selectedBankAccount.value?.vpaEntityList ?: emptyList(), screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@evaluateAndOnboardPspForFlow + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow resetCheckBalanceStates() updateNavigateToNextScreen( @@ -1639,7 +1644,7 @@ constructor( bankAccountUniqueId = selectedBankAccount.value?.accountId.orEmpty(), actionName = ACTION_PIN_SET, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) ) }, @@ -1659,7 +1664,8 @@ constructor( screenName = screenName, enabledAccountTypes = SAVINGS_ONLY_ENABLED_ACCOUNTS, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@handleAccountAdditionFlow + if (pspEvaluationResult.onboardingDataEntity == null) + return@handleAccountAdditionFlow resetPreviousLinkedAccountsSize() getUpiLiteScreenInfo(shouldAutoInitTopUp) @@ -2675,7 +2681,7 @@ constructor( } private fun updateNaviPaySessionAttributes() { - naviPaySessionHelper.createNewSessionId() + viewModelScope.launch(Dispatchers.IO) { naviPaySessionHelper.createNewSessionId() } } private suspend fun checkAndUpdateUiIfLiteSyncIsNeeded( @@ -2746,7 +2752,9 @@ constructor( if (selectedPsp == null) { evaluateAndOnboardPspForLiteActions( - onPspEvaluated = { pspEvaluationResult -> selectedPsp = pspEvaluationResult.psp } + onPspEvaluated = { pspEvaluationResult -> + selectedPsp = pspEvaluationResult.onboardingDataEntity?.pspType + } ) } @@ -2771,7 +2779,7 @@ constructor( getRegistrationCredData( upiRequestId = upiRequestId, linkedAccountEntity = linkedAccountEntity, - pspType = selectedPsp!!, + pspType = selectedPsp ?: return, ) val npciResult = @@ -2787,7 +2795,7 @@ constructor( linkedAccountEntity = linkedAccountEntity, shouldAutoInitTopUp = shouldAutoInitTopUp, initCreateAndExecuteMandate = initCreateAndExecuteMandate, - pspType = selectedPsp!!, + pspType = selectedPsp ?: return, ) } is NpciResult.Error -> { @@ -3075,7 +3083,9 @@ constructor( var onboardedPsp: PspType? = null evaluateAndOnboardPspForLiteActions( - onPspEvaluated = { pspEvaluationResult -> onboardedPsp = pspEvaluationResult.psp } + onPspEvaluated = { pspEvaluationResult -> + onboardedPsp = pspEvaluationResult.onboardingDataEntity?.pspType + } ) if (onboardedPsp == null) { return@launch @@ -3876,7 +3886,8 @@ constructor( evaluateAndOnboardPspForLiteActions( onOnboardingTriggered = { updateTriggerDismissBottomSheet() }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@evaluateAndOnboardPspForLiteActions + if (pspEvaluationResult.onboardingDataEntity == null) + return@evaluateAndOnboardPspForLiteActions if (pspEvaluationResult.isOnboardingTriggered) { resetPreviousLinkedAccountsSize() } @@ -3891,19 +3902,19 @@ constructor( val upiLiteBalance = upiLiteBalanceUseCase.execute() // If balance = 0, we can disable lite without onboarding if (upiLiteBalance.getFormattedAmountWithDecimal() != ZERO_STRING_WITH_DECIMAL) { - var pspEvaluationResult: PspEvaluationResult? = null + var pspType: PspType? = null evaluateAndOnboardPspForLiteActions( onOnboardingTriggered = { updateTriggerDismissBottomSheet() }, - onPspEvaluated = { - pspEvaluationResult = it - if (pspEvaluationResult?.psp == null) - return@evaluateAndOnboardPspForLiteActions - if (pspEvaluationResult?.isOnboardingTriggered == true) { + onPspEvaluated = { pspEvaluationResult -> + pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForLiteActions + if (pspEvaluationResult.isOnboardingTriggered) { resetPreviousLinkedAccountsSize() } }, ) - if (pspEvaluationResult?.psp == null) return@launch + if (pspType == null) return@launch } if (!checkIsInternetAvailableOrShowError()) return@launch if (checkIsAirplaneModeOnOrShowError()) return@launch @@ -3977,22 +3988,6 @@ constructor( } } - private suspend fun evaluatePspForNonZeroBalance( - onOnboardingTriggered: suspend () -> Unit - ): PspType? { - var pspEvaluationResult: PspEvaluationResult? = null - evaluateAndOnboardPspForLiteActions( - onOnboardingTriggered = { onOnboardingTriggered() }, - onPspEvaluated = { - pspEvaluationResult = it - if (pspEvaluationResult?.isOnboardingTriggered == true) { - resetPreviousLinkedAccountsSize() - } - }, - ) - return pspEvaluationResult?.psp - } - fun onDeleteMandateAndDisableLite() { viewModelScope.launch(coroutineDispatcherProvider.io) { val liteMandateInfo = upiLiteMandateInfo.value @@ -4288,7 +4283,9 @@ constructor( ) var onboardedPsp: PspType? = null evaluateAndOnboardPspForLiteActions( - onPspEvaluated = { pspEvaluationResult -> onboardedPsp = pspEvaluationResult.psp } + onPspEvaluated = { pspEvaluationResult -> + onboardedPsp = pspEvaluationResult.onboardingDataEntity?.pspType + } ) if (onboardedPsp == null) { return@launch @@ -4301,7 +4298,7 @@ constructor( amount = createMandateAmountFormatted, upiRequestId = upiRequestId, payeeVpa = getFormattedPayeeVpaForLiteMandate(lrn = lrn), - pspType = onboardedPsp!!, + pspType = onboardedPsp ?: return@launch, ) updateEnableButtonLottieState(isLoaderVisible = false) @@ -4950,9 +4947,9 @@ constructor( private suspend fun handlePayerInitiatedRevoke() { evaluateAndOnboardPspForLiteActions( onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForLiteActions - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForLiteActions val upiRequestId = upiRequestIdUseCase.execute() val revokeCredData = credDataProvider.mandateCred( @@ -4962,7 +4959,7 @@ constructor( amount = upiLiteMandateInfo.value?.amount.orEmpty(), payeeVpa = upiLiteMandateInfo.value?.payeeVpa.orEmpty(), upiRequestId = upiRequestId, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) updateDeleteMandateLoaderState(isLoaderVisible = false) @@ -5115,9 +5112,9 @@ constructor( vpaEntityList = linkedAccount.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow if (!checkIsInternetAvailableOrShowError()) return@evaluateAndOnboardPspForFlow if (checkIsAirplaneModeOnOrShowError()) return@evaluateAndOnboardPspForFlow @@ -5146,7 +5143,7 @@ constructor( accountListCheckBalanceUseCase.onCheckBalanceClicked( linkedAccount = linkedAccount, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultReceived = { if (isAccountSelectionBottomSheetVisible) { updateBottomSheetUiState( diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfActiveOrCompletedCategoryViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfActiveOrCompletedCategoryViewModel.kt index 676fd06429..4b87091d80 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfActiveOrCompletedCategoryViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfActiveOrCompletedCategoryViewModel.kt @@ -384,9 +384,9 @@ constructor( vpaEntity = getVpaEntityForMandate() ?: return@launch, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForVpa - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForVpa if (pspEvaluationResult.isOnboardingTriggered) { showRedirectionBottomSheet( @@ -401,7 +401,7 @@ constructor( _navigateToNextScreen.emit( ModifyMandateScreenDestination( mandateEntity = mandateEntityValue.value, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) ) }, @@ -461,9 +461,9 @@ constructor( updateBottomSheetUIState(showBottomSheet = false) }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForVpa - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForVpa if (pspEvaluationResult.isOnboardingTriggered) { val redirectionTitleText = @@ -537,7 +537,7 @@ constructor( amount = mandateEntityValue.value.amount, payeeVpa = mandateEntityValue.value.payeeVpa, upiRequestId = upiRequestId, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) val npciResult = @@ -781,9 +781,9 @@ constructor( screenName = screenName, onOnboardingTriggered = { updateBottomSheetUIState(showBottomSheet = false) }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForVpa - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForVpa if (pspEvaluationResult.isOnboardingTriggered) { showRedirectionBottomSheet( @@ -845,7 +845,7 @@ constructor( amount = mandateEntityValue.value.amount, payeeVpa = mandateEntityValue.value.payeeVpa, upiRequestId = upiRequestId, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) val npciResult = diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfPendingCategoryViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfPendingCategoryViewModel.kt index e66e1f7d24..2fa8ec621a 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfPendingCategoryViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/mandate/viewmodel/MandateDetailOfPendingCategoryViewModel.kt @@ -429,9 +429,9 @@ constructor( getOnboardedStackDataForMandate( onOnboardingTriggered = { updateBottomSheetUIState(showBottomSheet = false) }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@getOnboardedStackDataForMandate - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@getOnboardedStackDataForMandate if (pspEvaluationResult.isOnboardingTriggered) { if (mandateEntity != null && selectedBankAccount.value != null) { @@ -481,9 +481,9 @@ constructor( } if (isPendingMandateOfTypeCreate) { - createMandate(pspType = pspEvaluationResult.psp) + createMandate(pspType = pspType) } else { - approveMandate(pspType = pspEvaluationResult.psp) + approveMandate(pspType = pspType) } updateCtaLoaderTypeState(CtaLoaderType.None) }, @@ -858,7 +858,7 @@ constructor( getOnboardedStackDataForMandate( onOnboardingTriggered = { updateBottomSheetUIState(showBottomSheet = false) }, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { + if (pspEvaluationResult.onboardingDataEntity == null) { return@getOnboardedStackDataForMandate } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/moneytransfer/scanpay/viewmodel/QrScannerViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/moneytransfer/scanpay/viewmodel/QrScannerViewModel.kt index 2834d006ae..862df22b0e 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/moneytransfer/scanpay/viewmodel/QrScannerViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/moneytransfer/scanpay/viewmodel/QrScannerViewModel.kt @@ -188,7 +188,7 @@ constructor( } private fun updateNaviPaySessionId() { - naviPaySessionHelper.createNewSessionId() + viewModelScope.launch(Dispatchers.IO) { naviPaySessionHelper.createNewSessionId() } } fun unregisterLightSensorListener() { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/paytocontacts/viewmodel/PayToContactsViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/paytocontacts/viewmodel/PayToContactsViewModel.kt index 9085b24b92..823e86d4a0 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/paytocontacts/viewmodel/PayToContactsViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/paytocontacts/viewmodel/PayToContactsViewModel.kt @@ -335,7 +335,7 @@ constructor( } private fun updateNaviPaySessionId() { - naviPaySessionHelper.createNewSessionId() + viewModelScope.launch(Dispatchers.IO) { naviPaySessionHelper.createNewSessionId() } } fun getNaviPaySessionAttributes(): Map { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/savedbeneficiary/viewmodel/SavedBeneficiaryViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/savedbeneficiary/viewmodel/SavedBeneficiaryViewModel.kt index 6c62154a5b..0449bfc427 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/savedbeneficiary/viewmodel/SavedBeneficiaryViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/savedbeneficiary/viewmodel/SavedBeneficiaryViewModel.kt @@ -355,7 +355,7 @@ constructor( } private fun updateNaviPaySessionId() { - naviPaySessionHelper.createNewSessionId() + viewModelScope.launch(Dispatchers.IO) { naviPaySessionHelper.createNewSessionId() } } fun getNaviPaySessionAttributes(): Map = diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/addnew/viewmodel/AddNewUpiNumberViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/addnew/viewmodel/AddNewUpiNumberViewModel.kt index 57838be359..aa508fb01a 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/addnew/viewmodel/AddNewUpiNumberViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/addnew/viewmodel/AddNewUpiNumberViewModel.kt @@ -94,9 +94,11 @@ constructor( } private fun onScreenLandEvent() { - naviPayAnalytics.onLanded( - naviPayCustomerStatus = naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() - ) + viewModelScope.launch(Dispatchers.IO) { + naviPayAnalytics.onLanded( + naviPayCustomerStatusMap = naviPayCustomerStatusHandler.getCustomerStatusMap() + ) + } } private fun fetchLinkedAccounts() { @@ -130,13 +132,15 @@ constructor( onUpiNumberChanged(event.upiNumber) } is AddNewUpiNumberScreenContract.Event.OnLinkUpiNumberClicked -> { - naviPayAnalytics.onLinkUpiNumberClick( - upiNumber = state.value.inputUpiNumber.text, - selectedBankAccount = state.value.selectedAccount?.accountId ?: "", - naviPayCustomerStatus = - naviPayCustomerStatusHandler.getCustomerStatusOnMainThread(), - ) - onLinkUpiNumberClicked() + viewModelScope.launch(Dispatchers.IO) { + onLinkUpiNumberClicked() + naviPayAnalytics.onLinkUpiNumberClick( + upiNumber = state.value.inputUpiNumber.text, + selectedBankAccount = state.value.selectedAccount?.accountId ?: "", + naviPayCustomerStatusMap = + naviPayCustomerStatusHandler.getCustomerStatusMap(), + ) + } } is AddNewUpiNumberScreenContract.Event.OnUpdateSelectedAccount -> { updateSelectedAccount(event.selectedAccount) @@ -174,13 +178,12 @@ constructor( private fun onDropDownClicked() { viewModelScope.launch(Dispatchers.IO) { - naviPayAnalytics.onDropDownClick( - naviPayCustomerStatus = - naviPayCustomerStatusHandler.getCustomerStatusOnMainThread(), - selectedBankAccount = state.value.selectedAccount?.accountId ?: "", - ) _effect.emit(AddNewUpiNumberScreenContract.Effect.DropDownClicked) updateBottomSheetUIState(showBottomSheet = true, bottomSheetStateChange = true) + naviPayAnalytics.onDropDownClick( + naviPayCustomerStatusMap = naviPayCustomerStatusHandler.getCustomerStatusMap(), + selectedBankAccount = state.value.selectedAccount?.accountId ?: "", + ) } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/link/viewmodel/LinkUpiNumberViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/link/viewmodel/LinkUpiNumberViewModel.kt index f5031cbceb..22b47e42fc 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/link/viewmodel/LinkUpiNumberViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/link/viewmodel/LinkUpiNumberViewModel.kt @@ -22,6 +22,7 @@ import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.RefreshUpiNumbersUseCase import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.NaviPayCommonUtils.getHelpCtaData +import com.navi.pay.common.utils.fetchUserPhoneNumber import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.common.viewmodel.NaviPayBaseVM import com.navi.pay.entry.NaviPayActivityDataProvider @@ -170,9 +171,7 @@ constructor( } private fun updatePhoneNumber() { - viewModelScope.launch(Dispatchers.IO) { - _phoneNumber.update { deviceInfoProvider.getPhoneNumber().takeLast(10) } - } + viewModelScope.launch(Dispatchers.IO) { _phoneNumber.update { fetchUserPhoneNumber() } } } fun onAddCustomNumberClickEvent() { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/ActivateUpiNumberModalContent.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/ActivateUpiNumberModalContent.kt index 26e9fc88bd..027cc35dd4 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/ActivateUpiNumberModalContent.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/ActivateUpiNumberModalContent.kt @@ -33,6 +33,7 @@ import com.navi.design.font.naviFontFamily import com.navi.naviwidgets.extensions.NaviText import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.ui.LoaderRoundedButton @@ -48,7 +49,7 @@ fun ActivateUpiNumberModalContent( closeSheet: () -> Unit, showLoader: Boolean, cancelActionRequest: () -> Unit, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { val bankNameAccountNumber = activateUpiNumberConfirmation.upiNumberLinkedAccountEntity.bankNameAccountNumber @@ -117,7 +118,7 @@ fun ActivateUpiNumberModalContent( naviPayAnalytics.onActivateCancelClick( upiNumberLinkedAccountEntity = activateUpiNumberConfirmation.upiNumberLinkedAccountEntity, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) cancelActionRequest() closeSheet() @@ -135,7 +136,7 @@ fun ActivateUpiNumberModalContent( currentUpiNumber = activateUpiNumberConfirmation.upiNumber.upiNumber, upiNumberLinkedAccountEntity = activateUpiNumberConfirmation.upiNumberLinkedAccountEntity, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) activateUpiNumber(activateUpiNumberConfirmation) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberBottomSheetContent.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberBottomSheetContent.kt index 513f8e5b6a..a8a3badb85 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberBottomSheetContent.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberBottomSheetContent.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.unit.dp import com.navi.naviwidgets.R as widgetsR import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.ui.BottomSheetContentWithIconHeaderDescButton import com.navi.pay.common.ui.LinkUPINumberConfirmationBottomSheetWithVPAInfoContent @@ -38,7 +39,7 @@ fun UpiNumberBottomSheetContent( closeSheet: () -> Unit, showLoader: Boolean, cancelActionRequest: () -> Unit, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { when (upiNumberBottomSheetType) { is UpiNumberBottomSheetType.ActivateUpiNumberConfirmation -> @@ -49,7 +50,7 @@ fun UpiNumberBottomSheetContent( naviPayAnalytics = naviPayAnalytics, closeSheet = closeSheet, showLoader = showLoader, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) is UpiNumberBottomSheetType.UpiNumberMenuOptions -> UpiNumberMenuOptionsModalContent( @@ -61,7 +62,7 @@ fun UpiNumberBottomSheetContent( naviPayAnalytics = naviPayAnalytics, showLoader = showLoader, closeSheet = closeSheet, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) is UpiNumberBottomSheetType.SelectAccountToLink -> UpiNumberSelectAccountsModalContent( @@ -71,7 +72,7 @@ fun UpiNumberBottomSheetContent( cancelActionRequest = cancelActionRequest, showLoader = showLoader, closeSheet = closeSheet, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) is UpiNumberBottomSheetType.PortUpiNumberLinkedToExternalVpa -> LinkUPINumberConfirmationBottomSheetWithVPAInfoContent( @@ -93,7 +94,7 @@ fun UpiNumberBottomSheetContent( externalVpa = upiNumberBottomSheetType.existingVpa, onPrimaryButtonClicked = { naviPayAnalytics.onUpiNumberConfirmationBottomSheetConfirmClick( - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, upiNumber = upiNumberBottomSheetType.upiNumber, bankCode = upiNumberBottomSheetType.upiNumberLinkedAccountEntity.bankCode, currentMappedVpa = @@ -111,7 +112,7 @@ fun UpiNumberBottomSheetContent( }, onSecondaryButtonClicked = { naviPayAnalytics.onUpiNumberConfirmationBottomSheetCancelClick( - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, upiNumber = upiNumberBottomSheetType.upiNumber, bankCode = upiNumberBottomSheetType.upiNumberLinkedAccountEntity.bankCode, currentMappedVpa = @@ -147,7 +148,7 @@ fun UpiNumberBottomSheetContent( buttonText = stringResource(id = R.string.retry), onButtonClicked = { naviPayAnalytics.onLinkPhoneNumberRetryClicked( - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, bankCode = upiNumberBottomSheetType.upiNumberLinkedAccountEntity.bankCode, maskedAccountNumber = upiNumberBottomSheetType.upiNumberLinkedAccountEntity diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberMenuOptionsModalContent.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberMenuOptionsModalContent.kt index 9113ab9bae..5f62d10e3b 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberMenuOptionsModalContent.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberMenuOptionsModalContent.kt @@ -34,6 +34,7 @@ import com.navi.design.font.naviFontFamily import com.navi.naviwidgets.extensions.NaviText import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.ui.LoaderRoundedButton @@ -53,7 +54,7 @@ fun UpiNumberMenuOptionsModalContent( showLoader: Boolean, closeSheet: () -> Unit, cancelActionRequest: () -> Unit, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { val (selectedItem, onOptionSelected) = @@ -104,17 +105,17 @@ fun UpiNumberMenuOptionsModalContent( R.string.link_to_other_bank_account -> naviPayAnalytics.onMenuOptionCancelClicked( optionId = "link_other_bank", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) R.string.deactivate -> naviPayAnalytics.onMenuOptionCancelClicked( optionId = "deactivate", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) R.string.delete_upi_number -> naviPayAnalytics.onMenuOptionCancelClicked( optionId = "delete_upi_number", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) } }, @@ -133,21 +134,21 @@ fun UpiNumberMenuOptionsModalContent( R.string.link_to_other_bank_account -> { naviPayAnalytics.onMenuOptionSelected( optionId = "link_other_bank", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) onLinkUpiNumberToOtherAccountClick(upiNumberMenuOptions) } R.string.deactivate -> { naviPayAnalytics.onMenuOptionSelected( optionId = "deactivate", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) deactivateUpiNumber(upiNumberMenuOptions) } R.string.delete_upi_number -> { naviPayAnalytics.onMenuOptionSelected( optionId = "delete_upi_number", - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) naviPayAnalytics.onDeleteUpiNumberClicked() deleteUpiNumber(upiNumberMenuOptions) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberScreen.kt index 953f36ed1a..f9979f664a 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberScreen.kt @@ -67,6 +67,7 @@ import com.navi.naviwidgets.extensions.NaviText import com.navi.pay.NavGraphs import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayRouter import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor @@ -149,6 +150,8 @@ fun UpiNumberScreen( val upiNumberLinkedAccountEntities by remember { derivedStateOf { upiNumberViewModel.upiNumberLinkedAccountEntities } } + val naviPayCustomerStatusMap by + upiNumberViewModel.naviPayCustomerStatusMap.collectAsStateWithLifecycle() val clipboardManager = remember { naviPayActivity.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager @@ -238,7 +241,7 @@ fun UpiNumberScreen( isPrimary = upiNumberLinkedAccountEntity.isPrimary, upiNumber = phoneNumber, bankCode = upiNumberLinkedAccountEntity.bankCode, - naviPayCustomerStatus = upiNumberViewModel.naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, maskedAccountNumber = upiNumberLinkedAccountEntity.maskedAccountNumber, ) copyToClipboard( @@ -250,12 +253,62 @@ fun UpiNumberScreen( val onMenuClick = { upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, upiNumber: UpiNumber -> - naviPayAnalytics.onMenuClick( + scope.launch { + naviPayAnalytics.onMenuClick( + currentMappedVpa = upiNumberLinkedAccountEntity.vpa, + isPrimary = upiNumberLinkedAccountEntity.isPrimary, + upiNumber = upiNumber.upiNumber, + bankCode = upiNumberLinkedAccountEntity.bankCode, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, + maskedAccountNumber = upiNumberLinkedAccountEntity.maskedAccountNumber, + ) + if (!upiNumberViewModel.isUserOnboarded()) { + naviPayActivity.launchOnboardingSDK( + action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, + source = NaviPayAnalytics.NAVI_PAY_UPI_NUMBER_V2, + ) + } else { + upiNumberViewModel.onUpiNumberMenuClick( + upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, + upiNumber = upiNumber, + ) + } + } + Unit + } + + val onActivateClick = + { upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, upiNumber: UpiNumber -> + scope.launch { + naviPayAnalytics.onActivateClick( + upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, + currentUpiNumber = upiNumber, + ) + if (!upiNumberViewModel.isUserOnboarded()) { + naviPayActivity.launchOnboardingSDK( + action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, + source = NaviPayAnalytics.NAVI_PAY_UPI_NUMBER_V2, + ) + } else { + upiNumberViewModel.onActivateUpiNumberClick( + upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, + upiNumber = upiNumber, + ) + } + } + Unit + } + + val onLinkPhoneNumberClick = { upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity -> + scope.launch { + dismissBottomSheet() + naviPayAnalytics.onLinkToNaviPayClick( + naviPayCustomerStatusMap = naviPayCustomerStatusMap, currentMappedVpa = upiNumberLinkedAccountEntity.vpa, isPrimary = upiNumberLinkedAccountEntity.isPrimary, - upiNumber = upiNumber.upiNumber, + upiNumber = phoneNumber, bankCode = upiNumberLinkedAccountEntity.bankCode, - naviPayCustomerStatus = upiNumberViewModel.naviPayCustomerStatus, maskedAccountNumber = upiNumberLinkedAccountEntity.maskedAccountNumber, ) if (!upiNumberViewModel.isUserOnboarded()) { @@ -264,53 +317,12 @@ fun UpiNumberScreen( source = NaviPayAnalytics.NAVI_PAY_UPI_NUMBER_V2, ) } else { - upiNumberViewModel.onUpiNumberMenuClick( - upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, - upiNumber = upiNumber, + upiNumberViewModel.checkUpiNumberAvailabilityAndLink( + upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity ) } } - - val onActivateClick = - { upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity, upiNumber: UpiNumber -> - naviPayAnalytics.onActivateClick( - upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, - naviPayCustomerStatus = upiNumberViewModel.naviPayCustomerStatus, - currentUpiNumber = upiNumber, - ) - if (!upiNumberViewModel.isUserOnboarded()) { - naviPayActivity.launchOnboardingSDK( - action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, - source = NaviPayAnalytics.NAVI_PAY_UPI_NUMBER_V2, - ) - } else { - upiNumberViewModel.onActivateUpiNumberClick( - upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity, - upiNumber = upiNumber, - ) - } - } - - val onLinkPhoneNumberClick = { upiNumberLinkedAccountEntity: UpiNumberLinkedAccountEntity -> - dismissBottomSheet() - naviPayAnalytics.onLinkToNaviPayClick( - naviPayCustomerStatus = upiNumberViewModel.naviPayCustomerStatus, - currentMappedVpa = upiNumberLinkedAccountEntity.vpa, - isPrimary = upiNumberLinkedAccountEntity.isPrimary, - upiNumber = phoneNumber, - bankCode = upiNumberLinkedAccountEntity.bankCode, - maskedAccountNumber = upiNumberLinkedAccountEntity.maskedAccountNumber, - ) - if (!upiNumberViewModel.isUserOnboarded()) { - naviPayActivity.launchOnboardingSDK( - action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, - source = NaviPayAnalytics.NAVI_PAY_UPI_NUMBER_V2, - ) - } else { - upiNumberViewModel.checkUpiNumberAvailabilityAndLink( - upiNumberLinkedAccountEntity = upiNumberLinkedAccountEntity - ) - } + Unit } val onAddNewNumberClick = { @@ -357,7 +369,7 @@ fun UpiNumberScreen( showLoader = showLoader, isLinkToUpiNumberLottieEnabled = isLinkToUpiNumberLottieEnabled, snackBarState = snackBarState, - naviPayCustomerStatus = upiNumberViewModel.naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, dismissBottomSheet = dismissBottomSheet, activateUpiNumber = upiNumberViewModel::activateUpiNumber, onLinkUpiNumberToOtherAccountClick = @@ -408,7 +420,7 @@ fun UpiNumberMainScreen( showLoader: Boolean, isLinkToUpiNumberLottieEnabled: Boolean, snackBarState: SnackBarState, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, showBottomSheet: Boolean, dismissBottomSheet: () -> Unit, activateUpiNumber: (UpiNumberBottomSheetType.ActivateUpiNumberConfirmation) -> Unit, @@ -529,7 +541,7 @@ fun UpiNumberMainScreen( naviPayAnalytics = naviPayAnalytics, closeSheet = dismissBottomSheet, showLoader = showLoader, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberSelectAccountsModalContent.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberSelectAccountsModalContent.kt index 233ece9db2..3edeb19f9e 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberSelectAccountsModalContent.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/ui/UpiNumberSelectAccountsModalContent.kt @@ -41,6 +41,7 @@ import com.navi.design.font.naviFontFamily import com.navi.naviwidgets.extensions.NaviText import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.ui.ImageWithCircularBackground @@ -65,7 +66,7 @@ fun UpiNumberSelectAccountsModalContent( showLoader: Boolean, closeSheet: () -> Unit, cancelActionRequest: () -> Unit, - naviPayCustomerStatus: NaviPayCustomerStatus, + naviPayCustomerStatusMap: Map?, ) { val initialSelectedAccount = remember(selectAccountToLink.accountList) { selectAccountToLink.accountList.first() } @@ -144,7 +145,7 @@ fun UpiNumberSelectAccountsModalContent( ) { naviPayAnalytics.onLinkToOtherBankClick( newBankCode = selectedAccount.bankCode, - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap, ) linkUpiNumberToOtherAccount(selectAccountToLink, selectedAccount) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/viewmodel/UpiNumberViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/viewmodel/UpiNumberViewModel.kt index 149cffce27..d7b1b27dae 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/viewmodel/UpiNumberViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/upinumber/list/viewmodel/UpiNumberViewModel.kt @@ -14,6 +14,7 @@ import com.navi.pay.R import com.navi.pay.analytics.NaviPayAnalytics import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_UPI_NUMBER_V2 import com.navi.pay.common.model.view.NaviPayScreenType +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.CheckUpiNumberAvailabilityUseCase @@ -21,6 +22,7 @@ import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.RefreshUpiNumbersUseCase import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.NaviPayCommonUtils.getHelpCtaData +import com.navi.pay.common.utils.fetchUserPhoneNumber import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.common.viewmodel.NaviPayBaseVM import com.navi.pay.destinations.LinkUpiNumberScreenDestination @@ -47,7 +49,6 @@ import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_1 import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_2 import com.navi.pay.utils.MAX_NON_MOBILE_UPI_NUMBER import com.navi.pay.utils.MAX_UPI_NUMBER_ALLOWED -import com.navi.pay.utils.PHONE_NUMBER_LENGTH import com.navi.pay.utils.UPI_NUMBER_ACTION_DELETE import com.navi.pay.utils.UPI_NUMBER_LINK import com.navi.pay.utils.UPI_NUMBER_STATUS_DELETED @@ -131,8 +132,9 @@ constructor( private val _isLinkToUpiNumberLottieEnabled = MutableStateFlow(false) val isLinkToUpiNumberLottieEnabled = _isLinkToUpiNumberLottieEnabled.asStateFlow() - val naviPayCustomerStatus - get() = naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() + private val _naviPayCustomerStatusMap = + MutableStateFlow?>(null) + val naviPayCustomerStatusMap = _naviPayCustomerStatusMap.asStateFlow() private val _navigateToNextScreen = MutableSharedFlow() val navigateToNextScreen = _navigateToNextScreen.asSharedFlow() @@ -147,10 +149,13 @@ constructor( } private fun onScreenLandEvent() { - naviPayAnalytics.onUpiNumberScreenLanded( - upiNumberLinkedAccounts = upiNumberLinkedAccountEntities, - naviPayCustomerStatus = naviPayCustomerStatus, - ) + viewModelScope.launch(Dispatchers.IO) { + _naviPayCustomerStatusMap.update { naviPayCustomerStatusHandler.getCustomerStatusMap() } + naviPayAnalytics.onUpiNumberScreenLanded( + upiNumberLinkedAccounts = upiNumberLinkedAccountEntities, + naviPayCustomerStatusMap = naviPayCustomerStatusMap.value, + ) + } } private fun updateAndFetchUpiNumberLinkedAccounts() { @@ -161,9 +166,7 @@ constructor( it.accountType != AccountType.CREDIT.name && it.accountType != AccountType.UPICREDIT.name } - _phoneNumber.update { - deviceInfoProvider.getPhoneNumber().takeLast(PHONE_NUMBER_LENGTH) - } + _phoneNumber.update { fetchUserPhoneNumber() } if (noOfSavingsAccounts == 0) { updateScreenUIState(UpiSettingsScreenState.NoUpiNumberLinked) } else { @@ -176,11 +179,11 @@ constructor( fun onAddNewNumberClickedEvent() { if (isAddNewNonMobileNumberUpiNumberEnabled.value) { naviPayAnalytics.onAddNewUpiNumberBannerClick( - naviPayCustomerStatus = naviPayCustomerStatus + naviPayCustomerStatusMap = naviPayCustomerStatusMap.value ) } else { naviPayAnalytics.onAddNewUpiNumberMaximumLimitReachedClick( - naviPayCustomerStatus = naviPayCustomerStatus + naviPayCustomerStatusMap = naviPayCustomerStatusMap.value ) } } @@ -193,9 +196,9 @@ constructor( _screenState.update { screenState } } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA + suspend fun isUserOnboarded(): Boolean { + // TODO: Multibank - Remove hardcoded Juspay after multibank M3 integration + return naviPayCustomerStatusHandler.isUserOnboarded(pspType = PspType.JUSPAY) } private fun updateIsLinkToUpiNumberLottieEnabled(isEnabled: Boolean) { @@ -483,7 +486,7 @@ constructor( handlePortSuccess = { existingVpa -> updateIsLinkToUpiNumberLottieEnabled(isEnabled = false) naviPayAnalytics.onUpiNumberConfirmationBottomSheetLanded( - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap.value, upiNumber = phoneNumber.value, bankCode = upiNumberLinkedAccountEntity.bankCode, currentMappedVpa = upiNumberLinkedAccountEntity.vpa, @@ -510,7 +513,7 @@ constructor( ) { updateIsLinkToUpiNumberLottieEnabled(isEnabled = false) naviPayAnalytics.onLinkPhoneNumberRetryBottomSheetLanded( - naviPayCustomerStatus = naviPayCustomerStatus, + naviPayCustomerStatusMap = naviPayCustomerStatusMap.value, bankCode = upiNumberLinkedAccountEntity.bankCode, maskedAccountNumber = upiNumberLinkedAccountEntity.maskedAccountNumber, ) @@ -767,7 +770,7 @@ constructor( fun onHelpClicked() { viewModelScope.launch(Dispatchers.Default) { - naviPayAnalytics.onHelpClick(naviPayCustomerStatus) + naviPayAnalytics.onHelpClick(naviPayCustomerStatusMap.value) updateNavigateToNextScreenOnHelpCta(helpCta) } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/network/di/NaviPayModule.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/network/di/NaviPayModule.kt index 8c5bfd6c41..1b603cb683 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/network/di/NaviPayModule.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/network/di/NaviPayModule.kt @@ -36,6 +36,7 @@ import com.navi.pay.common.widget.NaviPayWidgetManager import com.navi.pay.common.widget.NaviPayWidgetManagerImpl import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_10_11 import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_11_12 +import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_12_13 import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_1_2 import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_2_3 import com.navi.pay.db.NAVI_PAY_APP_DATABASE_MIGRATION_3_4 @@ -161,6 +162,7 @@ object NaviPayNetworkModule { NAVI_PAY_APP_DATABASE_MIGRATION_9_10, NAVI_PAY_APP_DATABASE_MIGRATION_10_11, NAVI_PAY_APP_DATABASE_MIGRATION_11_12, + NAVI_PAY_APP_DATABASE_MIGRATION_12_13, ) .build() @@ -274,6 +276,11 @@ object NaviPayNetworkModule { @Provides fun providesOrderTagSummaryDao(naviPayAppDatabase: NaviPayAppDatabase) = naviPayAppDatabase.orderTagSummaryDao() + + @Singleton + @Provides + fun providesOnboardingDataDao(naviPayAppDatabase: NaviPayAppDatabase) = + naviPayAppDatabase.customerOnboardingDao() } @Module diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/ui/AccountAdditionScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/ui/AccountAdditionScreen.kt index 51849ed216..6338adb9d5 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/ui/AccountAdditionScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/ui/AccountAdditionScreen.kt @@ -29,6 +29,7 @@ import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems import com.navi.base.utils.orTrue import com.navi.common.upi.UPI_RESULT_CODE +import com.navi.pay.common.model.view.PspType import com.navi.pay.common.ui.NaviPayModalBottomSheet import com.navi.pay.common.utils.ErrorEventHandler import com.navi.pay.common.utils.NaviPayEventBus @@ -49,6 +50,7 @@ fun AccountAdditionScreen( naviPayOnboardingActivity: NaviPayOnboardingActivity, enabledAccountAdditionTypes: EnabledAccountAdditionTypes, accountAdditionViewModel: AccountAdditionViewModel = hiltViewModel(), + onboardingPsp: PspType, ) { val state by accountAdditionViewModel.state.collectAsStateWithLifecycle() diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/viewmodel/AccountAdditionViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/viewmodel/AccountAdditionViewModel.kt index 9048e8b81a..24279e9428 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/viewmodel/AccountAdditionViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/add/viewmodel/AccountAdditionViewModel.kt @@ -16,7 +16,6 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.PagingData import androidx.paging.cachedIn -import com.navi.base.cache.datastore.DataStoreHelper import com.navi.base.utils.BaseUtils import com.navi.base.utils.ResourceProvider import com.navi.common.di.CoroutineDispatcherProvider @@ -59,7 +58,6 @@ import com.navi.pay.onboarding.account.common.model.view.AccountAdditionUiState import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity import com.navi.pay.onboarding.common.utils.OnboardingIntentDataProvider import com.navi.pay.onboarding.common.utils.getUpiGuidelineItems -import com.navi.pay.utils.DS_KEY_NAVI_PAY_CUSTOMER_STATUS import com.navi.pay.utils.NAVI_PAY_GREEN_TICK_LOTTIE import com.navi.pay.utils.NAVI_PAY_PURPLE_CTA_LOADER_LOTTIE import com.navi.pay.utils.refresh @@ -97,14 +95,13 @@ constructor( private val naviPayManager: NaviPayManager, private val naviPayNetworkConnectivity: NaviPayNetworkConnectivity, private val deviceInfoProvider: DeviceInfoProvider, - private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, private val refreshLinkedAccountsUseCase: RefreshLinkedAccountsUseCase, - private val dataStoreHelper: DataStoreHelper, private val coroutineDispatcherProvider: CoroutineDispatcherProvider, onboardingDataFromIntentProvider: OnboardingIntentDataProvider, private val naviPaySessionHelper: NaviPaySessionHelper, private val liteAccountSyncUseCase: LiteAccountSyncUseCase, private val upiRequestIdUseCase: UpiRequestIdUseCase, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, ) : NaviPayBaseVM(), AccountAdditionScreenContract { private val naviPayAnalytics: NaviPayAnalytics.NaviPayAccountAddition = @@ -118,6 +115,8 @@ constructor( preferredBankCode = "", ) + private val onboardingPsp = savedStateHandle.get("onboardingPsp")!! + private val enabledAccountTypes = enabledAccountAdditionTypes.accountTypes private val addAccountSuccessDescription = @@ -259,7 +258,7 @@ constructor( ) } is AccountAdditionScreenContract.Event.OnBackPressed -> { - updateCustomerStatusInDataStoreAndFinishActivity(isBackPressed = true) + finishActivity(isBackPressed = true) } else -> { _bindingProgress.update { 0f } @@ -273,14 +272,10 @@ constructor( } } - private suspend fun updateCustomerStatusInDataStoreAndFinishActivity( + private suspend fun finishActivity( selectedAccount: LinkedAccountEntity? = null, isBackPressed: Boolean = false, ) { - dataStoreHelper.save( - key = DS_KEY_NAVI_PAY_CUSTOMER_STATUS, - value = naviPayCustomerStatusHandler.getCustomerStatus().name, - ) updateBottomSheetUIState(showBottomSheet = false) _effect.emit( AccountAdditionScreenContract.Effect.FinishActivity( @@ -486,7 +481,8 @@ constructor( _bindingProgress.update { 1f } _enableAddAccountCtaLoaderState.update { false } naviPayCustomerStatusHandler.updateCustomerStatusAndHandleNaviPayIntentActivityState( - customerStatus = NaviPayCustomerStatus.LINKED_VPA.name + pspType = onboardingPsp, + customerStatus = NaviPayCustomerStatus.LINKED_VPA, ) refreshLinkedAccountsUseCase.execute(screenName = screenName) delay(1.seconds) @@ -542,7 +538,7 @@ constructor( ) } delay(500) - updateCustomerStatusInDataStoreAndFinishActivity(selectedAccount = selectedAccount) + finishActivity(selectedAccount = selectedAccount) } } @@ -564,7 +560,7 @@ constructor( } private suspend fun onUpiGuidelinesContinueClicked(bankEntity: LinkedAccountEntity) { - updateCustomerStatusInDataStoreAndFinishActivity(selectedAccount = bankEntity) + finishActivity(selectedAccount = bankEntity) } private fun initBindingProgress() { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountDetailViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountDetailViewModel.kt index 3ec4fd6391..87b8c9a3fc 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountDetailViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountDetailViewModel.kt @@ -31,8 +31,6 @@ import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.SimInfo import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.settingscreen.model.QrDetails -import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.CheckAccountBalanceUseCase import com.navi.pay.common.usecase.CheckUpiNumberAvailabilityUseCase import com.navi.pay.common.usecase.DisableUpiLiteUseCase @@ -40,6 +38,7 @@ import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.LiteAccountSyncUseCase import com.navi.pay.common.usecase.RefreshLinkedAccountsUseCase import com.navi.pay.common.usecase.RefreshUpiNumbersUseCase +import com.navi.pay.common.usecase.UpdateCustomerStatusOnAccountRemovalUseCase import com.navi.pay.common.usecase.UpiLiteBalanceUseCase import com.navi.pay.common.usecase.UpiRequestIdUseCase import com.navi.pay.common.utils.DeviceInfoProvider @@ -91,7 +90,6 @@ import com.navi.pay.onboarding.account.detail.utils.getGradientColorsForBankCode import com.navi.pay.utils.ACTION_PIN_RESET import com.navi.pay.utils.ACTION_PIN_SET import com.navi.pay.utils.BANK_ACCOUNT_UNIQUE_ID -import com.navi.pay.utils.DS_KEY_NAVI_PAY_CUSTOMER_STATUS import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_1 import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_2 import com.navi.pay.utils.KEY_UPI_LITE_ACTIVE_ACCOUNT_INFO @@ -115,7 +113,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn @@ -148,13 +145,14 @@ constructor( private val naviCacheRepository: NaviCacheRepository, private val upiRequestIdUseCase: UpiRequestIdUseCase, private val mandateRepository: MandateRepository, - private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, private val vpaQRCodeManager: VpaQRCodeManager, private val upiNumberRepository: UpiNumberRepository, private val checkUpiNumberAvailabilityUseCase: CheckUpiNumberAvailabilityUseCase, private val refreshUpiNumbersUseCase: RefreshUpiNumbersUseCase, private val checkAccountBalanceUseCase: CheckAccountBalanceUseCase, private val naviPayPspManager: NaviPayPspManager, + private val updateCustomerStatusOnAccountRemovalUseCase: + UpdateCustomerStatusOnAccountRemovalUseCase, naviPayActivityDataProvider: NaviPayActivityDataProvider, savedStateHandle: SavedStateHandle, upiNumbersHelper: UpiNumbersHelper, @@ -520,7 +518,7 @@ constructor( naviPayFlowType = NaviPayFlowType.DEFAULT, linkedAccountEntity = linkedAccountEntity!!, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp.isNull()) { + if (pspEvaluationResult.onboardingDataEntity.isNull()) { return@evaluateAndOnboardPsp } updateLastClickedCardState( @@ -642,16 +640,8 @@ constructor( updateShowLoaderState(showLoader = false) emitTriggerDismissBottomSheet() updateUIState(uiState = LinkedAccountDetailScreenUIState.RemoveAccountSuccess) - if (linkedAccountsUseCase.execute(screenName = screenName).first().isEmpty()) { - naviPayCustomerStatusHandler - .updateCustomerStatusAndHandleNaviPayIntentActivityState( - NaviPayCustomerStatus.DEVICE_BOUNDED.name - ) - dataStoreHelper.save( - key = DS_KEY_NAVI_PAY_CUSTOMER_STATUS, - value = NaviPayCustomerStatus.DEVICE_BOUNDED.name, - ) - } + + updateCustomerStatusOnAccountRemovalUseCase.execute(screenName = screenName) } } @@ -720,10 +710,12 @@ constructor( ), screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@evaluateAndOnboardPspForVpa + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForVpa updateDeleteMandateLoaderState(isLoaderVisible = true) - val upiRequestId = upiRequestIdUseCase.execute(pspType = pspEvaluationResult.psp) + val upiRequestId = upiRequestIdUseCase.execute(pspType = pspType) val revokeCredData = credDataProvider.mandateCred( accountEntity = linkedAccountEntity.value!!, @@ -732,7 +724,7 @@ constructor( amount = upiLiteMandateInfo.value?.amount.orEmpty(), payeeVpa = upiLiteMandateInfo.value?.payeeVpa.orEmpty(), upiRequestId = upiRequestId, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) val npciResult = npciRepository.fetchCredentials( @@ -836,9 +828,9 @@ constructor( naviPayFlowType = NaviPayFlowType.PIN_MANAGEMENT, linkedAccountEntity = linkedAccountEntity!!, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp.isNull()) { - return@evaluateAndOnboardPsp - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPsp updateLastClickedCardState( lastClickedCardState = LinkedAccountDetailScreenButtonState.ChangePin @@ -867,7 +859,7 @@ constructor( npciResult = npciResult, upiRequestId = upiRequestId, linkedAccountEntity = linkedAccountEntity!!, - pspType = pspEvaluationResult.psp!!, + pspType = pspType, ) }, ) @@ -947,9 +939,10 @@ constructor( vpaEntityList = linkedAccountEntity!!.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow + updateLastClickedCardState( lastClickedCardState = LinkedAccountDetailScreenButtonState.CheckBalance ) @@ -965,7 +958,7 @@ constructor( checkAccountBalanceUseCase.generateCheckAccountBalanceCred( linkedAccountEntity = linkedAccountEntity!!, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultError = { isUserAborted -> updateShowLoaderState(showLoader = false) if (!isUserAborted) { @@ -977,7 +970,7 @@ constructor( credBlock = credBlock, upiRequestId = upiRequestId, selectedBankAccount = linkedAccountEntity!!, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) }, onUpiRequestIdFailure = { @@ -1035,15 +1028,15 @@ constructor( naviPayFlowType = NaviPayFlowType.PIN_MANAGEMENT, linkedAccountEntity = linkedAccountEntity!!, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPsp - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPsp updateNavigateToNextScreen( nextScreen = LinkedAccountVerifyScreenDestination( bankAccountUniqueId = bankAccountUniqueId, actionName = ACTION_PIN_SET, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) ) }, @@ -1066,9 +1059,9 @@ constructor( naviPayFlowType = NaviPayFlowType.PIN_MANAGEMENT, linkedAccountEntity = linkedAccountEntity!!, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPsp - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPsp updateLastClickedCardState( lastClickedCardState = LinkedAccountDetailScreenButtonState.ForgotPin ) @@ -1077,7 +1070,7 @@ constructor( LinkedAccountVerifyScreenDestination( bankAccountUniqueId = bankAccountUniqueId, actionName = ACTION_PIN_RESET, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) ) }, @@ -1263,7 +1256,7 @@ constructor( } }, ) - if (pspEvaluationResult?.psp == null) return@launch + if (pspEvaluationResult?.onboardingDataEntity == null) return@launch } if (!checkIsInternetAvailableOrShowError()) return@launch if (checkIsAirplaneModeOnOrShowError()) return@launch diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountVerifyViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountVerifyViewModel.kt index 4e5a590ab6..c2ba91f4a1 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountVerifyViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/detail/viewmodel/LinkedAccountVerifyViewModel.kt @@ -380,8 +380,9 @@ constructor( vpaEntityList = linkedAccountEntity.value?.vpaEntityList ?: emptyList(), screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - pspEvaluationResult.psp?.let { onboardedPsp -> pspTyp = onboardedPsp } - ?: run { triggerNavigateBack() } + pspEvaluationResult.onboardingDataEntity?.let { onboardedPsp -> + pspTyp = pspEvaluationResult.onboardingDataEntity.pspType + } ?: run { triggerNavigateBack() } }, ) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/LinkedAccountsScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/LinkedAccountsScreen.kt index 82e2151d24..2e379019b9 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/LinkedAccountsScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/LinkedAccountsScreen.kt @@ -334,14 +334,29 @@ fun RenderLinkedAccountsScreen( lastClickedCardId: String, naviPayAnalytics: NaviPayAnalytics.NaviPayConnectedAccounts, ) { + val scope = rememberCoroutineScope() + + val fireOnNoLinkedAccountsScreenAddAccountButtonClickedEvent = { + scope.launch { + naviPayAnalytics.onNoLinkedAccountsScreenAddAccountButtonClicked( + linkedAccountsScreenSource = linkedAccountsScreenSource, + naviPayCustomerStatusMap = + linkedAccountsViewModel.naviPayCustomerStatusHandler.getCustomerStatusMap(), + ) + } + Unit + } + if (filteredLinkedAccounts.isEmpty()) { - naviPayAnalytics.onNoLinkedAccountsScreenLanded( - linkedAccountsScreenSource = linkedAccountsScreenSource, - linkedAccounts = linkedAccounts, - filteredLinkedAccounts = filteredLinkedAccounts, - naviPayCustomerStatus = - linkedAccountsViewModel.naviPayCustomerStatusHandler.getCustomerStatusOnMainThread(), - ) + LaunchedEffect(Unit) { + naviPayAnalytics.onNoLinkedAccountsScreenLanded( + linkedAccountsScreenSource = linkedAccountsScreenSource, + linkedAccounts = linkedAccounts, + filteredLinkedAccounts = filteredLinkedAccounts, + naviPayCustomerStatusMap = + linkedAccountsViewModel.naviPayCustomerStatusHandler.getCustomerStatusMap(), + ) + } NoLinkedAccountScreen( onBackClick = onBackClick, actionIconText = linkedAccountsViewModel.helpCta?.title, @@ -350,9 +365,8 @@ fun RenderLinkedAccountsScreen( handleSdkAction = linkedAccountsViewModel::handleSdkAction, setUserOnboardedFromNoAccountsLinkedScreen = linkedAccountsViewModel::setUserOnboardedFromNoAccountsLinkedScreen, - naviPayAnalytics = naviPayAnalytics, - naviPayCustomerStatus = - linkedAccountsViewModel.naviPayCustomerStatusHandler.getCustomerStatusOnMainThread(), + fireOnNoLinkedAccountsScreenAddAccountButtonClickedEvent = + fireOnNoLinkedAccountsScreenAddAccountButtonClickedEvent, ) } else { val scrollState = rememberScrollState() @@ -447,13 +461,15 @@ fun RenderLinkedAccountsScreen( text = stringResource(id = linkedAccountsScreenSource.buttonTextResId), onClick = { - naviPayAnalytics.onAddAccountClicked( - linkedAccountsScreenSource = linkedAccountsScreenSource, - naviPayCustomerStatus = - linkedAccountsViewModel.naviPayCustomerStatusHandler - .getCustomerStatusOnMainThread(), - ) - linkedAccountsViewModel.handleSdkAction() + scope.launch { + linkedAccountsViewModel.handleSdkAction() + naviPayAnalytics.onAddAccountClicked( + linkedAccountsScreenSource = linkedAccountsScreenSource, + naviPayCustomerStatusMap = + linkedAccountsViewModel.naviPayCustomerStatusHandler + .getCustomerStatusMap(), + ) + } }, modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), ) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/NoLinkedAccountScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/NoLinkedAccountScreen.kt index a0f6e9f30c..ced801b42f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/NoLinkedAccountScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/ui/NoLinkedAccountScreen.kt @@ -29,8 +29,6 @@ import com.navi.design.font.FontWeightEnum import com.navi.design.font.getFontWeight import com.navi.design.font.naviFontFamily import com.navi.naviwidgets.extensions.NaviText -import com.navi.pay.analytics.NaviPayAnalytics -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.theme.color.NaviPayColor import com.navi.pay.common.ui.NaviPayHeader import com.navi.pay.common.ui.ThemeRoundedButton @@ -44,8 +42,7 @@ fun NoLinkedAccountScreen( linkedAccountsScreenSource: LinkedAccountsScreenSource, handleSdkAction: () -> Unit, setUserOnboardedFromNoAccountsLinkedScreen: (Boolean) -> Unit, - naviPayAnalytics: NaviPayAnalytics.NaviPayConnectedAccounts, - naviPayCustomerStatus: NaviPayCustomerStatus, + fireOnNoLinkedAccountsScreenAddAccountButtonClickedEvent: () -> Unit, ) { val noLinkedAccountsScreenDetails = remember { NoLinkedAccountsSourceToDetailsMapper(linkedAccountsScreenSource) @@ -102,10 +99,7 @@ fun NoLinkedAccountScreen( modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), onClick = { handleSdkAction() - naviPayAnalytics.onNoLinkedAccountsScreenAddAccountButtonClicked( - linkedAccountsScreenSource = linkedAccountsScreenSource, - naviPayCustomerStatus = naviPayCustomerStatus, - ) + fireOnNoLinkedAccountsScreenAddAccountButtonClickedEvent() if (linkedAccountsScreenSource == LinkedAccountsScreenSource.CheckBalance) { setUserOnboardedFromNoAccountsLinkedScreen(true) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/viewmodel/LinkedAccountsViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/viewmodel/LinkedAccountsViewModel.kt index 458bc440e7..7fcecfa1c5 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/viewmodel/LinkedAccountsViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/account/linked/viewmodel/LinkedAccountsViewModel.kt @@ -24,7 +24,6 @@ import com.navi.pay.common.model.view.NaviPayOnboardingRequest import com.navi.pay.common.model.view.NaviPaySessionHelper import com.navi.pay.common.model.view.PspType import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.usecase.AccountListCheckBalanceUseCase import com.navi.pay.common.usecase.CheckAccountBalanceUseCase import com.navi.pay.common.usecase.LinkedAccountsUseCase @@ -32,6 +31,7 @@ import com.navi.pay.common.usecase.RefreshUpiNumbersUseCase import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.NaviPayCommonUtils import com.navi.pay.common.utils.NaviPayOnboardingNavigator +import com.navi.pay.common.utils.fetchUserPhoneNumber import com.navi.pay.common.utils.getLinkedAccountScreenSourceFromBundleConverter import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.common.viewmodel.NaviPayBaseVM @@ -44,6 +44,7 @@ import com.navi.pay.management.upinumber.list.model.network.CheckUpiNumberAvaila import com.navi.pay.management.upinumber.list.model.network.CreateNewUpiNumberRequest import com.navi.pay.management.upinumber.list.repository.UpiNumberRepository import com.navi.pay.onboarding.account.add.model.view.AccountType +import com.navi.pay.onboarding.account.common.model.view.VpaStatus import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity import com.navi.pay.onboarding.account.linked.model.view.LinkedAccountsBottomSheetStateHolder import com.navi.pay.onboarding.account.linked.model.view.LinkedAccountsScreenBottomSheetUIState @@ -62,7 +63,6 @@ import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_1 import com.navi.pay.utils.ERROR_UPI_NUMBER_MAPPING_ALREADY_EXIST_2 import com.navi.pay.utils.NAVI_PAY_CRED_BLOCK_KEY import com.navi.pay.utils.NAVI_PAY_PURPLE_CTA_LOADER_LOTTIE -import com.navi.pay.utils.PHONE_NUMBER_LENGTH import com.navi.pay.utils.SAVINGS_ONLY_ENABLED_ACCOUNTS import com.navi.pay.utils.UPI_NUMBER_LINK import com.navi.pay.utils.UPI_NUMBER_STATUS_ACTIVE @@ -159,9 +159,7 @@ constructor( private var userOnboardedFromEmptyScreen = false init { - viewModelScope.launch(Dispatchers.IO) { - upiNumber = deviceInfoProvider.getPhoneNumber().takeLast(PHONE_NUMBER_LENGTH) - } + viewModelScope.launch(Dispatchers.IO) { upiNumber = fetchUserPhoneNumber() } if (linkedAccountsScreenSource == LinkedAccountsScreenSource.SelfTransfer) { updateNaviPaySessionId() } @@ -230,16 +228,6 @@ constructor( } } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA - } - - private fun isCustomerStatusDeviceBoundedOrLinkedVpa(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() in - listOf(NaviPayCustomerStatus.DEVICE_BOUNDED, NaviPayCustomerStatus.LINKED_VPA) - } - fun setUserOnboardedFromNoAccountsLinkedScreen(isUserOnboardedFromEmptyScreen: Boolean) { userOnboardedFromEmptyScreen = isUserOnboardedFromEmptyScreen } @@ -252,9 +240,10 @@ constructor( vpaEntityList = linkedAccount.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow + naviPayAnalytics.onCheckBalanceClicked(linkedAccount = linkedAccount) if (!naviPayNetworkConnectivity.isInternetConnected()) { notifyError(getNoInternetErrorConfig()) @@ -287,7 +276,7 @@ constructor( accountListCheckBalanceUseCase.onCheckBalanceClicked( linkedAccount = linkedAccount, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultReceived = { if (pspEvaluationResult.isOnboardingTriggered) { updateBottomSheetUIState(showBottomSheet = false) @@ -411,13 +400,23 @@ constructor( } } - private fun shouldAutoTriggerCheckBalance(linkedAccounts: List) = + private suspend fun shouldAutoTriggerCheckBalance(linkedAccounts: List) = linkedAccountsScreenSource is LinkedAccountsScreenSource.CheckBalance && linkedAccounts.size == 1 && linkedAccounts.first().isMPinSet && - isCustomerStatusDeviceBoundedOrLinkedVpa() + isAccountVPAsActiveAndDeviceBound(linkedAccounts.first()) - private fun checkAndOpenBankSelectionBottomSheet() { + private suspend fun isAccountVPAsActiveAndDeviceBound( + linkedAccountEntity: LinkedAccountEntity + ): Boolean { + val pspList = + linkedAccountEntity.vpaEntityList + .filter { it.status == VpaStatus.ACTIVE } + .mapNotNull { PspType.fromVpa(it.vpa) } + return pspList.any { naviPayCustomerStatusHandler.isUserOnboarded(pspType = it) } + } + + private suspend fun checkAndOpenBankSelectionBottomSheet() { val isSourceOfTypeAccounts = linkedAccountsScreenSource in listOf( @@ -431,7 +430,7 @@ constructor( } if ( - isCustomerStatusDeviceBoundedOrLinkedVpa() && + naviPayCustomerStatusHandler.isUserDeviceBoundForAnyPsp() && filteredLinkedAccounts.value.isEmpty() && isBankSelectionBottomSheetAutoTriggered ) { @@ -483,7 +482,7 @@ constructor( } private fun updateNaviPaySessionId() { - naviPaySessionHelper.createNewSessionId() + viewModelScope.launch(Dispatchers.IO) { naviPaySessionHelper.createNewSessionId() } } fun updateBottomSheetUIState( @@ -515,9 +514,10 @@ constructor( vpaEntityList = linkedAccountEntity.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow + if (!naviPayNetworkConnectivity.isInternetConnected()) { notifyError(getNoInternetErrorConfig()) return@evaluateAndOnboardPspForFlow @@ -551,7 +551,7 @@ constructor( checkAccountBalanceUseCase.generateCheckAccountBalanceCred( linkedAccountEntity = linkedAccountEntity, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultError = { isUserAborted -> updateShowButtonLoaderState(showButtonLoader = false) updateAccountId(accountId = "") @@ -570,7 +570,7 @@ constructor( upiRequestId = upiRequestId, selectedBankAccount = linkedAccountEntity, isCheckBalanceAutoTriggered = isCheckBalanceAutoTriggered, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) }, ) @@ -587,16 +587,18 @@ constructor( vpaEntityList = linkedAccountEntity.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp != null) { - emitNavigationEventAndResetCheckBalanceStates( - direction = - LinkedAccountVerifyScreenDestination( - bankAccountUniqueId = linkedAccountEntity.accountId, - actionName = ACTION_PIN_SET, - pspType = pspEvaluationResult.psp, - ) - ) - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow + + emitNavigationEventAndResetCheckBalanceStates( + direction = + LinkedAccountVerifyScreenDestination( + bankAccountUniqueId = linkedAccountEntity.accountId, + actionName = ACTION_PIN_SET, + pspType = pspType, + ) + ) }, ) } @@ -803,7 +805,8 @@ constructor( screenName = screenName, enabledAccountTypes = enabledAccountTypes, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) return@handleAccountAdditionFlow + if (pspEvaluationResult.onboardingDataEntity == null) + return@handleAccountAdditionFlow if (linkedAccountsScreenSource is LinkedAccountsScreenSource.CheckBalance) { initiateCheckBalanceAfterAccountAddition() } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/CustomerStatusConverter.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/CustomerStatusConverter.kt new file mode 100644 index 0000000000..1a73386d68 --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/CustomerStatusConverter.kt @@ -0,0 +1,24 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.onboarding.binding.db.converter + +import androidx.room.TypeConverter +import com.navi.pay.common.setup.model.NaviPayCustomerStatus + +class CustomerStatusConverter { + + @TypeConverter + fun from(customerStatus: NaviPayCustomerStatus): String { + return customerStatus.name + } + + @TypeConverter + fun to(customerStatus: String): NaviPayCustomerStatus { + return NaviPayCustomerStatus.fromString(value = customerStatus) + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/PspTypeConverter.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/PspTypeConverter.kt new file mode 100644 index 0000000000..befef8fd6c --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/converter/PspTypeConverter.kt @@ -0,0 +1,24 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.onboarding.binding.db.converter + +import androidx.room.TypeConverter +import com.navi.pay.common.model.view.PspType + +class PspTypeConverter { + + @TypeConverter + fun from(pspType: PspType): String { + return pspType.name + } + + @TypeConverter + fun to(pspType: String): PspType { + return PspType.fromName(psp = pspType) ?: PspType.JUSPAY + } +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/dao/NaviPayCustomerOnboardingDao.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/dao/NaviPayCustomerOnboardingDao.kt new file mode 100644 index 0000000000..4842a8d0c3 --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/db/dao/NaviPayCustomerOnboardingDao.kt @@ -0,0 +1,35 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.onboarding.binding.db.dao + +import androidx.room.Dao +import androidx.room.Query +import androidx.room.RawQuery +import androidx.room.Upsert +import androidx.sqlite.db.SupportSQLiteQuery +import com.navi.pay.common.model.view.PspType +import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity +import com.navi.pay.utils.NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME + +@Dao +interface NaviPayCustomerOnboardingDao { + @Upsert suspend fun upsert(naviPayCustomerOnboardingDataEntity: NaviPayCustomerOnboardingEntity) + + @Query("DELETE FROM $NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME") + suspend fun deleteAll() + + @Query( + "SELECT * FROM $NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME WHERE pspType = :pspType" + ) + suspend fun findByPspType(pspType: PspType): NaviPayCustomerOnboardingEntity? + + @Query("SELECT * FROM $NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME") + suspend fun getAllCustomerOnboardingData(): List + + @RawQuery suspend fun deleteRows(query: SupportSQLiteQuery): Int +} diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/model/view/OnboardingDataEntity.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/model/view/OnboardingDataEntity.kt new file mode 100644 index 0000000000..b5c1846432 --- /dev/null +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/model/view/OnboardingDataEntity.kt @@ -0,0 +1,31 @@ +/* + * + * * Copyright © 2024-2025 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.pay.onboarding.binding.model.view + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey +import androidx.room.TypeConverters +import com.navi.pay.common.model.view.PspType +import com.navi.pay.common.setup.model.NaviPayCustomerStatus +import com.navi.pay.onboarding.binding.db.converter.CustomerStatusConverter +import com.navi.pay.onboarding.binding.db.converter.PspTypeConverter +import com.navi.pay.utils.NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME + +@Entity(tableName = NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME) +data class NaviPayCustomerOnboardingEntity( + @PrimaryKey + @ColumnInfo(name = "pspType") + @TypeConverters(PspTypeConverter::class) + val pspType: PspType, + @ColumnInfo(name = "merchantCustomerId") val merchantCustomerId: String, + @ColumnInfo(name = "customerStatus") + @TypeConverters(CustomerStatusConverter::class) + val customerStatus: NaviPayCustomerStatus, + @ColumnInfo(name = "deviceFingerPrint") val deviceFingerPrint: String, +) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/repository/NaviPayOnboardingRepository.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/repository/NaviPayOnboardingRepository.kt index aa5ef73480..6593883d3f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/repository/NaviPayOnboardingRepository.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/repository/NaviPayOnboardingRepository.kt @@ -10,14 +10,18 @@ package com.navi.pay.onboarding.binding.repository import com.navi.common.checkmate.model.MetricInfo import com.navi.common.network.models.RepoResult import com.navi.common.network.retrofit.ResponseCallback +import com.navi.pay.common.model.view.PspType +import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.network.retrofit.NaviPayExternalRetrofitService import com.navi.pay.network.retrofit.NaviPayRetrofitService +import com.navi.pay.onboarding.binding.db.dao.NaviPayCustomerOnboardingDao import com.navi.pay.onboarding.binding.model.network.BindDeviceRequest import com.navi.pay.onboarding.binding.model.network.BindDeviceResponse import com.navi.pay.onboarding.binding.model.network.BindDeviceStatusRequest import com.navi.pay.onboarding.binding.model.network.BindDeviceStatusResponse import com.navi.pay.onboarding.binding.model.network.DeclineDeviceRequest import com.navi.pay.onboarding.binding.model.network.DeclineDeviceResponse +import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity import javax.inject.Inject import retrofit2.Response @@ -26,6 +30,7 @@ class NaviPayOnboardingRepository constructor( private val naviPayRetrofitService: NaviPayRetrofitService, private val naviPayExternalRetrofitService: NaviPayExternalRetrofitService, + private val naviPayCustomerOnboardingDao: NaviPayCustomerOnboardingDao, ) : ResponseCallback() { suspend fun bindDevice( @@ -67,4 +72,60 @@ constructor( suspend fun initiateSmv(url: String, params: Map): Response { return naviPayExternalRetrofitService.initiateSmv(url = url, params = params) } + + suspend fun getCustomerOnboardingEntity(pspType: PspType) = + naviPayCustomerOnboardingDao.findByPspType(pspType) + + suspend fun getAllCustomerOnboardingData() = + naviPayCustomerOnboardingDao.getAllCustomerOnboardingData() + + suspend fun upsertCustomerOnboardingDataEntity( + naviPayCustomerOnboardingDataEntity: NaviPayCustomerOnboardingEntity + ) = + naviPayCustomerOnboardingDao.upsert( + naviPayCustomerOnboardingDataEntity = naviPayCustomerOnboardingDataEntity + ) + + suspend fun upsertCustomerOnboardingDataEntity( + pspType: PspType, + customerStatus: NaviPayCustomerStatus? = null, + merchantCustomerId: String? = null, + deviceFingerPrint: String? = null, + ) { + if (customerStatus == null && merchantCustomerId == null && deviceFingerPrint == null) { + return + } + + val existingCustomerOnboardingDataEntity = + naviPayCustomerOnboardingDao.findByPspType(pspType) + + if (existingCustomerOnboardingDataEntity == null) { + upsertCustomerOnboardingDataEntity( + naviPayCustomerOnboardingDataEntity = + NaviPayCustomerOnboardingEntity( + pspType = pspType, + merchantCustomerId = merchantCustomerId.orEmpty(), + customerStatus = customerStatus ?: NaviPayCustomerStatus.NOT_SET, + deviceFingerPrint = deviceFingerPrint.orEmpty(), + ) + ) + } else { + upsertCustomerOnboardingDataEntity( + naviPayCustomerOnboardingDataEntity = + NaviPayCustomerOnboardingEntity( + pspType = pspType, + merchantCustomerId = + merchantCustomerId + ?: existingCustomerOnboardingDataEntity.merchantCustomerId, + customerStatus = + customerStatus ?: existingCustomerOnboardingDataEntity.customerStatus, + deviceFingerPrint = + deviceFingerPrint + ?: existingCustomerOnboardingDataEntity.deviceFingerPrint, + ) + ) + } + } + + suspend fun deleteAll() = naviPayCustomerOnboardingDao.deleteAll() } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayBlankScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayBlankScreen.kt index 6e6ceb55dd..fba0822049 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayBlankScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayBlankScreen.kt @@ -14,8 +14,10 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.navi.base.deeplink.DeepLinkManager import com.navi.base.deeplink.util.DeeplinkConstants import com.navi.base.model.CtaData @@ -51,8 +53,11 @@ fun NaviPayBlankScreen( onScreenClose() } - LaunchedEffect(Unit) { - if (naviPayOnboardingViewModel.isUserOnboarded) { + val isUserOnboarded by + naviPayOnboardingViewModel.isUserOnboardedForAnyPsp.collectAsStateWithLifecycle() + + LaunchedEffect(isUserOnboarded) { + if (isUserOnboarded) { onScreenClose() } else { var enabledAccountTypes = naviPayActivity.intent.getStringExtra(ENABLED_ACCOUNT_TYPES) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayOnboardingScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayOnboardingScreen.kt index e64edf5bf9..847b7b278c 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayOnboardingScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/ui/NaviPayOnboardingScreen.kt @@ -151,18 +151,13 @@ fun NaviPayOnboardingScreen( LaunchedEffect(Unit) { naviPayOnboardingViewModel.finishActivity.collectLatest { - if (it) { - naviPayOnboardingActivity.finish() - } + naviPayOnboardingActivity.finish() } } val onDismissRequest = { naviPayOnboardingViewModel.updateBottomSheetUIState(showBottomSheet = false) naviPayOnboardingActivity.finish() - naviPayOnboardingViewModel.updateCustomerStatusInDataStoreAndFinishActivity( - shouldFinishActivity = false - ) } LaunchedEffect(Unit) { @@ -176,7 +171,8 @@ fun NaviPayOnboardingScreen( EnabledAccountAdditionTypes( accountTypes = enabledAccountTypes, preferredBankCode = preferredBankCode, - ) + ), + onboardingPsp = naviPayOnboardingViewModel.onboardingPsp, ) ) } @@ -349,7 +345,7 @@ fun NaviPayOnboardingScreen( context = naviPayOnboardingActivity.applicationContext ), ) - naviPayOnboardingViewModel.updateCustomerStatusInDataStoreAndFinishActivity() + naviPayOnboardingActivity.finish() } is NavResult.Value -> { if (result.value.isGranted) { @@ -404,7 +400,7 @@ fun NaviPayOnboardingScreen( context = naviPayOnboardingActivity.applicationContext ), ) - naviPayOnboardingViewModel.updateCustomerStatusInDataStoreAndFinishActivity() + naviPayOnboardingActivity.finish() } } } @@ -428,7 +424,7 @@ fun NaviPayOnboardingScreen( naviPayOnboardingViewModel.onboardingAction.collect { when (it) { is NaviPayOnBoardingActions.FinishScreen -> { - naviPayOnboardingViewModel.updateCustomerStatusInDataStoreAndFinishActivity() + naviPayOnboardingActivity.finish() } is NaviPayOnBoardingActions.E2EOnboarding -> { if ( @@ -476,15 +472,15 @@ fun NaviPayOnboardingScreen( LaunchedEffect(Unit) { naviPayOnboardingViewModel.customerStatusAfterOnboarding.collectLatest { customerStatus -> - naviPayOnboardingViewModel.setCustomerStatusInDataStore(customerStatus = customerStatus) + naviPayOnboardingViewModel.updateOnboardingEntityCustomerStatus( + customerStatus = customerStatus + ) + naviPayOnboardingActivity.setResult( UPI_RESULT_CODE, NaviPaySdkUtils.getDelayedOnboardingSuccessIntent(), ) naviPayOnboardingActivity.finish() - /* - TODO: send onboarding result to source, also check if this is correct - */ } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayBlankOnboardingViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayBlankOnboardingViewModel.kt index 0e5fce45cd..e79f122a61 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayBlankOnboardingViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayBlankOnboardingViewModel.kt @@ -7,19 +7,34 @@ package com.navi.pay.onboarding.binding.viewmodel +import androidx.lifecycle.viewModelScope import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_BLANK_ONBOARDING_SCREEN -import com.navi.pay.common.setup.NaviPayManager +import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.viewmodel.NaviPayBaseVM import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch @HiltViewModel class NaviPayBlankOnboardingViewModel @Inject -constructor(private val naviPayManager: NaviPayManager) : NaviPayBaseVM() { +constructor(private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler) : + NaviPayBaseVM() { - val isUserOnboarded - get() = naviPayManager.isUserOnboarded() + private val _isUserOnboardedForAnyPsp = MutableStateFlow(false) + val isUserOnboardedForAnyPsp = _isUserOnboardedForAnyPsp.asStateFlow() + + init { + viewModelScope.launch(Dispatchers.IO) { + _isUserOnboardedForAnyPsp.update { + naviPayCustomerStatusHandler.isUserOnboardedForAnyPsp() + } + } + } override val screenName: String get() = NAVI_PAY_BLANK_ONBOARDING_SCREEN diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayOnboardingViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayOnboardingViewModel.kt index 98688964c3..0d0d6f86db 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayOnboardingViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/binding/viewmodel/NaviPayOnboardingViewModel.kt @@ -17,10 +17,8 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.google.gson.reflect.TypeToken import com.navi.base.AppServiceManager -import com.navi.base.cache.datastore.DataStoreHelper import com.navi.base.cache.model.NaviCacheEntity import com.navi.base.cache.repository.NaviCacheRepository -import com.navi.base.utils.BaseUtils import com.navi.base.utils.ResourceProvider import com.navi.base.utils.orFalse import com.navi.base.utils.orTrue @@ -54,13 +52,13 @@ import com.navi.pay.common.model.view.PspType import com.navi.pay.common.model.view.SimInfo import com.navi.pay.common.model.view.isAnyEmpty import com.navi.pay.common.repository.CommonRepository -import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.NaviPayManager import com.navi.pay.common.setup.NaviPaySetupUseCase import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.setup.model.NaviPaySetupFailureReason import com.navi.pay.common.setup.model.NaviPaySetupStatus +import com.navi.pay.common.usecase.ClearOnboardingAndDeviceDataUseCase import com.navi.pay.common.usecase.LinkedAccountsUseCase import com.navi.pay.common.usecase.LiteAccountSyncUseCase import com.navi.pay.common.usecase.NaviPayConfigUseCase @@ -70,6 +68,7 @@ import com.navi.pay.common.usecase.SyncSavedBeneficiariesUseCase import com.navi.pay.common.usecase.SyncUpiLiteMandateInfoUseCase import com.navi.pay.common.utils.DeviceInfoProvider import com.navi.pay.common.utils.NaviPayCommonUtils +import com.navi.pay.common.utils.fetchUserPhoneNumber import com.navi.pay.common.utils.getMetricInfo import com.navi.pay.common.utils.getSetPinActionPayload import com.navi.pay.common.viewmodel.NaviPayBaseVM @@ -97,14 +96,11 @@ import com.navi.pay.permission.utils.PermissionKeys.NON_FIRST_TIME_SCREEN_PERMIS import com.navi.pay.permission.utils.PermissionStateProvider import com.navi.pay.permission.utils.PermissionUtils import com.navi.pay.tstore.list.usecase.SyncOrderHistoryUseCase -import com.navi.pay.utils.DS_KEY_NAVI_PAY_CUSTOMER_STATUS import com.navi.pay.utils.INDIA_COUNTRY_CODE_WITHOUT_PLUS import com.navi.pay.utils.LITMUS_EXPERIMENT_NAVIPAY_SMV_BINDING import com.navi.pay.utils.NAVI_PAY_API_STATUS_SUCCESS import com.navi.pay.utils.NAVI_PAY_DEVICE_BINDING_IS_SMV_TRIGGERED_AND_FAILED -import com.navi.pay.utils.NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS import com.navi.pay.utils.NAVI_PAY_GREEN_TICK_LOTTIE -import com.navi.pay.utils.NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS import com.navi.pay.utils.NAVI_PAY_PURPLE_CTA_LOADER_LOTTIE import com.navi.pay.utils.NON_VERIFIED_SENDER_LOGIN import com.navi.pay.utils.ONBOARDING_CONFIG @@ -143,10 +139,8 @@ constructor( private val commonRepository: CommonRepository, private val deviceInfoProvider: DeviceInfoProvider, private val naviPayOnboardingRepository: NaviPayOnboardingRepository, - private val sharedPreferenceRepository: SharedPreferenceRepository, private val refreshBankListUseCase: RefreshBankListUseCase, private val refreshLinkedAccountsUseCase: RefreshLinkedAccountsUseCase, - private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, private val naviPayConfigUseCase: NaviPayConfigUseCase, private val syncOrderHistoryUseCase: SyncOrderHistoryUseCase, private val naviPayManager: NaviPayManager, @@ -157,7 +151,6 @@ constructor( private val resourceProvider: ResourceProvider, private val coroutineDispatcherProvider: CoroutineDispatcherProvider, private val linkedAccountsUseCase: LinkedAccountsUseCase, - private val dataStoreHelper: DataStoreHelper, private val onboardingDataFromIntentProvider: OnboardingIntentDataProvider, private val permissionStateProvider: PermissionStateProvider, private val naviPaySessionHelper: NaviPaySessionHelper, @@ -166,6 +159,8 @@ constructor( private val syncUpiLiteMandateInfoUseCase: SyncUpiLiteMandateInfoUseCase, private val litmusExperimentsUseCase: LitmusExperimentsUseCase, private val naviCacheRepository: NaviCacheRepository, + private val clearOnboardingAndDeviceDataUseCase: ClearOnboardingAndDeviceDataUseCase, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, savedStateHandle: SavedStateHandle, ) : NaviPayBaseVM() { @@ -179,7 +174,7 @@ constructor( MutableStateFlow(NaviPayOnboardingActionsType.E2E_ONBOARDING) private val onboardingActionFromIntent = _onboardingActionFromIntent.asStateFlow() - val userPhoneNumber = BaseUtils.getPhoneNumber()?.takeLast(PHONE_NUMBER_LENGTH) ?: EMPTY + val userPhoneNumber = fetchUserPhoneNumber() private val _onboardingAction = MutableSharedFlow( @@ -242,7 +237,7 @@ constructor( private val _bindingProgress = MutableStateFlow(0f) val bindingProgress = _bindingProgress.asStateFlow() - private val _finishActivity = MutableSharedFlow(replay = 1) + private val _finishActivity = MutableSharedFlow(replay = 1) val finishActivity = _finishActivity.asSharedFlow() private val _isSmvEligibilityCheckOngoing = MutableStateFlow(false) @@ -257,6 +252,8 @@ constructor( private val _onboardingSource = MutableStateFlow(EMPTY) val onboardingSource = _onboardingSource.asStateFlow() + val onboardingPsp = onboardingDataFromIntent.value.pspType + var naviPayOnboardingConfig = NaviPayOnboardingConfig() private var isAwayFromMainScreen = false private val naviApiPoller by lazy { @@ -344,12 +341,21 @@ constructor( preferredBankCode = onboardingDataFromIntent.value.preferredBankCode ) } - naviPayAnalytics.onDevGenericEvent( - eventName = "NaviPay_Dev_OnboardingIntentData", - customerStatus = naviPayCustomerStatusHandler.getCustomerStatusOnMainThread().name, - extraParams = - mapOf("onboardingDataFromIntent" to onboardingDataFromIntent.value.toString()), - ) + + fireOnboardingIntentDataDevEvent() + } + + private fun fireOnboardingIntentDataDevEvent() { + viewModelScope.launch(coroutineDispatcherProvider.io) { + val customerOnboardingEntity = + naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = onboardingPsp) + naviPayAnalytics.onDevGenericEvent( + eventName = "NaviPay_Dev_OnboardingIntentData", + customerStatus = customerOnboardingEntity?.customerStatus?.name.orEmpty(), + extraParams = + mapOf("onboardingDataFromIntent" to onboardingDataFromIntent.value.toString()), + ) + } } private fun updateNaviPayOnboardingConfig() { @@ -376,10 +382,12 @@ constructor( private fun handleOnboardingActionsFromIntent() { viewModelScope.safeLaunch(coroutineDispatcherProvider.io) { + val customerOnboardingEntity = + naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = onboardingPsp) when (onboardingActionFromIntent.value) { NaviPayOnboardingActionsType.E2E_ONBOARDING -> { handleE2EOnboarding( - customerStatus = naviPayCustomerStatusHandler.getCustomerStatus().name + customerStatus = customerOnboardingEntity?.customerStatus?.name.orEmpty() ) } NaviPayOnboardingActionsType.DEVICE_BINDING -> { @@ -401,16 +409,8 @@ constructor( } } - fun updateCustomerStatusInDataStoreAndFinishActivity(shouldFinishActivity: Boolean = true) { - coroutineScope.safeLaunch(coroutineDispatcherProvider.io) { - dataStoreHelper.save( - key = DS_KEY_NAVI_PAY_CUSTOMER_STATUS, - value = naviPayCustomerStatusHandler.getCustomerStatus().name, - ) - if (shouldFinishActivity) { - _finishActivity.emit(true) - } - } + fun triggerFinishActivity() { + coroutineScope.safeLaunch(coroutineDispatcherProvider.io) { _finishActivity.emit(Unit) } } fun verifyNaviPaySetup() { @@ -420,7 +420,9 @@ constructor( return@safeLaunch } - val customerStatus = naviPayCustomerStatusHandler.getCustomerStatus() + val customerStatus = + naviPayCustomerStatusHandler.getCustomerStatus(pspType = onboardingPsp) + val isCustomerStatusSet = customerStatus != NaviPayCustomerStatus.NOT_SET val isLocalDeviceDataNotAvailable = !isLocalDeviceDataAvailable() @@ -438,7 +440,7 @@ constructor( */ if (isCustomerStatusSet || isLocalDeviceDataNotAvailable) { // Setup is done at app launch. - onSetupSuccess(customerStatus = customerStatus.name) + onSetupSuccess(customerStatus = customerStatus) return@safeLaunch } @@ -487,8 +489,11 @@ constructor( } } is NaviPaySetupStatus.Success -> { + val customerStatus = + naviPaySetupStatus.naviPaySetupSuccessDetailsMap[onboardingPsp] + ?.customerStatus ?: NaviPayCustomerStatus.NOT_SET showLoadingBottomSheet(isVisible = false) - onSetupSuccess(customerStatus = naviPaySetupStatus.customerStatus) + onSetupSuccess(customerStatus = customerStatus) } } } @@ -538,27 +543,29 @@ constructor( _selectedSimInfo.update { selectedSimInfo } } - private suspend fun onSetupSuccess(customerStatus: String) { + private suspend fun onSetupSuccess(customerStatus: NaviPayCustomerStatus) { naviPayAnalytics.verifySetupSuccess( - customerStatus = customerStatus, + customerStatus = customerStatus.name, onboardingSource = onboardingSource.value, naviPaySessionAttributes = getNaviPaySessionAttributes(), ) + naviPayCustomerStatusHandler.updateCustomerStatusAndHandleNaviPayIntentActivityState( - customerStatus = customerStatus + pspType = onboardingPsp, + customerStatus = customerStatus, ) when (customerStatus) { - NaviPayCustomerStatus.LINKED_VPA.name -> { + NaviPayCustomerStatus.LINKED_VPA -> { syncLiteAccountInfo() handleOnboardingActionsFromIntent() } - NaviPayCustomerStatus.DEVICE_BOUNDED.name -> { + NaviPayCustomerStatus.DEVICE_BOUNDED -> { updateEnabledAccountTypes(enabledAccountTypes = enabledAccountTypes.value) handleAction(action = NaviPayOnBoardingActions.AccountAddition) } else -> { - handleE2EOnboarding(customerStatus = customerStatus) + handleE2EOnboarding(customerStatus = customerStatus.name) } } } @@ -741,7 +748,7 @@ constructor( handleFlowSpecificOnboardingIntent() } is NaviPayOnBoardingActions.FinishScreen -> { - updateCustomerStatusInDataStoreAndFinishActivity() + triggerFinishActivity() } } } @@ -1165,9 +1172,14 @@ constructor( name = selectedSimInfo.value?.carrierName ?: EMPTY, ), ) + deviceInfoProvider.saveDeviceData(deviceData = deviceData!!) - deviceInfoProvider.saveMerchantCustomerId(merchantCustomerId = merchantCustomerId) + naviPayCustomerStatusHandler.upsertCustomerOnboardingDataEntity( + pspType = onboardingPsp, + deviceFingerPrint = deviceFingerPrint, + merchantCustomerId = merchantCustomerId, + ) handleDeviceBindingSuccess() } @@ -1278,7 +1290,8 @@ constructor( } naviPayCustomerStatusHandler.updateCustomerStatusAndHandleNaviPayIntentActivityState( - customerStatus = customerStatus + pspType = onboardingPsp, + customerStatus = NaviPayCustomerStatus.fromString(customerStatus), ) if (customerStatus == NaviPayCustomerStatus.LINKED_VPA.name) { @@ -1334,10 +1347,6 @@ constructor( handleAction(action = NaviPayOnBoardingActions.AccountAddition) } - suspend fun setCustomerStatusInDataStore(customerStatus: NaviPayCustomerStatus) { - dataStoreHelper.save(key = DS_KEY_NAVI_PAY_CUSTOMER_STATUS, value = customerStatus.name) - } - @OptIn(DelicateCoroutinesApi::class) private suspend fun showLinkedAccountState() { GlobalScope.launch(Dispatchers.IO) { @@ -1404,10 +1413,7 @@ constructor( } private suspend fun clearNaviPayData() { - sharedPreferenceRepository.clearKeyBasedSessionPreferenceData( - encryptedDataKeys = NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS, - nonEncryptedDataKeys = NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS, - ) + clearOnboardingAndDeviceDataUseCase.execute() } private fun updateDeviceBindingState( @@ -1505,7 +1511,8 @@ constructor( private fun handleFlowSpecificOnboardingIntent() { viewModelScope.safeLaunch(coroutineDispatcherProvider.io) { - val customerStatus = naviPayCustomerStatusHandler.getCustomerStatus() + val customerStatus = + naviPayCustomerStatusHandler.getCustomerStatus(pspType = onboardingPsp) when (customerStatus) { NaviPayCustomerStatus.DEVICE_BOUNDED -> { updateEnabledAccountTypes(enabledAccountTypes = listOf(AccountType.SAVINGS)) @@ -1767,6 +1774,15 @@ constructor( } } + fun updateOnboardingEntityCustomerStatus(customerStatus: NaviPayCustomerStatus) { + viewModelScope.launch(Dispatchers.IO) { + naviPayCustomerStatusHandler.upsertCustomerOnboardingDataEntity( + pspType = onboardingPsp, + customerStatus = customerStatus, + ) + } + } + override val screenName: String get() = NAVI_PAY_SETUP } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/ui/NaviPayFaqScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/ui/NaviPayFaqScreen.kt index 68850ad637..ac00c69dc9 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/ui/NaviPayFaqScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/ui/NaviPayFaqScreen.kt @@ -107,8 +107,12 @@ fun NaviPayFaqScreen( val observer = LifecycleEventObserver { _, event -> when (event) { Lifecycle.Event.ON_RESUME -> { - if (isChatBotOpened && naviPayFaqViewModel.isUserOnboarded().not()) { - naviPayActivity.finish() + scope.launch { + if ( + isChatBotOpened && naviPayFaqViewModel.isUserOnboardedForAnyPsp().not() + ) { + naviPayActivity.finish() + } } } else -> Unit diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/viewmodel/NaviPayFaqViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/viewmodel/NaviPayFaqViewModel.kt index 305ce2203d..392ad608b8 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/viewmodel/NaviPayFaqViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/faq/viewmodel/NaviPayFaqViewModel.kt @@ -11,7 +11,6 @@ import androidx.lifecycle.viewModelScope import com.navi.base.model.CtaData import com.navi.pay.analytics.NaviPayAnalytics.Companion.NAVI_PAY_FAQ import com.navi.pay.common.setup.NaviPayCustomerStatusHandler -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.utils.NaviPayCommonUtils.getHelpCtaData import com.navi.pay.common.viewmodel.NaviPayBaseVM import com.navi.pay.onboarding.faq.model.view.UpiVideoEntity @@ -65,9 +64,8 @@ constructor(private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandl _uiOptionsSelectedVideo.update { upiVideoEntity } } - fun isUserOnboarded(): Boolean { - return naviPayCustomerStatusHandler.getCustomerStatusOnMainThread() == - NaviPayCustomerStatus.LINKED_VPA + suspend fun isUserOnboardedForAnyPsp(): Boolean { + return naviPayCustomerStatusHandler.isUserOnboardedForAnyPsp() } fun updateBottomSheetVisibility(isBottomSheetVisible: Boolean) { diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/model/view/LauncherScreenToNextScreenNavigate.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/model/view/LauncherScreenToNextScreenNavigate.kt index 5a6c608432..d84014fc29 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/model/view/LauncherScreenToNextScreenNavigate.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/model/view/LauncherScreenToNextScreenNavigate.kt @@ -13,7 +13,7 @@ import com.navi.pay.management.mandate.model.view.MandateEntity import com.ramcosta.composedestinations.spec.Direction sealed class LauncherScreenToNextScreenNavigate { - data class OnLocalDataValidState(val customerStatus: String) : + data class OnLocalDataValidState(val isUserDeviceBoundOnAnyPsp: Boolean) : LauncherScreenToNextScreenNavigate() data class IntentMandate(val payeeEntity: PayeeEntity) : LauncherScreenToNextScreenNavigate() diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/ui/NaviPayLauncherScreen.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/ui/NaviPayLauncherScreen.kt index 7b306ec3f9..cafb977a7f 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/ui/NaviPayLauncherScreen.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/ui/NaviPayLauncherScreen.kt @@ -101,7 +101,7 @@ private fun handleNavigation( ?.getBundleExtra(NAVI_PAY_NOTIFICATION_DATA_BUNDLE) ?.getHashMap(), naviPayLocalUri = naviPayActivity.intent?.data, - customerStatus = navigateToNextScreen.customerStatus, + isUserDeviceBoundOnAnyPsp = navigateToNextScreen.isUserDeviceBoundOnAnyPsp, bundle = naviPayActivity.intent?.extras, ) } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/viewmodel/NaviPayLauncherViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/viewmodel/NaviPayLauncherViewModel.kt index 4efe8dd961..cf9d3d5aec 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/viewmodel/NaviPayLauncherViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/onboarding/launcher/viewmodel/NaviPayLauncherViewModel.kt @@ -20,13 +20,12 @@ import com.navi.pay.common.connectivity.NaviPayNetworkConnectivity import com.navi.pay.common.model.network.ValidateVpaRequest import com.navi.pay.common.model.view.NaviPaySessionHelper import com.navi.pay.common.repository.CommonRepository -import com.navi.pay.common.repository.SharedPreferenceRepository import com.navi.pay.common.setup.NaviPayCustomerStatusHandler import com.navi.pay.common.setup.NaviPayRouter.getDirectionFromCtaUrl import com.navi.pay.common.setup.NaviPaySetupUseCase -import com.navi.pay.common.setup.model.NaviPayCustomerStatus import com.navi.pay.common.setup.model.NaviPaySetupFailureReason import com.navi.pay.common.setup.model.NaviPaySetupStatus +import com.navi.pay.common.usecase.ClearOnboardingAndDeviceDataUseCase import com.navi.pay.common.usecase.RefreshLiteMandateAndAccountInfoUseCase import com.navi.pay.common.usecase.ValidateVpaUseCase import com.navi.pay.common.utils.DeviceInfoProvider @@ -47,12 +46,10 @@ import com.navi.pay.onboarding.launcher.model.view.LauncherScreenToNextScreenNav import com.navi.pay.utils.DEFAULT_INITIATION_MODE_INTENT_MANDATE_AND_TRANSACTION import com.navi.pay.utils.IS_FROM_IAN import com.navi.pay.utils.NAVI_PAY_DEFAULT_MCC -import com.navi.pay.utils.NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS import com.navi.pay.utils.NAVI_PAY_INTENT_COLLECT_HOST import com.navi.pay.utils.NAVI_PAY_INTENT_MANDATE_HOST import com.navi.pay.utils.NAVI_PAY_INTENT_PAY_HOST import com.navi.pay.utils.NAVI_PAY_LOCAL_URI_SCHEME -import com.navi.pay.utils.NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS import com.navi.pay.utils.NAVI_PAY_NOTIFICATION_APPROVE_OR_DECLINE_MANDATE import com.navi.pay.utils.NAVI_PAY_NOTIFICATION_COLLECT_REQUEST import com.navi.pay.utils.NAVI_PAY_NOTIFICATION_DATA_CTA_KEY @@ -77,15 +74,15 @@ class NaviPayLauncherViewModel @Inject constructor( private val commonRepository: CommonRepository, - private val sharedPreferenceRepository: SharedPreferenceRepository, private val deviceInfoProvider: DeviceInfoProvider, private val upiUriParser: UpiUriParser, private val naviPaySetupUseCase: NaviPaySetupUseCase, - private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, private val naviPayNetworkConnectivity: NaviPayNetworkConnectivity, private val naviPaySessionHelper: NaviPaySessionHelper, private val validateVpaUseCase: ValidateVpaUseCase, private val refreshLiteMandateAndAccountInfoUseCase: RefreshLiteMandateAndAccountInfoUseCase, + private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler, + private val clearOnboardingAndDeviceDataUseCase: ClearOnboardingAndDeviceDataUseCase, ) : NaviPayBaseVM() { private val _navigateToNextScreen = @@ -107,11 +104,13 @@ constructor( private fun initLauncher() { viewModelScope.launch(Dispatchers.IO) { logEvent(message = "initLauncherCalled") - val customerStatus = naviPayCustomerStatusHandler.getCustomerStatus() + + val isUserDeviceBoundForAnyPsp = + naviPayCustomerStatusHandler.isUserDeviceBoundForAnyPsp() updateNavigateToNextScreenValue( value = LauncherScreenToNextScreenNavigate.OnLocalDataValidState( - customerStatus = customerStatus.name + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundForAnyPsp ) ) } @@ -146,14 +145,26 @@ constructor( } } is NaviPaySetupStatus.Success -> { - naviPayCustomerStatusHandler - .updateCustomerStatusAndHandleNaviPayIntentActivityState( - naviPaySetupStatus.customerStatus - ) + val isUserDeviceBoundOnAnyPsp = + naviPaySetupStatus.naviPaySetupSuccessDetailsMap.any { + it.value.customerStatus.isBound + } + naviPaySetupStatus.naviPaySetupSuccessDetailsMap.forEach { + pspType, + naviPaySetupSuccessDetails -> + launch { + naviPayCustomerStatusHandler + .updateCustomerStatusAndHandleNaviPayIntentActivityState( + pspType = pspType, + customerStatus = naviPaySetupSuccessDetails.customerStatus, + ) + } + } + updateNavigateToNextScreenValue( value = LauncherScreenToNextScreenNavigate.OnLocalDataValidState( - customerStatus = naviPaySetupStatus.customerStatus + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp ) ) } @@ -166,47 +177,47 @@ constructor( uriFromSA: Uri?, notificationData: HashMap?, naviPayLocalUri: Uri?, - customerStatus: String, + isUserDeviceBoundOnAnyPsp: Boolean, bundle: Bundle?, ) { viewModelScope.launch(Dispatchers.IO) { if (uriFromSA != null) { checkUriTypeFromSuperAppAndNavigate( uri = uriFromSA, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, ) } else if (notificationData != null) { checkNotificationDataAndNavigate( notificationData = notificationData, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, bundle = bundle ?: Bundle(), ) } else if (naviPayLocalUri != null) { checkNaviPayLocalUriAndNavigate( naviPayUri = naviPayLocalUri, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, bundle = bundle ?: Bundle(), ) } else { - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } } } - private suspend fun clearNaviPayData() { - sharedPreferenceRepository.clearKeyBasedSessionPreferenceData( - encryptedDataKeys = NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS, - nonEncryptedDataKeys = NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS, - ) - } - - private suspend fun checkUriTypeFromSuperAppAndNavigate(uri: Uri, customerStatus: String) = + private suspend fun checkUriTypeFromSuperAppAndNavigate( + uri: Uri, + isUserDeviceBoundOnAnyPsp: Boolean, + ) = withContext(Dispatchers.IO) { logEvent(message = "checkUriTypeFromSuperAppAndNavigate. Uri is $uri") when (val upiUriResult = upiUriParser.parseForUpiUri(uri)) { is UpiUriResult.Error -> { logEvent(message = "UpiUriResult.Error. Navigating based on customer status") - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } is UpiUriResult.Success -> { when (uri.host) { @@ -237,7 +248,7 @@ constructor( "checkUriTypeFromSuperAppAndNavigate for mandate case. Exception: ${e.message}" ) navigateToNextScreenBasedOnCustomerStatus( - customerStatus = customerStatus + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp ) } } @@ -296,7 +307,7 @@ constructor( NAVI_PAY_INTENT_COLLECT_HOST -> {} else -> { navigateToNextScreenBasedOnCustomerStatus( - customerStatus = customerStatus + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp ) } } @@ -306,7 +317,7 @@ constructor( private suspend fun checkNotificationDataAndNavigate( notificationData: HashMap, - customerStatus: String, + isUserDeviceBoundOnAnyPsp: Boolean, bundle: Bundle?, ) = withContext(Dispatchers.IO) { @@ -326,7 +337,7 @@ constructor( } redirectBasedOnCtaDataOrCustomerStatus( ctaData = ctaData, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, bundle = bundle, ) return@withContext @@ -339,9 +350,11 @@ constructor( if (mandateReferenceId.isEmpty()) { logEvent( message = - "MandateReferenceId is empty. Navigating based on customer status. CustomerStatus: $customerStatus" + "MandateReferenceId is empty. Navigating based on customer status. isUserDeviceBound: $isUserDeviceBoundOnAnyPsp" + ) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp ) - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) } else { updateNaviPaySessionId() updateNavigateToNextScreenValue( @@ -357,7 +370,7 @@ constructor( NAVI_PAY_NOTIFICATION_COLLECT_REQUEST -> { processCollectRequestAndNavigate( notificationData = notificationData, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, isFromInAppNotification = isFromIan, ) return@withContext @@ -367,14 +380,14 @@ constructor( redirectBasedOnCtaDataOrCustomerStatus( ctaData = ctaData, - customerStatus = customerStatus, + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp, bundle = bundle, ) } private suspend fun redirectBasedOnCtaDataOrCustomerStatus( ctaData: String, - customerStatus: String, + isUserDeviceBoundOnAnyPsp: Boolean, bundle: Bundle?, ) { val nextScreenDestination = @@ -395,13 +408,15 @@ constructor( ) ) } else { - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } } private suspend fun processCollectRequestAndNavigate( notificationData: HashMap, - customerStatus: String, + isUserDeviceBoundOnAnyPsp: Boolean, isFromInAppNotification: Boolean, ) { try { @@ -438,7 +453,9 @@ constructor( ) if (!mandateDetailAPIResponse.isSuccessWithData()) { - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) return } @@ -457,17 +474,19 @@ constructor( ) } catch (exception: Exception) { logEvent(message = "processCollectRequestAndNavigate. Exception: ${exception.message}") - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } } - private fun updateNaviPaySessionId() { + private suspend fun updateNaviPaySessionId() { naviPaySessionHelper.createNewSessionId() } private suspend fun checkNaviPayLocalUriAndNavigate( naviPayUri: Uri, - customerStatus: String, + isUserDeviceBoundOnAnyPsp: Boolean, bundle: Bundle = Bundle(), ) = withContext(Dispatchers.IO) { @@ -476,7 +495,9 @@ constructor( message = "checkNaviPayLocalUriAndNavigate NaviPayScheme is not valid. Scheme is ${naviPayUri.scheme}" ) - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } else { val nextScreenDestination = naviPayUri.host?.let { @@ -501,7 +522,9 @@ constructor( logEvent( message = "checkNaviPayLocalUriAndNavigate. Next screen destination is null" ) - navigateToNextScreenBasedOnCustomerStatus(customerStatus = customerStatus) + navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp = isUserDeviceBoundOnAnyPsp + ) } } } @@ -604,14 +627,13 @@ constructor( } } - private suspend fun navigateToNextScreenBasedOnCustomerStatus(customerStatus: String) { - when (customerStatus) { - NaviPayCustomerStatus.LINKED_VPA.name, - NaviPayCustomerStatus.DEVICE_BOUNDED.name -> - _navigateToNextScreen.emit(LauncherScreenToNextScreenNavigate.None) - else -> { // de-registered, re-register, fresh - clearNaviPayData() - } + private suspend fun navigateToNextScreenBasedOnCustomerStatus( + isUserDeviceBoundOnAnyPsp: Boolean + ) { + if (isUserDeviceBoundOnAnyPsp) { + _navigateToNextScreen.emit(LauncherScreenToNextScreenNavigate.None) + } else { // de-registered, re-register, fresh + clearOnboardingAndDeviceDataUseCase.execute() } } diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/details/viewmodel/OrderDetailsViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/details/viewmodel/OrderDetailsViewModel.kt index d6c7fcfb3e..38d4f1a9d5 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/details/viewmodel/OrderDetailsViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/tstore/details/viewmodel/OrderDetailsViewModel.kt @@ -908,15 +908,17 @@ constructor( private fun fireRepeatTransactionCtaClickedEvent( naviPayTransactionDetailsMetadata: NaviPayTransactionDetailsMetadata? ) { - naviPaySessionHelper.createNewSessionId() - naviPayAnalytics.onRepeatTransactionClicked( - source = screenName, - transactionType = naviPayTransactionDetailsMetadata?.txnType.orEmpty(), - upiRequestId = naviPayTransactionDetailsMetadata?.upiReqId.orEmpty(), - accountAdded = isTransactionAccountActive, - status = orderEntity.value?.orderStatusOfView?.name.orEmpty(), - naviPaySessionAttributes = naviPaySessionHelper.getNaviPaySessionAttributes(), - ) + viewModelScope.launch(Dispatchers.IO) { + naviPaySessionHelper.createNewSessionId() + naviPayAnalytics.onRepeatTransactionClicked( + source = screenName, + transactionType = naviPayTransactionDetailsMetadata?.txnType.orEmpty(), + upiRequestId = naviPayTransactionDetailsMetadata?.upiReqId.orEmpty(), + accountAdded = isTransactionAccountActive, + status = orderEntity.value?.orderStatusOfView?.name.orEmpty(), + naviPaySessionAttributes = naviPaySessionHelper.getNaviPaySessionAttributes(), + ) + } } private suspend fun handleRepeatTransactionForSelfPay(otherUserInfo: UserTxnInfo?) { @@ -1268,9 +1270,10 @@ constructor( vpaEntityList = selectedAccount.vpaEntityList, screenName = screenName, onPspEvaluated = { pspEvaluationResult -> - if (pspEvaluationResult.psp == null) { - return@evaluateAndOnboardPspForFlow - } + val pspType = + pspEvaluationResult.onboardingDataEntity?.pspType + ?: return@evaluateAndOnboardPspForFlow + if (!naviPayNetworkConnectivity.isInternetConnected()) { notifyError(getNoInternetErrorConfig()) return@evaluateAndOnboardPspForFlow @@ -1300,7 +1303,7 @@ constructor( checkAccountBalanceUseCase.generateCheckAccountBalanceCred( linkedAccountEntity = selectedAccount, screenName = screenName, - pspType = pspEvaluationResult.psp, + pspType = pspType, onNpciResultError = { isUserAborted -> if (!isUserAborted) { notifyError(getNoInternetErrorConfig()) @@ -1311,7 +1314,7 @@ constructor( credBlock = credBlock, upiRequestId = upiRequestId, selectedBankAccount = selectedAccount, - pspType = pspEvaluationResult.psp, + pspType = pspType, ) }, ) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt index d395ac1560..e17507221d 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt @@ -71,7 +71,6 @@ const val NAVI_PAY_PROTECT_ARC_PENDING_LOTTIE = "navi-pay-arc-pending-loader.lot const val KEY_DEVICE_FINGERPRINT = "naviPayKeyDeviceFingerPrint" const val KEY_DEVICE_ID = "naviPayKeyDeviceId" const val KEY_SSID = "naviPayKeySSID" -const val KEY_PHONE_NUMBER = "naviPayKeyPhoneNumber" const val KEY_SIM_SLOT = "naviPayKeySimSlot" const val KEY_PACKAGE_NAME = "naviPayKeyPackageName" const val KEY_PROVIDER_NAME = "naviPayKeyProviderName" @@ -86,26 +85,12 @@ const val KEY_NPCI_TOKEN = "npciToken" const val KEY_NPCI_TOKEN_STORED_TIME = "npciTokenStoredTime" val NAVI_PAY_ENCRYPT_SHARED_PREF_DATA_KEYS = - listOf( - KEY_NPCI_TOKEN, - KEY_NPCI_TOKEN_STORED_TIME, - KEY_DEVICE_FINGERPRINT, - KEY_DEVICE_ID, - KEY_SSID, - KEY_PHONE_NUMBER, - KEY_SIM_SLOT, - KEY_PACKAGE_NAME, - KEY_PROVIDER_NAME, - KEY_EXTERNAL_CUSTOMER_ID, - KEY_CUSTOMER_STATUS, - KEY_UPI_LITE_ACTIVE_ACCOUNT_INFO, - ) + listOf(KEY_NPCI_TOKEN, KEY_NPCI_TOKEN_STORED_TIME, KEY_UPI_LITE_ACTIVE_ACCOUNT_INFO) const val KEY_NPCI_TOKEN_EXPIRY_IN_DAYS = "npciTokenExpriyInDays" const val KEY_BANK_LIST_DB_LAST_REFRESHED_TIMESTAMP = "bankListLastRefreshedTimestamp" -val NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS = - listOf(KEY_BANK_LIST_DB_LAST_REFRESHED_TIMESTAMP, KEY_CUSTOMER_STATUS) +val NAVI_PAY_NON_ENCRYPT_SHARED_PREF_DATA_KEYS = listOf(KEY_BANK_LIST_DB_LAST_REFRESHED_TIMESTAMP) // Shared Preference constants ends here const val INTENT_ACTION_SMS_SENT = "smsSent" @@ -159,6 +144,15 @@ const val NAVI_PAY_DEVICE_BINDING_IS_SMV_TRIGGERED_AND_FAILED = const val NAVI_PAY_PSP_ROUTING_BUCKETS_KEY = "naviPayPspRoutingBucketsKey" const val KEY_UPI_LITE_LAST_MANDATE_EXECUTION_TIMESTAMP = "upiLiteLastMandateExecutionTimestamp" const val KEY_UPI_LITE_LAST_MANDATE_EXECUTION_ATTEMPTS = "upiLiteLastMandateExecutionAttempts" +const val NAVI_PAY_ONBOARDING_DATA_MIGRATION_COMPLETED_KEY = + "naviPayOnboardingDataMigrationCompletedKey" + +// Navi Pay device data keys +const val NAVI_PAY_SIM_SLOT_CACHE_KEY = "naviPaySimSlotKey" +const val NAVI_PAY_SIM_PROVIDER_CACHE_KEY = "naviPaySimProviderKey" +const val NAVI_PAY_PACKAGE_NAME_CACHE_KEY = "naviPayPackageNameKey" +const val NAVI_PAY_SSID_CACHE_KEY = "naviPaySsidKey" +const val NAVI_PAY_DEVICE_ID_CACHE_KEY = "naviPayDeviceIdKey" // Sync DB keys const val NAVI_PAY_SYNC_TABLE_TRANSACTION_HISTORY_KEY = "transactionHistoryKey" @@ -299,6 +293,7 @@ const val NAVI_PAY_DATABASE_T_STORE_ORDER_HISTORY_TABLE_NAME = "orderHistory" const val NAVI_PAY_DATABASE_UPI_NUMBERS_TABLE_NAME = "upiNumbers" const val NAVI_PAY_DATABASE_VPA_TRANSACTION_INSIGHTS_TABLE_NAME = "vpaTransactionsInsights" const val NAVI_PAY_DATABASE_ORDER_TAG_SUMMARY_TABLE_NAME = "orderTagSummary" +const val NAVI_PAY_DATABASE_CUSTOMER_ONBOARDING_DETAILS_TABLE_NAME = "customerOnboardingDetails" // Shortcuts & Widgets keys const val NAVI_PAY_WIDGET_CLICKED_KEY = "NaviPay_Widget_Clicked" @@ -391,7 +386,6 @@ const val PAY_TO_CONTACTS_SCREEN_ROUTE = "pay_to_contacts_screen" const val QR_SCANNER_SCREEN_ROUTE = "qr_scanner_screen" // datastore -const val DS_KEY_NAVI_PAY_CUSTOMER_STATUS = "naviPayCustomerStatus" const val DS_KEY_SHOULD_REFRESH_MANDATE_SCREEN = "naviPayShouldRefreshMandateScreen" // Onboarding SDK constants diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/MPSScreen.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/MPSScreen.kt index 7628948e14..4e79784db8 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/MPSScreen.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/MPSScreen.kt @@ -379,52 +379,91 @@ fun MPSScreen( rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result -> - val resultResponse = result.data?.extras?.getString(NAVI_PAY_RESPONSE) - naviPaymentAnalytics.redirectionFromNaviUpi( - entryPoint = result.data?.extras?.getString("type").orEmpty(), - baseAttributes = mpsViewModel.getAnalyticsParams(), - resultCode = result.resultCode.toString(), - payload = resultResponse.orEmpty(), - ) - val payloadJson = resultResponse.stringToJsonObject() - if ( - result.resultCode == 200 && - payloadJson != null && - validateUpiProcessPayload(payloadJson) - ) { - val actionType = payloadJson.optString(TYPE) + coroutineScope.launch { + val resultResponse = result.data?.extras?.getString(NAVI_PAY_RESPONSE) + naviPaymentAnalytics.redirectionFromNaviUpi( + entryPoint = result.data?.extras?.getString("type").orEmpty(), + baseAttributes = mpsViewModel.getAnalyticsParams(), + resultCode = result.resultCode.toString(), + payload = resultResponse.orEmpty(), + ) + val payloadJson = resultResponse.stringToJsonObject() if ( - actionType == NaviPayAction.ONBOARDING_V2.name && - selectedBankAccount.isNotNull() + result.resultCode == 200 && + payloadJson != null && + validateUpiProcessPayload(payloadJson) ) { - mpsViewModel.updateBottomSheetUIState(true) - if (checkBalanceAccountId.isEmpty()) { - mpsViewModel.startPayAmount() + val actionType = payloadJson.optString(TYPE) + if ( + actionType == NaviPayAction.ONBOARDING_V2.name && + selectedBankAccount.isNotNull() + ) { + mpsViewModel.updateBottomSheetUIState(true) + if (checkBalanceAccountId.isEmpty()) { + mpsViewModel.startPayAmount() + } else { + mpsViewModel.onCheckBalanceClicked(checkBalanceAccountId) + } + } else if (selectedBankAccount.isNull()) { + mpsViewModel.refreshMPSScreen() } else { - mpsViewModel.onCheckBalanceClicked(checkBalanceAccountId) + mpsViewModel.updateBottomSheetUIState(true) } - } else if (selectedBankAccount.isNull()) { - mpsViewModel.refreshMPSScreen() } else { - mpsViewModel.updateBottomSheetUIState(true) - } - } else { - if (selectedBankAccount.isNull() && mpsViewModel.isUserOnboarded()) { - mpsViewModel.refreshMPSScreen() - } else { - mpsViewModel.updateBottomSheetUIState(true) - mpsViewModel.updateCheckBalanceAccountId(EMPTY) + if (selectedBankAccount.isNull() && mpsViewModel.isUserOnboardedForAnyPsp()) { + mpsViewModel.refreshMPSScreen() + } else { + mpsViewModel.updateBottomSheetUIState(true) + mpsViewModel.updateCheckBalanceAccountId(EMPTY) + } } } } val onCheckBalanceClicked: (accountId: String) -> Unit = { accountId -> try { - if (showPayNowLoader.not()) { - mpsViewModel.updateCheckBalanceAccountId(accountId) - if (mpsViewModel.isUserOnboarded()) { - mpsViewModel.onCheckBalanceClicked(accountId) - } else { + coroutineScope.launch { + if (showPayNowLoader.not()) { + mpsViewModel.updateCheckBalanceAccountId(accountId) + if (mpsViewModel.isUserOnboardedForAnyPsp()) { + mpsViewModel.onCheckBalanceClicked(accountId) + } else { + mpsViewModel.updateBottomSheetUIState(false) + val addAccountType = mpsViewModel.addAccountType + val addAccountTypeString = + if (addAccountType?.contains(CREDIT_ACCOUNT_TYPE).orFalse()) { + ALL_ENABLED_ACCOUNTS + } else { + SAVINGS_ONLY_ENABLED_ACCOUNTS + } + naviPaymentActivity.launchOnboardingSDK( + action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, + enabledAccountTypes = addAccountTypeString, + launcher = upiResultLauncher, + source = NaviPaymentScreenType.MINI_PAYMENT_SCREEN.name, + selectedAccountId = selectedBankAccount?.accountId, + ) + } + } + } + } catch (exception: JSONException) { + exception.log() + } + } + + val onPayButtonClick: () -> Unit = { + coroutineScope.launch { + try { + if (mpsViewModel.isUserOnboardedForAnyPsp().not()) { + naviPaymentAnalytics.onPayNowClickedNonOnboarded( + isDiscountApplied = isDiscountApplied.toString(), + baseAttributes = mpsViewModel.getAnalyticsParams(), + ) + naviPaymentAnalytics.redirectionToNaviUpi( + isDiscountApplied = isDiscountApplied.toString(), + action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, + baseAttributes = mpsViewModel.getAnalyticsParams(), + ) mpsViewModel.updateBottomSheetUIState(false) val addAccountType = mpsViewModel.addAccountType val addAccountTypeString = @@ -440,63 +479,30 @@ fun MPSScreen( source = NaviPaymentScreenType.MINI_PAYMENT_SCREEN.name, selectedAccountId = selectedBankAccount?.accountId, ) + } else if (checkBalanceAccountId.isNotEmpty()) { + // Do nothing + } else if (selectedBankAccount?.isMPinSet.orFalse().not()) { + naviPaymentAnalytics.onSetUpiPinBtnClick( + isDiscountApplied = isDiscountApplied.toString(), + baseAttributes = mpsViewModel.getAnalyticsParams(), + ) + val data = getMpinSetAction(selectedBankAccount?.accountId.orEmpty()) + naviPaymentAnalytics.redirectionToNaviUpi( + entryPoint = UpiIntent.SET_PIN.name, + baseAttributes = mpsViewModel.getAnalyticsParams(), + ) + mpsViewModel.updateBottomSheetUIState(mpsViewModel.isNaviUpiOnboarded.value) + mpsViewModel.startAction(naviPaymentActivity, upiResultLauncher, data) + } else { + naviPaymentAnalytics.onPayNowClicked( + isDiscountApplied = isDiscountApplied.toString(), + baseAttributes = mpsViewModel.getAnalyticsParams(), + ) + mpsViewModel.startPayAmount() } + } catch (exception: JSONException) { + exception.log() } - } catch (exception: JSONException) { - exception.log() - } - } - - val onPayButtonClick: () -> Unit = { - try { - if (mpsViewModel.isUserOnboarded().not()) { - naviPaymentAnalytics.onPayNowClickedNonOnboarded( - isDiscountApplied = isDiscountApplied.toString(), - baseAttributes = mpsViewModel.getAnalyticsParams(), - ) - naviPaymentAnalytics.redirectionToNaviUpi( - isDiscountApplied = isDiscountApplied.toString(), - action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, - baseAttributes = mpsViewModel.getAnalyticsParams(), - ) - mpsViewModel.updateBottomSheetUIState(false) - val addAccountType = mpsViewModel.addAccountType - val addAccountTypeString = - if (addAccountType?.contains(CREDIT_ACCOUNT_TYPE).orFalse()) { - ALL_ENABLED_ACCOUNTS - } else { - SAVINGS_ONLY_ENABLED_ACCOUNTS - } - naviPaymentActivity.launchOnboardingSDK( - action = NaviPayOnboardingActionsType.E2E_ONBOARDING.name, - enabledAccountTypes = addAccountTypeString, - launcher = upiResultLauncher, - source = NaviPaymentScreenType.MINI_PAYMENT_SCREEN.name, - selectedAccountId = selectedBankAccount?.accountId, - ) - } else if (checkBalanceAccountId.isNotEmpty()) { - // Do nothing - } else if (selectedBankAccount?.isMPinSet.orFalse().not()) { - naviPaymentAnalytics.onSetUpiPinBtnClick( - isDiscountApplied = isDiscountApplied.toString(), - baseAttributes = mpsViewModel.getAnalyticsParams(), - ) - val data = getMpinSetAction(selectedBankAccount?.accountId.orEmpty()) - naviPaymentAnalytics.redirectionToNaviUpi( - entryPoint = UpiIntent.SET_PIN.name, - baseAttributes = mpsViewModel.getAnalyticsParams(), - ) - mpsViewModel.updateBottomSheetUIState(mpsViewModel.isNaviUpiOnboarded.value) - mpsViewModel.startAction(naviPaymentActivity, upiResultLauncher, data) - } else { - naviPaymentAnalytics.onPayNowClicked( - isDiscountApplied = isDiscountApplied.toString(), - baseAttributes = mpsViewModel.getAnalyticsParams(), - ) - mpsViewModel.startPayAmount() - } - } catch (exception: JSONException) { - exception.log() } } diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/WebPaymentMainScreen.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/WebPaymentMainScreen.kt index 4e04cb342d..82d2a9351f 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/WebPaymentMainScreen.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/screens/WebPaymentMainScreen.kt @@ -184,61 +184,67 @@ fun WebPaymentMainScreen( rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result -> - val resultResponse = - result.data?.extras?.getString(NAVI_PAY_RESPONSE).stringToJsonObject() - ?: JSONObject() - webPaymentViewModel.sendEvent( - "NaviPMT_WebPaymentScreen_RedirectionFromNaviUpi", - mapOf( - "entry_point" to result.data?.extras?.getString("type").orEmpty(), - "result_code" to result.resultCode.toString(), - "payload" to resultResponse.toString(), - ), - ) - if (result.resultCode == UPI_RESULT_CODE && validateUpiProcessPayload(resultResponse)) { - when (lastExecutedActionBeforeOnboardingSdkTrigger) { - WebPaymentAction.WEB_VIEW_SEND_MONEY -> { - webPaymentViewModel.updateBottomSheetUIState( - false, - WebPaymentScreenState.PaymentPreProcessing, - ) - startWebViewPayment() + coroutineScope.launch { + val resultResponse = + result.data?.extras?.getString(NAVI_PAY_RESPONSE).stringToJsonObject() + ?: JSONObject() + webPaymentViewModel.sendEvent( + "NaviPMT_WebPaymentScreen_RedirectionFromNaviUpi", + mapOf( + "entry_point" to result.data?.extras?.getString("type").orEmpty(), + "result_code" to result.resultCode.toString(), + "payload" to resultResponse.toString(), + ), + ) + if ( + result.resultCode == UPI_RESULT_CODE && + validateUpiProcessPayload(resultResponse) + ) { + when (lastExecutedActionBeforeOnboardingSdkTrigger) { + WebPaymentAction.WEB_VIEW_SEND_MONEY -> { + webPaymentViewModel.updateBottomSheetUIState( + false, + WebPaymentScreenState.PaymentPreProcessing, + ) + startWebViewPayment() + } + WebPaymentAction.WEB_SEND_MONEY -> { + webPaymentViewModel.updateBottomSheetUIState( + true, + WebPaymentScreenState.Loading, + ) + webPaymentViewModel.getMethodData() + } + else -> { + handleResultAndFinish( + activity = activity, + webPaymentAction = webPaymentAction, + webPaymentData = webPaymentData, + status = SUCCESS, + additionalParams = + mapOf(NAVI_PAY_RESPONSE to resultResponse.toString()), + ) + } } - WebPaymentAction.WEB_SEND_MONEY -> { - webPaymentViewModel.updateBottomSheetUIState( - true, - WebPaymentScreenState.Loading, - ) - webPaymentViewModel.getMethodData() - } - else -> { + webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(null) + } else { + if ( + lastExecutedActionBeforeOnboardingSdkTrigger.isNotNull() && + webPaymentAction == WebPaymentAction.WEB_SEND_MONEY && + webPaymentViewModel.isUserOnboardedForAnyPsp() + ) { + webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(null) + webPaymentViewModel.updateBottomSheetUIState(true) + } else { handleResultAndFinish( activity = activity, webPaymentAction = webPaymentAction, webPaymentData = webPaymentData, - status = SUCCESS, + status = getUpiTransationStatus(resultResponse), additionalParams = mapOf(NAVI_PAY_RESPONSE to resultResponse.toString()), ) } } - webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(null) - } else { - if ( - lastExecutedActionBeforeOnboardingSdkTrigger.isNotNull() && - webPaymentAction == WebPaymentAction.WEB_SEND_MONEY && - webPaymentViewModel.isUserOnboarded() - ) { - webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(null) - webPaymentViewModel.updateBottomSheetUIState(true) - } else { - handleResultAndFinish( - activity = activity, - webPaymentAction = webPaymentAction, - webPaymentData = webPaymentData, - status = getUpiTransationStatus(resultResponse), - additionalParams = mapOf(NAVI_PAY_RESPONSE to resultResponse.toString()), - ) - } } } @@ -252,11 +258,13 @@ fun WebPaymentMainScreen( } val startOrOnboardWebViewPayment = { - if (webPaymentViewModel.isUserOnboarded().not()) { - webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(webPaymentAction) - startOnboarding() - } else { - startWebViewPayment() + coroutineScope.launch { + if (webPaymentViewModel.isUserOnboardedForAnyPsp().not()) { + webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(webPaymentAction) + startOnboarding() + } else { + startWebViewPayment() + } } } @@ -409,7 +417,7 @@ fun WebPaymentMainScreen( ) } WebPaymentAction.WEB_SEND_MONEY -> { - if (webPaymentViewModel.isUserOnboarded().not()) { + if (webPaymentViewModel.isUserOnboardedForAnyPsp().not()) { webPaymentViewModel.updateLastTriggeredActionBeforeOnboarding(webPaymentAction) startOnboarding() } else { diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt index bafe9faca7..85107c5319 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt @@ -521,7 +521,7 @@ constructor( "token" to paymentSdkInitParams?.token.orEmpty(), "payment_method" to "UPI_LINKED_BANK_ACCOUNTS", "payment_sdk_type" to "compose", - "is_navi_upi_onboarded" to naviPayManager.isUserOnboarded().toString(), + "is_navi_upi_onboarded" to naviPayManager.isUserOnboardedForAnyPsp().toString(), ) ) } @@ -658,7 +658,7 @@ constructor( arcNudgeUseCase.updateAccountArcStatusForLinkedAccount(it) } } - if (!naviPayManager.isUserOnboarded() && finalList.isEmpty()) { + if (!naviPayManager.isUserOnboardedForAnyPsp() && finalList.isEmpty()) { updateBottomSheetUIState( showBottomSheet = true, bottomSheetUIState = MPSScreenUtils.MPSScreenType.NonOnboarded, @@ -678,7 +678,7 @@ constructor( } } ?: run { - if (naviPayManager.isUserOnboarded().not()) { + if (naviPayManager.isUserOnboardedForAnyPsp().not()) { updateBottomSheetUIState( showBottomSheet = true, bottomSheetUIState = MPSScreenUtils.MPSScreenType.NonOnboarded, @@ -838,8 +838,8 @@ constructor( } } - fun isUserOnboarded(): Boolean { - return naviPayManager.isUserOnboarded() + suspend fun isUserOnboardedForAnyPsp(): Boolean { + return naviPayManager.isUserOnboardedForAnyPsp() } fun onDiscountClicked(isDiscountApplied: Boolean) { diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NPSViewModel.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NPSViewModel.kt index 51fbaf5e32..08f9f6d209 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NPSViewModel.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NPSViewModel.kt @@ -490,7 +490,8 @@ constructor( return npsScreenState.copy( naviUpiPaymentState = npsScreenState.naviUpiPaymentState.copy( - showOnboardingCard = !naviPayManager.isUserOnboarded() && finalList.isEmpty(), + showOnboardingCard = + !naviPayManager.isUserOnboardedForAnyPsp() && finalList.isEmpty(), onboardingDetails = instrumentDetails.onboardingDetails, addAccountType = instrumentDetails.availableAddAccountTypes, bankAccountState = BankAccountsState.AccountList(finalList), @@ -987,7 +988,7 @@ constructor( ?.accounts .isNotNullAndNotEmpty() ) { - if (naviPayManager.isUserOnboarded().not()) { + if (naviPayManager.isUserOnboardedForAnyPsp().not()) { handleNaviUpiOnboarding(selectedBankAccountId = selectedBankAccount?.accountId) } else { if (selectedBankAccount?.isMPinSet.orTrue().not()) { @@ -1452,7 +1453,7 @@ constructor( as? BankAccountsState.AccountList) ?.accounts ?.firstOrNull { it.accountId == accountId } - if (naviPayManager.isUserOnboarded()) { + if (naviPayManager.isUserOnboardedForAnyPsp()) { updateCheckBalanceCtaLoaderState(isCheckBalanceCtaLoaderEnabled = true) linkedAccount?.let { accountListCheckBalanceUseCase.onCheckBalanceClicked( diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/UpiIntentViewModel.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/UpiIntentViewModel.kt index 8155567c93..1f339069ad 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/UpiIntentViewModel.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/UpiIntentViewModel.kt @@ -307,7 +307,7 @@ constructor( private suspend fun buildPayNowRequest(vpa: String): PayNowRequest? { val vpaAccount = upiScreenState.connectedAccountVpaMap?.get(vpa) - return if (vpaAccount.isNotNull() && naviPayManager.isUserOnboarded().not()) { + return if (vpaAccount.isNotNull() && naviPayManager.isUserOnboardedForAnyPsp().not()) { _effect.emit( UpiIntentScreenContract.UpiScreenEffect.StartNaviUpiOnboarding( selectedBankAccountId = vpaAccount?.accountId diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/WebNaviPaymentViewModel.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/WebNaviPaymentViewModel.kt index 53ff56d8fb..271d80578c 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/WebNaviPaymentViewModel.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/WebNaviPaymentViewModel.kt @@ -149,49 +149,51 @@ constructor( } private fun initiate() { - var showBottomSheet = false - val screenState: WebPaymentScreenState - when (webPayAction) { - WebPaymentAction.WEB_VIEW_ONBOARDING -> { - screenState = WebPaymentScreenState.Init - } - WebPaymentAction.WEB_VIEW_ADD_BANK_ACCOUNT -> { - screenState = WebPaymentScreenState.Init - } - WebPaymentAction.WEB_VIEW_SET_PIN -> { - screenState = WebPaymentScreenState.Init - } - WebPaymentAction.WEB_VIEW_SEND_MONEY -> { - showBottomSheet = false - screenState = - if (naviPayManager.isUserOnboarded()) { - WebPaymentScreenState.PaymentPreProcessing - } else { - WebPaymentScreenState.Init - } - } - WebPaymentAction.WEB_SEND_MONEY -> { - if (naviPayManager.isUserOnboarded()) { - showBottomSheet = true - screenState = WebPaymentScreenState.Loading - } else { + viewModelScope.launch(Dispatchers.IO) { + var showBottomSheet = false + val screenState: WebPaymentScreenState + when (webPayAction) { + WebPaymentAction.WEB_VIEW_ONBOARDING -> { screenState = WebPaymentScreenState.Init } + WebPaymentAction.WEB_VIEW_ADD_BANK_ACCOUNT -> { + screenState = WebPaymentScreenState.Init + } + WebPaymentAction.WEB_VIEW_SET_PIN -> { + screenState = WebPaymentScreenState.Init + } + WebPaymentAction.WEB_VIEW_SEND_MONEY -> { + showBottomSheet = false + screenState = + if (naviPayManager.isUserOnboardedForAnyPsp()) { + WebPaymentScreenState.PaymentPreProcessing + } else { + WebPaymentScreenState.Init + } + } + WebPaymentAction.WEB_SEND_MONEY -> { + if (naviPayManager.isUserOnboardedForAnyPsp()) { + showBottomSheet = true + screenState = WebPaymentScreenState.Loading + } else { + screenState = WebPaymentScreenState.Init + } + } + else -> { + screenState = WebPaymentScreenState.Error() + } } - else -> { - screenState = WebPaymentScreenState.Error() - } - } - updateBottomSheetUIState(showBottomSheet, screenState) - paymentDataProvider.updateAnalyticsParams( - mapOf( - WEB_PAYMENT_SOURCE to - if (webPayAction == WebPaymentAction.WEB_SEND_MONEY) - WebPaymentSource.BROWSER.name - else WebPaymentSource.WEBVIEW.name, - WEB_PAY_ACTION to webPayAction?.name.orEmpty(), + updateBottomSheetUIState(showBottomSheet, screenState) + paymentDataProvider.updateAnalyticsParams( + mapOf( + WEB_PAYMENT_SOURCE to + if (webPayAction == WebPaymentAction.WEB_SEND_MONEY) + WebPaymentSource.BROWSER.name + else WebPaymentSource.WEBVIEW.name, + WEB_PAY_ACTION to webPayAction?.name.orEmpty(), + ) ) - ) + } } fun getMethodData() { @@ -510,8 +512,8 @@ constructor( _lastExecutedActionBeforeUpiSdkTrigger.value = action } - fun isUserOnboarded(): Boolean { - return naviPayManager.isUserOnboarded() + suspend fun isUserOnboardedForAnyPsp(): Boolean { + return naviPayManager.isUserOnboardedForAnyPsp() } fun sendEvent(eventName: String, additionalParams: Map = emptyMap()) {