NTP-47479 | Shiv Natani | one cc mpin set (#15549)

This commit is contained in:
Shiv Natani
2025-03-27 16:29:39 +05:30
committed by GitHub
parent d905b5310a
commit a39815e54a
3 changed files with 114 additions and 12 deletions

View File

@@ -7,9 +7,12 @@
package com.navi.payment.nativepayment.components
import android.content.Intent
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentTransitionScope
@@ -89,10 +92,13 @@ import com.navi.payment.nativepayment.model.OneClickBottomSheetUiState
import com.navi.payment.nativepayment.model.PaymentsMainCtaState
import com.navi.payment.nativepayment.model.RewardsInfoV2
import com.navi.payment.nativepayment.presentation.reducer.OneClickCheckoutState
import com.navi.payment.nativepayment.presentation.reducer.OneClickScreenEffect
import com.navi.payment.nativepayment.presentation.reducer.OneClickScreenEvent
import com.navi.payment.nativepayment.screens.RedirectingBottomSheetContent
import com.navi.payment.nativepayment.sharedviewmodel.NaviCheckoutViewModelV2
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@@ -163,6 +169,24 @@ fun PaymentCheckoutFooter(
)
}
val upiResultLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result
->
naviCheckoutViewModel.onEvent(
OneClickScreenEvent.OnNaviUpiResultReceived(
result = result,
generateToken = generateToken,
)
)
}
EffectsHandler(
activity = activity,
oneCliCkCheckoutScreenEffect = naviCheckoutViewModel.effect,
oneClickCheckoutViewModelV2 = naviCheckoutViewModel,
upiResultLauncher = upiResultLauncher,
)
Column(
modifier =
modifier
@@ -512,3 +536,25 @@ fun OneClickBankAccountItem(
}
}
}
@Composable
fun EffectsHandler(
oneCliCkCheckoutScreenEffect: SharedFlow<OneClickScreenEffect>,
oneClickCheckoutViewModelV2: NaviCheckoutViewModelV2,
activity: ComponentActivity,
upiResultLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>,
) {
LaunchedEffect(Unit) {
oneCliCkCheckoutScreenEffect.collectLatest { effect ->
when (effect) {
is OneClickScreenEffect.StartNaviUpiMPinSetAction -> {
oneClickCheckoutViewModelV2.startAction(
activity = activity,
upiResultLauncher = upiResultLauncher,
data = effect.payload,
)
}
}
}
}
}

View File

@@ -7,6 +7,7 @@
package com.navi.payment.nativepayment.presentation.reducer
import androidx.activity.result.ActivityResult
import com.navi.pay.common.model.view.CheckBalanceState
import com.navi.pay.management.common.sendmoney.model.view.BankAccountsState
import com.navi.pay.management.common.sendmoney.model.view.EligibilityState
@@ -14,6 +15,7 @@ import com.navi.pay.onboarding.account.detail.model.view.LinkedAccountEntity
import com.navi.payment.model.paymentmethod.Amount
import com.navi.payment.nativepayment.model.PaymentsMainCtaState
import kotlinx.coroutines.flow.MutableStateFlow
import org.json.JSONObject
interface OneClickScreenContract :
NaviPaymentViewModelContract<OneClickCheckoutState, OneClickScreenEffect, OneClickScreenEvent>
@@ -40,9 +42,14 @@ sealed interface OneClickScreenEvent {
data object OnArcNudgeClicked : OneClickScreenEvent
data object OnCheckBalanceClicked : OneClickScreenEvent
data class OnNaviUpiResultReceived(val result: ActivityResult, val generateToken: () -> Unit) :
OneClickScreenEvent
}
sealed interface OneClickScreenEffect {}
sealed interface OneClickScreenEffect {
data class StartNaviUpiMPinSetAction(val payload: JSONObject) : OneClickScreenEffect
}
enum class CheckoutCtaAction {
SEND_MONEY_NAVIGATION,

View File

@@ -7,7 +7,11 @@
package com.navi.payment.nativepayment.sharedviewmodel
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.result.ActivityResult
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.navi.base.AppServiceManager
@@ -23,11 +27,15 @@ import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PMT_ONE_CLICK_CHECKOUT_API_TIMEOUT_MILLIS
import com.navi.common.network.models.isSuccessWithData
import com.navi.common.payments.arc.model.network.ArcNudgeBottomSheetData
import com.navi.common.upi.NAVI_PAY_RESPONSE
import com.navi.common.upi.NaviPayAction
import com.navi.common.upi.TYPE
import com.navi.common.upi.UpiDataType
import com.navi.common.usecase.LitmusExperimentsUseCase
import com.navi.common.utils.CommonUtils.getDisplayableAmount
import com.navi.common.utils.Constants.DEFAULT
import com.navi.common.utils.EMPTY
import com.navi.common.utils.stringToJsonObject
import com.navi.pay.common.model.view.NaviPayFlowType
import com.navi.pay.common.setup.NaviPayManager
import com.navi.pay.common.usecase.AccountListCheckBalanceUseCase
@@ -50,6 +58,7 @@ import com.navi.payment.nativepayment.dataprovider.PaymentDataProvider
import com.navi.payment.nativepayment.dataprovider.PaymentDataProvider.Companion.ACTION_TYPE
import com.navi.payment.nativepayment.dataprovider.PaymentDataProvider.Companion.SCREEN_TYPE
import com.navi.payment.nativepayment.dataprovider.PaymentDataProvider.Companion.UPI_LITE_MAX_PAYABLE_AMOUNT_PER_TRANSACTION
import com.navi.payment.nativepayment.dataprovider.getMpinSetAction
import com.navi.payment.nativepayment.model.GetPaymentMethodsV3Request
import com.navi.payment.nativepayment.model.InstrumentDetails
import com.navi.payment.nativepayment.model.NaviPaymentScreenType
@@ -95,6 +104,7 @@ import com.navi.payment.utils.getArcNudgeBottomSheetCampaignTitle
import com.navi.payment.utils.getArcNudgeBottomSheetTitle
import com.navi.payment.utils.getInstalledUpiAppsList
import com.navi.payment.utils.getPMSMetricInfo
import com.navi.payment.utils.validateUpiProcessPayload
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
@@ -244,11 +254,45 @@ constructor(
is OneClickScreenEvent.OnCheckBalanceClicked -> {
handleCheckBalanceClicked()
}
is OneClickScreenEvent.OnNaviUpiResultReceived -> {
handleNaviUpiResultReceived(
result = event.result,
generateToken = event.generateToken,
)
}
}
}
}
}
private fun handleNaviUpiResultReceived(result: ActivityResult, generateToken: () -> Unit) {
val resultResponse = result.data?.extras?.getString(NAVI_PAY_RESPONSE)
val payloadJson = resultResponse.stringToJsonObject()
if (
result.resultCode == 200 &&
payloadJson != null &&
validateUpiProcessPayload(payloadJson)
) {
val actionType = payloadJson.optString(TYPE)
if (actionType == NaviPayAction.SET_PIN.name) {
updateBottomSheetUIState(
showBottomSheet = true,
bottomSheetUIState =
OneClickBottomSheetUiState.RedirectingBottomSheet(
titleText =
resourceProvider.getString(R.string.redirecting_make_payment)
),
)
triggerTokenGeneration(generateToken)
} else {
// Do Nothing - Onboarding is handled by NaviPayPspManager
}
} else {
// Do Nothing
}
}
fun onTokenGenerated(paymentSdkInitParams: PaymentSdkInitParams) {
viewModelScope.safeLaunch {
naviPaymentAnalytics.onTokenReceived(
@@ -605,16 +649,16 @@ constructor(
isMpinSetOfSelectedAccount = linkedAccountEntity.isMPinSet,
ctaAction = ctaAction.toString(),
)
naviPayPspManager.evaluateAndOnboardPspForFlow(
naviPayFlowType = NaviPayFlowType.PIN_MANAGEMENT,
vpaEntityList = linkedAccountEntity.vpaEntityList,
screenName = NaviPaymentScreenType.ONE_CLICK_CHECKOUT_SCREEN.name,
onPspEvaluated = { pspEvaluationResult ->
if (pspEvaluationResult.onboardingDataEntity.isNotNull()) {
resetCheckBalanceStates()
}
},
)
val pinSetPayLoad = getMpinSetAction(state.value.selectedAccount?.accountId.orEmpty())
_effect.emit(OneClickScreenEffect.StartNaviUpiMPinSetAction(payload = pinSetPayLoad))
}
fun startAction(
activity: Activity,
upiResultLauncher: ManagedActivityResultLauncher<Intent, ActivityResult>,
data: JSONObject,
) {
naviPayManager.startAction(activity, upiResultLauncher, data)
}
private suspend fun startPayment(generateToken: () -> Unit) {
@@ -811,7 +855,12 @@ constructor(
val pspType = pspEvaluationResult.onboardingDataEntity?.pspType ?: return
if (selectedBankAccount.isMPinSet.not().orFalse()) {
handleSetPinClick(selectedBankAccount)
_effect.emit(
OneClickScreenEffect.StartNaviUpiMPinSetAction(
payload = getMpinSetAction(selectedBankAccount.accountId)
)
)
return
}
if (pspEvaluationResult.isOnboardingTriggered) {