NTP-60662 | Vedant Aggarwal | Multibank Support in Delayed VPA Validation (#16123)
This commit is contained in:
@@ -19,7 +19,6 @@ import com.navi.pay.common.model.network.ValidateVpaRequest
|
||||
import com.navi.pay.common.model.network.ValidateVpaResponse
|
||||
import com.navi.pay.common.model.view.NaviPayFlowType
|
||||
import com.navi.pay.common.model.view.NaviPaySessionHelper
|
||||
import com.navi.pay.common.model.view.PspType
|
||||
import com.navi.pay.common.repository.CommonRepository
|
||||
import com.navi.pay.common.setup.NaviPayCustomerStatusHandler
|
||||
import com.navi.pay.common.utils.getMetricInfo
|
||||
@@ -27,7 +26,6 @@ import com.navi.pay.common.validatevpa.model.view.ValidateVpaEntity
|
||||
import com.navi.pay.management.common.utils.NaviPayPspManager
|
||||
import com.navi.pay.management.paytocontacts.model.network.PayToContactRequest
|
||||
import com.navi.pay.network.di.NaviPayGsonBuilder
|
||||
import com.navi.pay.onboarding.account.common.repository.AccountsRepository
|
||||
import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity
|
||||
import com.navi.pay.utils.DEFAULT_RETRY_COUNT
|
||||
import com.navi.pay.utils.RETRY_INTERVAL_IN_SECONDS
|
||||
@@ -48,7 +46,6 @@ constructor(
|
||||
private val naviPaySessionHelper: NaviPaySessionHelper,
|
||||
private val naviPayPspManager: NaviPayPspManager,
|
||||
private val naviPayCustomerStatusHandler: NaviPayCustomerStatusHandler,
|
||||
private val accountsRepository: AccountsRepository,
|
||||
@NaviPayGsonBuilder private val gson: Gson,
|
||||
) {
|
||||
val naviPayAnalytics = NaviPayAnalytics.INSTANCE.NaviPayValidateVpaUseCase()
|
||||
@@ -65,25 +62,22 @@ constructor(
|
||||
naviPayAnalytics.onValidateVpaStart(
|
||||
naviPaySessionAttributes = naviPaySessionHelper.getNaviPaySessionAttributes()
|
||||
)
|
||||
val isCustomerExists = isCustomerExistsOnAnySupportedPsp(screenName)
|
||||
val pspTypesWhereCustomerExists =
|
||||
naviPayPspManager.getSupportedPspListWhereCustomerExists(
|
||||
naviPayFlowType = NaviPayFlowType.VALIDATE_VPA,
|
||||
screenName = screenName,
|
||||
)
|
||||
val isCustomerExists = pspTypesWhereCustomerExists.isNotEmpty()
|
||||
if (!skipCustomerOnboardingCheck && !isCustomerExists) {
|
||||
naviPayAnalytics.onValidateVpaAbort(naviPaySessionHelper.getNaviPaySessionAttributes())
|
||||
return null // early return
|
||||
}
|
||||
|
||||
var customerOnboardingEntity: NaviPayCustomerOnboardingEntity? = null
|
||||
|
||||
if (isCustomerExists) {
|
||||
// TODO: Hardcoded PSP to be removed in multibank
|
||||
customerOnboardingEntity =
|
||||
naviPayCustomerStatusHandler.getCustomerOnboardingEntity(
|
||||
pspType = PspType.JUSPAY_AXIS
|
||||
)
|
||||
} else {
|
||||
evaluateAndBindPspForVpaValidation(
|
||||
onPspEvaluatedSuccess = { customerOnboardingEntity = it }
|
||||
)
|
||||
}
|
||||
evaluatePspForVpaValidation(
|
||||
isCustomerExists = isCustomerExists,
|
||||
onPspEvaluatedSuccess = { customerOnboardingEntity = it },
|
||||
)
|
||||
|
||||
if (customerOnboardingEntity == null) {
|
||||
return null
|
||||
@@ -137,20 +131,41 @@ constructor(
|
||||
return validateVpaRepoResultResponse
|
||||
}
|
||||
|
||||
private suspend fun evaluateAndBindPspForVpaValidation(
|
||||
onPspEvaluatedSuccess: (NaviPayCustomerOnboardingEntity?) -> Unit,
|
||||
private suspend fun evaluatePspForVpaValidation(
|
||||
isCustomerExists: Boolean,
|
||||
onPspEvaluatedSuccess: (NaviPayCustomerOnboardingEntity) -> Unit,
|
||||
onPspEvaluatedFailed: () -> Unit = {},
|
||||
) {
|
||||
naviPayPspManager.evaluateAndBindAnySupportedPspForFlow(
|
||||
naviPayFlowType = NaviPayFlowType.VALIDATE_VPA,
|
||||
screenName = screenName,
|
||||
onPspEvaluated = { pspEvaluationResult ->
|
||||
if (pspEvaluationResult.onboardingDataEntity == null) {
|
||||
onPspEvaluatedFailed()
|
||||
if (isCustomerExists) {
|
||||
val selectedPsp =
|
||||
naviPayPspManager.getPspWithoutOnboardingForFlow(
|
||||
naviPayFlowType = NaviPayFlowType.VALIDATE_VPA,
|
||||
screenName = screenName,
|
||||
)
|
||||
|
||||
val customerOnboardingEntity =
|
||||
selectedPsp?.let {
|
||||
naviPayCustomerStatusHandler.getCustomerOnboardingEntity(pspType = it)
|
||||
}
|
||||
onPspEvaluatedSuccess(pspEvaluationResult.onboardingDataEntity)
|
||||
},
|
||||
)
|
||||
|
||||
if (customerOnboardingEntity != null) {
|
||||
onPspEvaluatedSuccess(customerOnboardingEntity)
|
||||
} else {
|
||||
onPspEvaluatedFailed()
|
||||
}
|
||||
} else {
|
||||
naviPayPspManager.evaluateAndBindAnySupportedPspForFlow(
|
||||
naviPayFlowType = NaviPayFlowType.VALIDATE_VPA,
|
||||
screenName = screenName,
|
||||
onPspEvaluated = { pspEvaluationResult ->
|
||||
if (pspEvaluationResult.onboardingDataEntity == null) {
|
||||
onPspEvaluatedFailed()
|
||||
return@evaluateAndBindAnySupportedPspForFlow
|
||||
}
|
||||
onPspEvaluatedSuccess(pspEvaluationResult.onboardingDataEntity)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> fetchFromNetworkAndSaveToDb(
|
||||
@@ -234,21 +249,6 @@ constructor(
|
||||
return apiResponse
|
||||
}
|
||||
|
||||
// returns true if customer has done binding or has at least one account in db
|
||||
private suspend fun isCustomerExistsOnAnySupportedPsp(screenName: String): Boolean {
|
||||
val accounts = accountsRepository.getAllAccounts()
|
||||
if (accounts.isNotEmpty()) {
|
||||
return true
|
||||
}
|
||||
val supportedPspTypes =
|
||||
naviPayPspManager.getSupportedPspList(
|
||||
naviPayFlowType = NaviPayFlowType.VALIDATE_VPA,
|
||||
screenName = screenName,
|
||||
)
|
||||
val customerStatusMap = naviPayCustomerStatusHandler.getCustomerStatusMap()
|
||||
return supportedPspTypes.any { psp -> customerStatusMap[psp]?.isBound == true }
|
||||
}
|
||||
|
||||
private fun <T> getVpaKeyParam(request: T): String {
|
||||
return when (request) {
|
||||
is ValidateVpaRequest -> request.vpa
|
||||
|
||||
@@ -24,6 +24,7 @@ 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.account.common.repository.AccountsRepository
|
||||
import com.navi.pay.onboarding.activatevpa.model.view.VpaActivationData
|
||||
import com.navi.pay.onboarding.binding.model.view.NaviPayCustomerOnboardingEntity
|
||||
import com.navi.pay.onboarding.common.NaviPayOnboardingActionsType
|
||||
@@ -52,6 +53,7 @@ constructor(
|
||||
private val naviPayOnboardingNavigator: NaviPayOnboardingNavigator,
|
||||
private val naviCacheRepository: NaviCacheRepository,
|
||||
private val resourceProvider: ResourceProvider,
|
||||
private val accountsRepository: AccountsRepository,
|
||||
@NaviPayGsonBuilder private val gson: Gson,
|
||||
) {
|
||||
private lateinit var screenName: String
|
||||
@@ -299,8 +301,8 @@ constructor(
|
||||
val pspSelectionConfig = getPspSelectionConfig()
|
||||
|
||||
val supportedPspList =
|
||||
getSupportedPspList(
|
||||
naviPayFlowType = naviPayFlowType,
|
||||
getSupportedPspListWhereCustomerExists(
|
||||
naviPayFlowType,
|
||||
pspSelectionConfig = pspSelectionConfig,
|
||||
)
|
||||
if (supportedPspList.isEmpty()) {
|
||||
@@ -404,14 +406,55 @@ constructor(
|
||||
onPspEvaluated(pspEvaluationResult)
|
||||
}
|
||||
|
||||
suspend fun getSupportedPspList(
|
||||
/**
|
||||
* Retrieves a list of supported PSP types where a customer exists.
|
||||
*
|
||||
* @param naviPayFlowType The flow type for the NaviPay process.
|
||||
* @param pspSelectionConfig Optional configuration for PSP selection. If null, defaults to the
|
||||
* standard configuration.
|
||||
* @param screenName The name of the screen invoking this function. Defaults to the instance's
|
||||
* screen name.
|
||||
* @return A list of supported PSP types that have associated accounts or are device bound.
|
||||
*/
|
||||
suspend fun getSupportedPspListWhereCustomerExists(
|
||||
naviPayFlowType: NaviPayFlowType,
|
||||
pspSelectionConfig: PspSelectionConfigContent? = null,
|
||||
screenName: String = this.screenName,
|
||||
): List<PspType> {
|
||||
this@NaviPayPspManager.screenName = screenName
|
||||
val flowToRoutingBucketMap =
|
||||
(pspSelectionConfig ?: getPspSelectionConfig()).flowToRoutingBucketMap
|
||||
|
||||
val supportedPspTypes =
|
||||
getSupportedPspList(
|
||||
naviPayFlowType = naviPayFlowType,
|
||||
pspSelectionConfig = pspSelectionConfig ?: getPspSelectionConfig(),
|
||||
)
|
||||
|
||||
val pspTypesWhereCustomerExists = getPspListWhereCustomerExists().toSet()
|
||||
|
||||
return supportedPspTypes.filter { it in pspTypesWhereCustomerExists }
|
||||
}
|
||||
|
||||
private suspend fun getPspListWhereCustomerExists(): List<PspType> {
|
||||
val vpaEntities = accountsRepository.getAllVpaEntities()
|
||||
|
||||
val pspTypesWithAccounts =
|
||||
vpaEntities
|
||||
.filter { it.pspType != null && it.status != VpaStatus.PENDING_ADDITION }
|
||||
.mapNotNull { it.pspType }
|
||||
.toSet()
|
||||
|
||||
val customerStatusMap = naviPayCustomerStatusHandler.getCustomerStatusMap()
|
||||
|
||||
return PspType.entries.filter { psp ->
|
||||
pspTypesWithAccounts.contains(psp) || customerStatusMap[psp]?.isBound == true
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getSupportedPspList(
|
||||
naviPayFlowType: NaviPayFlowType,
|
||||
pspSelectionConfig: PspSelectionConfigContent,
|
||||
): List<PspType> {
|
||||
val flowToRoutingBucketMap = pspSelectionConfig.flowToRoutingBucketMap
|
||||
val pspDistributionMap =
|
||||
getPspDistributionMap(
|
||||
naviPayFlowType = naviPayFlowType,
|
||||
|
||||
@@ -48,4 +48,7 @@ interface VpaDao {
|
||||
"SELECT accountId FROM $NAVI_PAY_DATABASE_VPA_TABLE_NAME WHERE bankAccountUniqueId = :buid LIMIT 1"
|
||||
)
|
||||
suspend fun getAccountIdByBuid(buid: String): String?
|
||||
|
||||
@Query("SELECT * FROM $NAVI_PAY_DATABASE_VPA_TABLE_NAME")
|
||||
suspend fun getAllVpaEntities(): List<VpaEntity>
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ constructor(
|
||||
suspend fun insertAllAccountEntity(accountEntities: List<AccountEntity>) =
|
||||
accountDao.insertAll(accountEntities = accountEntities)
|
||||
|
||||
suspend fun getAllAccounts() = accountDao.getAllAccounts()
|
||||
suspend fun getAllVpaEntities() = vpaDao.getAllVpaEntities()
|
||||
|
||||
fun getAllAccountByStatusAsFlow(status: AccountStatus) =
|
||||
accountDao.getAllAccountByStatusAsFlow(status = status)
|
||||
|
||||
Reference in New Issue
Block a user