TP-72001 | Payment sdk integration (#11788)

This commit is contained in:
shreyansu raj
2024-07-16 15:19:23 +05:30
committed by GitHub
parent bbaabd34e3
commit 18124e573d
12 changed files with 427 additions and 90 deletions

View File

@@ -9,34 +9,62 @@ package com.naviapp.custom_payments
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.navi.base.model.CtaData
import com.navi.common.listeners.FragmentInterchangeListener
import com.navi.common.model.ModuleNameV2
import com.navi.common.utils.observeNullable
import com.navi.payment.model.common.PaymentSdkInitParams
import com.navi.payment.model.common.PaymentSdkTypes
import com.navi.payment.model.initiatesdk.PaymentPrefetchMethodRequest
import com.navi.payment.nativepayment.router.NaviPaymentRouter
import com.navi.payment.nativepayment.sharedviewmodel.NaviCheckoutViewModel
import com.navi.payment.paymentscreen.model.PaymentActivityResponse
import com.navi.payment.paymentscreen.viewmodel.PaymentScreenSharedViewModel
import com.navi.payment.utils.Constants.FULL_PAYMENT_SCREEN
import com.navi.payment.utils.PaymentSource
import com.navi.paymentclients.model.InitiatePaymentRequest
import com.naviapp.R
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.dashboard.DashboardBaseActivity
import com.naviapp.databinding.ActivityCustomPaymentBinding
import com.naviapp.part_prepayment.FragmentMapper
import com.naviapp.payment.activities.FeedbackActivity
import com.naviapp.payment.models.Amount
import com.naviapp.payment.viewmodel.PaymentVM
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.IS_SYNC_FLOW
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import com.naviapp.utils.LOAN_ACCOUNT_REQUEST_ID
import dagger.hilt.android.AndroidEntryPoint
import java.util.Locale
import javax.inject.Inject
@AndroidEntryPoint
class CustomPaymentActivity : DashboardBaseActivity(), FragmentInterchangeListener {
class CustomPaymentActivity :
DashboardBaseActivity(), FragmentInterchangeListener, InitiatePaymentListener {
private lateinit var binding: ActivityCustomPaymentBinding
@Inject lateinit var fragmentMapper: FragmentMapper
private val paymentVM by viewModels<PaymentVM>()
private val paymentScreenSharedViewModel by lazy {
ViewModelProvider(this)[PaymentScreenSharedViewModel::class.java]
}
private val naviCheckoutViewModel by viewModels<NaviCheckoutViewModel>()
private var loanAccountNumber: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
binding = DataBindingUtil.setContentView(this, R.layout.activity_custom_payment)
super.onCreate(savedInstanceState)
@@ -44,6 +72,9 @@ class CustomPaymentActivity : DashboardBaseActivity(), FragmentInterchangeListen
intent?.extras?.getString(Constants.REDIRECT_STATUS).orEmpty(),
intent?.extras ?: Bundle()
)
initError(paymentVM, actionErrorV2Enabled = true)
observePaymentListener()
observeInitiatePaymentStatus()
}
override val screenName: String
@@ -112,4 +143,106 @@ class CustomPaymentActivity : DashboardBaseActivity(), FragmentInterchangeListen
)
}
}
override fun initiatePayment(
amount: Amount,
isPreClosure: Boolean,
repaymentType: String?,
sourceOfFunds: String?,
otherSourceOfFunds: String?,
partPrePaymentRescheduleType: String?,
loanAccountNumber: String?,
loanType: String?
) {
this.loanAccountNumber = loanAccountNumber
if (
System.currentTimeMillis() - apiCallLastTime <=
Constants.API_CALL_MULTI_CLICK_THRESOLD_DUR
)
return
showLoader()
NaviAnalytics.naviAnalytics.Payment().onPlPaymentInitiatePaymentCalled(loanType)
paymentVM.setIsPaymentLoaderShowing(true)
val data =
InitiatePaymentRequest(
loanAccountNumber,
com.navi.paymentclients.model.Amount(
value = amount.value,
currency = amount.currency,
symbol = amount.symbol
),
isPreClosure,
repaymentType,
sourceOfFunds,
otherSourceOfFunds,
partPrePaymentRescheduleType
)
paymentVM.initiatePayment(data)
}
private fun observePaymentListener() {
paymentVM.initPaymentResponse.observeNullable(this) { paymentResponse ->
hideLoader()
val paymentSdkInitParams =
PaymentSdkInitParams(
token = paymentResponse?.tokenDetails?.token.orEmpty(),
requestId = null,
mintToken = false,
paymentPreFetchMethodRequest =
PaymentPrefetchMethodRequest(
callSdkExitOnBack = false,
previousScreenName = PaymentSource.PL.name
),
screenType = FULL_PAYMENT_SCREEN,
paymentSource = PaymentSource.PL.name
)
naviCheckoutViewModel.initiatePayment(paymentSdkInitParams)
}
}
private fun observeInitiatePaymentStatus() {
lifecycleScope.launchWhenResumed {
naviCheckoutViewModel.paymentResponse.collect { data ->
if (data) {
NaviPaymentRouter.startPayment(
composePaymentsResultLauncher,
this@CustomPaymentActivity
)
}
}
}
}
private val composePaymentsResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == 0) return@registerForActivityResult
val status =
result
?.data
?.extras
?.getString(
com.navi.payment.utils.Constants.STATUS.uppercase(Locale.getDefault())
)
when (status) {
PaymentSdkTypes.DISMISS_LOADER.name -> Unit
PaymentSdkTypes.TRANSACTION_SUCCESS.name -> {
showLoader()
redirectToPaymentSuccessScreen()
}
else -> Unit
}
}
private fun redirectToPaymentSuccessScreen() {
val intent = Intent(this, FeedbackActivity::class.java)
intent.putExtra(LOAN_ACCOUNT_NUMBER, loanAccountNumber)
intent.putExtra(
LOAN_ACCOUNT_REQUEST_ID,
paymentVM.initPaymentResponse.value?.requestId.toString()
)
intent.putExtra(IS_SYNC_FLOW, true)
intent.putExtra(LOAN_TYPE, TYPE_PERSONAL_LOAN)
startActivity(intent)
finish()
}
}

View File

@@ -7,6 +7,7 @@
package com.naviapp.custom_payments.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -27,6 +28,7 @@ import com.navi.naviwidgets.widgets.BaseNaviWidgetLayout
import com.naviapp.R
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.fragment.InfoBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.custom_payments.view_models.CustomPaymentCalendarVM
import com.naviapp.databinding.FragmentCustomPaymentCalendarReviewBinding
import com.naviapp.part_prepayment.PartPrePaymentActivity
@@ -36,6 +38,7 @@ import com.naviapp.payment.activities.NaviPaymentActivity
import com.naviapp.payment.models.Amount
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@@ -47,6 +50,7 @@ class CustomPaymentCalendarReviewFragment :
ViewModelProvider(this).get(CustomPaymentCalendarVM::class.java)
}
private lateinit var binding: FragmentCustomPaymentCalendarReviewBinding
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreateView(
inflater: LayoutInflater,
@@ -63,6 +67,11 @@ class CustomPaymentCalendarReviewFragment :
return binding.root
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initError(customPaymentCalendarVM, actionErrorV2Enabled = true)
@@ -148,12 +157,21 @@ class CustomPaymentCalendarReviewFragment :
val symbol = firstOrNull { it.key == PartPrePaymentActivity.SYMBOL }?.value
val paymentType = firstOrNull { it.key == PartPrePaymentActivity.PAYMENT_TYPE }?.value
loanType = firstOrNull { it.key == Constants.LOAN_TYPE }?.value
startPayment(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
partPrePaymentRescheduleType = repaymentType,
paymentType = paymentType,
loanType = loanType
)
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData?.toDoubleOrNull(), currency, symbol),
repaymentType = paymentType,
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
startPayment(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
partPrePaymentRescheduleType = repaymentType,
paymentType = paymentType,
loanType = loanType
)
}
}
}

View File

@@ -7,6 +7,7 @@
package com.naviapp.custom_payments.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -33,6 +34,7 @@ import com.navi.naviwidgets.widgets.BaseNaviWidgetLayout
import com.naviapp.R
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.fragment.InfoBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.databinding.FragmentForecloseLoanBinding
import com.naviapp.network.ApiErrorTagType
import com.naviapp.part_prepayment.PartPrePaymentActivity
@@ -43,6 +45,7 @@ import com.naviapp.payment.fragments.PaymentType
import com.naviapp.payment.models.Amount
import com.naviapp.utils.CLOSURE_TYPE
import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import kotlinx.coroutines.launch
@@ -61,6 +64,7 @@ class ForecloseLoanFragment :
private var termsAndConditionsBottomSheet: BottomSheetInfo? = null
private var paymentFooterWidget: PaymentFooterWidget? = null
private var repaymentType: String? = null
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreateView(
inflater: LayoutInflater,
@@ -93,6 +97,11 @@ class ForecloseLoanFragment :
initObservers()
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
private fun initObservers() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
launch {
@@ -266,12 +275,20 @@ class ForecloseLoanFragment :
val currency = firstOrNull { it.key == PartPrePaymentActivity.CURRENCY }?.value
val symbol = firstOrNull { it.key == PartPrePaymentActivity.SYMBOL }?.value
loanType = firstOrNull { it.key == LOAN_TYPE }?.value
onPaymentClick(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
true,
repaymentType = repaymentType ?: PaymentType.SCHEDULED_PRE_CLOSURE.name,
loanType
)
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData?.toDoubleOrNull(), currency, symbol),
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
onPaymentClick(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
true,
repaymentType = repaymentType ?: PaymentType.SCHEDULED_PRE_CLOSURE.name,
loanType
)
}
}
}
}

View File

@@ -7,6 +7,7 @@
package com.naviapp.custom_payments.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -52,6 +53,7 @@ import com.naviapp.R
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.analytics.utils.NaviAnalytics.Companion.NORMAL_FLOW
import com.naviapp.common.fragment.InfoBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.custom_payments.view_models.LoanRepaymentTypeVM
import com.naviapp.databinding.FragmentLoanRepaymentOptionsBinding
import com.naviapp.part_prepayment.PartPrePaymentActivity
@@ -84,6 +86,7 @@ class LoanRepaymentOptionsFragment :
private var inputBinding: ViewDataBinding? = null
private var infoWithTimerV2WidgetBinding: ViewDataBinding? = null
private var loanTypeFromArgument = ""
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -110,6 +113,11 @@ class LoanRepaymentOptionsFragment :
return binding.root
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
init()
@@ -448,11 +456,21 @@ class LoanRepaymentOptionsFragment :
repaymentType = paymentType
)
}
initiatePayment(
amount = Amount(amountData.toDoubleOrNull(), currency, symbol),
isPreClosure = preClosure,
repaymentType = paymentType
)
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData.toDoubleOrNull(), currency, symbol),
isPreClosure = preClosure,
repaymentType = paymentType,
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
initiatePayment(
amount = Amount(amountData.toDoubleOrNull(), currency, symbol),
isPreClosure = preClosure,
repaymentType = paymentType
)
}
}
}
}

View File

@@ -7,6 +7,7 @@
package com.naviapp.custom_payments.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -44,6 +45,7 @@ import com.naviapp.analytics.utils.NaviAnalytics.Companion.COLENDING_BALANCE_TRA
import com.naviapp.analytics.utils.NaviAnalytics.Companion.ELIGIBLE_FOR_BALANCE_TRANSFER
import com.naviapp.analytics.utils.NaviAnalytics.Companion.FALSE
import com.naviapp.common.fragment.InfoBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.custom_payments.view_models.CustomPaymentTypeVM
import com.naviapp.databinding.FragmentRepaymentTypeBinding
import com.naviapp.network.ApiErrorTagType
@@ -59,6 +61,7 @@ import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.PART_PRE_PAYMENT
import com.naviapp.utils.Constants.SAVE_AGREEMENT
import com.naviapp.utils.Constants.TRUE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@@ -84,6 +87,7 @@ class RepaymentTypeFragment :
InitiateRescheduleLoanAgreementGenerationRequest? =
null
private var loanTypeFromArgument = ""
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreateView(
inflater: LayoutInflater,
@@ -128,6 +132,11 @@ class RepaymentTypeFragment :
init()
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
private fun init() {
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
launch { customPaymentTypeVM.widgetDataResponse.collect { setWidgetState(it) } }
@@ -339,12 +348,25 @@ class RepaymentTypeFragment :
val paymentType =
firstOrNull { it.key == PartPrePaymentActivity.PAYMENT_TYPE }?.value
loanType = firstOrNull { it.key == Constants.LOAN_TYPE }?.value
startPayment(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
partPrePaymentRescheduleType = type as? String,
paymentType = paymentType,
loanType = loanType
)
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData?.toDoubleOrNull(), currency, symbol),
repaymentType = paymentType,
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
startPayment(
Amount(
amountData?.toDoubleOrNull(),
currency = currency,
symbol = symbol
),
partPrePaymentRescheduleType = type as? String,
paymentType = paymentType,
loanType = loanType
)
}
}
}
}

View File

@@ -0,0 +1,23 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.custom_payments.listener
import com.naviapp.payment.models.Amount
interface InitiatePaymentListener {
fun initiatePayment(
amount: Amount,
isPreClosure: Boolean = false,
repaymentType: String? = null,
sourceOfFunds: String? = null,
otherSourceOfFunds: String? = null,
partPrePaymentRescheduleType: String? = null,
loanAccountNumber: String? = null,
loanType: String? = null
)
}

View File

@@ -19,6 +19,8 @@ import android.widget.Toast
import androidx.activity.SystemBarStyle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
@@ -46,7 +48,6 @@ import com.navi.base.utils.ConnectivityObserver
import com.navi.base.utils.ConnectivityObserverImpl
import com.navi.base.utils.DateUtils
import com.navi.base.utils.isNotNull
import com.navi.base.utils.isNotNullAndNotEmpty
import com.navi.base.utils.isNull
import com.navi.base.utils.orElse
import com.navi.base.utils.orFalse
@@ -86,7 +87,6 @@ import com.navi.common.utils.Constants.ScreenLockConstants.IS_SCREEN_LOCK_ENABLE
import com.navi.common.utils.TemporaryStorageHelper
import com.navi.common.utils.getDensityName
import com.navi.common.utils.getDeviceSignature
import com.navi.common.utils.getErrorData
import com.navi.common.utils.getInstalledDynamicModulesCommaSeparated
import com.navi.common.utils.getLocalStorageLocation
import com.navi.common.utils.getNetworkType
@@ -129,15 +129,16 @@ import com.navi.payment.model.initiatesdk.PaymentPrefetchMethodRequest
import com.navi.payment.model.paymentmethod.PaymentMethodResponse
import com.navi.payment.model.paymentmethod.PaymentScreenIntegrationMethodDetailResponse
import com.navi.payment.model.paymentresult.PaymentPrefetchMethodDetailsResponse
import com.navi.payment.nativepayment.router.NaviPaymentRouter
import com.navi.payment.nativepayment.sharedviewmodel.NaviCheckoutViewModel
import com.navi.payment.paymenthandler.model.PaymentRequest
import com.navi.payment.paymenthandler.model.PaymentStatusData
import com.navi.payment.paymentscreen.model.PaymentActivityResponse
import com.navi.payment.paymentscreen.model.PaymentInitiateConfig
import com.navi.payment.paymentscreen.ui.PaymentMethodSuccessFragment
import com.navi.payment.paymentscreen.utils.PaymentNavigator
import com.navi.payment.paymentscreen.viewmodel.PaymentScreenSharedViewModel
import com.navi.payment.utils.Constants.FULL_PAYMENT_SCREEN
import com.navi.payment.utils.Constants.PAYMENT_METHOD_REQUEST_CODE
import com.navi.payment.utils.PaymentAnalytics
import com.navi.payment.utils.PaymentSource
import com.navi.paymentclients.model.InitiatePaymentRequest as PMSInitiatePaymentRequest
import com.navi.paymentclients.viewmodel.base.PaymentManager
@@ -202,6 +203,7 @@ import com.naviapp.payment.models.InitiatePaymentRequest
import com.naviapp.payment.states.BottomSheetInfoV2State
import com.naviapp.payment.viewmodel.PaymentVM
import com.naviapp.personalloan.getloan.loandetails.fragments.DailyOfferBottomSheet
import com.naviapp.personalloanrevamp.common.utils.PaymentSdkResultUtil
import com.naviapp.personalloanrevamp.customview.DailyOfferBottomSheetV2
import com.naviapp.registration.helper.AppsFlyerDeeplinkHandler
import com.naviapp.registration.helper.isLocationPermissionGranted
@@ -227,6 +229,7 @@ import com.naviapp.utils.toast
import dagger.hilt.android.AndroidEntryPoint
import io.branch.referral.Branch
import java.lang.ref.WeakReference
import java.util.Locale
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
@@ -282,6 +285,8 @@ class HomePageActivity :
private val connectivityObserver: ConnectivityObserver by lazy {
ConnectivityObserverImpl(context = applicationContext)
}
private val naviCheckoutViewModel by viewModels<NaviCheckoutViewModel>()
private val naviAnalyticsWidgetEventTracker = NaviAnalytics.naviAnalytics.Widget()
private val userDataAnalyticsTracker = NaviAnalytics.naviAnalytics.UserData()
@@ -589,6 +594,7 @@ class HomePageActivity :
}
}
}
observeInitiatePaymentStatus()
}
private fun observeGIPaymentFailed() {
@@ -2104,50 +2110,33 @@ class HomePageActivity :
private fun observeInitPaymentRequestData() {
if (isEnabled() && paymentVM.initPaymentResponse.hasObservers()) return
paymentVM.initPaymentResponse.observeNullable(this) { data ->
paymentInitListener?.setPaymentSyncStatus(data?.syncFlow.orFalse())
if (data?.syncFlow.orFalse()) {
NaviAnalytics.naviAnalytics
.Payment()
.onPlPaymentTokenRecieved(
isValidToken = data?.tokenDetails?.token.isNotNullAndNotEmpty()
val paymentSdkInitParams =
PaymentSdkInitParams(
token = data?.tokenDetails?.token.orEmpty(),
requestId = null,
mintToken = false,
paymentPreFetchMethodRequest =
PaymentPrefetchMethodRequest(
callSdkExitOnBack = false,
previousScreenName = PaymentSource.PL.name
),
screenType = FULL_PAYMENT_SCREEN,
paymentSource = PaymentSource.PL.name
)
naviCheckoutViewModel.initiatePayment(paymentSdkInitParams)
}
}
private fun observeInitiatePaymentStatus() {
lifecycleScope.launch {
naviCheckoutViewModel.paymentResponse.collect { dataRecieved ->
if (dataRecieved) {
hideLoader()
NaviPaymentRouter.startPayment(
composePaymentsResultLauncher,
this@HomePageActivity
)
if (data?.tokenDetails?.token.isNullOrEmpty()) {
paymentVM.setErrorData(
listOf(
getErrorData(
context = this,
logMessage = "pl_${PaymentAnalytics.EMPTY_TOKEN_RECEIVED}"
)
)
)
} else {
this.repaymentType = data?.repaymentType.orEmpty()
this.notificationPath = data?.notificationPath.orEmpty()
paymentManager.init(
token = data?.tokenDetails?.token.orEmpty(),
activity = this,
listener = this,
requestId = data?.requestId,
initiatePaymentRequest = paymentVM.paymentInitiateRequest,
razorPaySDK = paymentInitListener?.getRazorPaySDK(),
optimisationDisable =
FirebaseRemoteConfigHelper.getBoolean(
FirebaseRemoteConfigHelper.PAYMENT_OPTIMISATION_DISABLE
),
paymentInitiateConfig = PaymentInitiateConfig.S2S_INTEGRATION
)
}
} else {
data?.requestId?.let {
firebaseInit(
it,
INIT_REPAYMENT,
data.notificationPath.orEmpty(),
data.repaymentType
)
apiPollInit(it, INIT_REPAYMENT, data.repaymentType)
}
}
}
@@ -2346,4 +2335,22 @@ class HomePageActivity :
}
}
}
private val composePaymentsResultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == 0) return@registerForActivityResult
val status =
result
?.data
?.extras
?.getString(
com.navi.payment.utils.Constants.STATUS.uppercase(Locale.getDefault())
)
PaymentSdkResultUtil.paymentSdkCallbackStatus(
status,
this,
loanAccountNumber,
paymentVM.initPaymentResponse.value?.requestId.toString()
)
}
}

View File

@@ -7,6 +7,7 @@
package com.naviapp.part_prepayment.fragments
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -27,6 +28,7 @@ import com.navi.naviwidgets.widgets.BaseNaviWidgetLayout
import com.naviapp.R
import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.fragment.InfoBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.databinding.FragmentPartPrePaymentEmiCalendarReviewBinding
import com.naviapp.part_prepayment.PartPrePaymentActivity
import com.naviapp.part_prepayment.states.GenericWidgetState
@@ -35,6 +37,7 @@ import com.naviapp.payment.activities.NaviPaymentActivity
import com.naviapp.payment.models.Amount
import com.naviapp.utils.Constants
import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
@@ -48,6 +51,8 @@ class PartPrePaymentEmiCalendarReviewFragment :
}
private lateinit var binding: FragmentPartPrePaymentEmiCalendarReviewBinding
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -70,6 +75,11 @@ class PartPrePaymentEmiCalendarReviewFragment :
init()
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
override fun onClick(naviClickAction: NaviClickAction, widgetId: String?) {
if (naviClickAction is CtaData) {
when (naviClickAction.url) {
@@ -103,12 +113,21 @@ class PartPrePaymentEmiCalendarReviewFragment :
val symbol = firstOrNull { it.key == PartPrePaymentActivity.SYMBOL }?.value
val paymentType = firstOrNull { it.key == PartPrePaymentActivity.PAYMENT_TYPE }?.value
loanType = firstOrNull() { it.key == Constants.LOAN_TYPE }?.value
startPayment(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
partPrePaymentRescheduleType = repaymentType,
paymentType = paymentType,
loanType = loanType
)
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData?.toDoubleOrNull(), currency, symbol),
repaymentType = paymentType,
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
startPayment(
Amount(amountData?.toDoubleOrNull(), currency = currency, symbol = symbol),
partPrePaymentRescheduleType = repaymentType,
paymentType = paymentType,
loanType = loanType
)
}
}
}

View File

@@ -9,6 +9,7 @@ package com.naviapp.payment_behaviour.fragments
import android.animation.Animator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Color
import android.media.MediaPlayer
import android.os.Bundle
@@ -62,6 +63,7 @@ import com.naviapp.common.fragment.InfoBottomSheetV3
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.custom_payments.fragments.PaymentFooterBottomSheet
import com.naviapp.custom_payments.fragments.PaymentFooterBottomSheetListener
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.databinding.FragmentPaymentBehaviourBinding
import com.naviapp.databinding.LayoutAnimatedTextWithLoaderFullScreenViewBinding
import com.naviapp.part_prepayment.PartPrePaymentActivity
@@ -102,6 +104,7 @@ class PaymentBehaviourFragment :
widgetCallback = this,
factory = ViewHolderFactoryImpl()
)
private lateinit var initiatePaymentListener: InitiatePaymentListener
override fun onCreateView(
inflater: LayoutInflater,
@@ -120,6 +123,11 @@ class PaymentBehaviourFragment :
init()
}
override fun onAttach(context: Context) {
super.onAttach(context)
initiatePaymentListener = context as InitiatePaymentListener
}
override fun widgetAnalytics(genericAnalyticsData: GenericAnalyticsData?) {
NaviAnalytics.naviAnalytics.sendGenericAnalyticsData(genericAnalyticsData, screenName)
}
@@ -533,7 +541,15 @@ class PaymentBehaviourFragment :
amount = Amount(amountData.toDoubleOrNull(), currency, symbol)
)
}
initiatePayment(amount = Amount(amountData.toDoubleOrNull(), currency, symbol))
if (loanType == TYPE_PERSONAL_LOAN && ::initiatePaymentListener.isInitialized) {
initiatePaymentListener.initiatePayment(
amount = Amount(amountData.toDoubleOrNull(), currency, symbol),
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
initiatePayment(amount = Amount(amountData.toDoubleOrNull(), currency, symbol))
}
}
}
}

View File

@@ -45,6 +45,7 @@ import com.naviapp.analytics.utils.NaviAnalytics
import com.naviapp.common.listeners.FooterInteractionListener
import com.naviapp.common.listeners.KeyValueListener
import com.naviapp.common.navigator.NaviDeepLinkNavigator
import com.naviapp.custom_payments.listener.InitiatePaymentListener
import com.naviapp.dashboard.listeners.FragmentInteractionListener
import com.naviapp.databinding.EmiDateChangeFragmentBinding
import com.naviapp.models.AnimationData
@@ -84,6 +85,7 @@ class EMIDateChangeFragment : PaymentBaseFragment(), FooterInteractionListener {
private val viewModel by lazy {
ViewModelProvider(this).get(EMIDateChangeFragmentVM::class.java)
}
private lateinit var initiatePaymentListener: InitiatePaymentListener
override val screenName: String
get() = TAG
@@ -93,6 +95,7 @@ class EMIDateChangeFragment : PaymentBaseFragment(), FooterInteractionListener {
headerInteractionListener = context as? HeaderInteractionListener
listener = context as? FragmentInteractionListener
fragmentInterchangeListener = context as? FragmentInterchangeListener
initiatePaymentListener = context as InitiatePaymentListener
}
override fun onDetach() {
@@ -494,10 +497,30 @@ class EMIDateChangeFragment : PaymentBaseFragment(), FooterInteractionListener {
)
)
}
initiatePayment(
amount =
Amount(amountData.toDoubleOrNull(), currency, symbol)
)
if (
loanType == TYPE_PERSONAL_LOAN &&
::initiatePaymentListener.isInitialized
) {
initiatePaymentListener.initiatePayment(
amount =
Amount(
amountData.toDoubleOrNull(),
currency,
symbol
),
loanAccountNumber = loanAccountNumber,
loanType = loanType
)
} else {
initiatePayment(
amount =
Amount(
amountData.toDoubleOrNull(),
currency,
symbol
)
)
}
}
}
CtaType.CLOSE_BOTTOM_SHEET.name -> {

View File

@@ -0,0 +1,49 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.personalloanrevamp.common.utils
import android.content.Intent
import com.navi.payment.model.common.PaymentSdkTypes
import com.naviapp.home.compose.activity.HomePageActivity
import com.naviapp.payment.activities.FeedbackActivity
import com.naviapp.utils.Constants.LOAN_TYPE
import com.naviapp.utils.Constants.TYPE_PERSONAL_LOAN
import com.naviapp.utils.IS_SYNC_FLOW
import com.naviapp.utils.LOAN_ACCOUNT_NUMBER
import com.naviapp.utils.LOAN_ACCOUNT_REQUEST_ID
object PaymentSdkResultUtil {
fun paymentSdkCallbackStatus(
status: String?,
activity: HomePageActivity,
loanAccountNumber: String?,
requestId: String
) {
when (status) {
PaymentSdkTypes.DISMISS_LOADER.name -> Unit
PaymentSdkTypes.TRANSACTION_SUCCESS.name -> {
redirectToPaymentSuccessScreen(activity, loanAccountNumber, requestId)
}
else -> Unit
}
}
private fun redirectToPaymentSuccessScreen(
activity: HomePageActivity,
loanAccountNumber: String?,
requestId: String
) {
val intent = Intent(activity, FeedbackActivity::class.java)
intent.putExtra(LOAN_ACCOUNT_NUMBER, loanAccountNumber)
intent.putExtra(LOAN_ACCOUNT_REQUEST_ID, requestId)
intent.putExtra(IS_SYNC_FLOW, true)
intent.putExtra(LOAN_TYPE, TYPE_PERSONAL_LOAN)
activity.startActivity(intent)
}
}

View File

@@ -66,8 +66,6 @@ import com.navi.payment.paymentscreen.utils.PaymentScreenUtil
import com.navi.payment.paymentscreen.viewmodel.PaymentLoaderUiState
import com.navi.payment.paymentscreen.viewmodel.PaymentLoaderViewModel
import com.navi.payment.paymentscreen.viewmodel.PaymentScreenSharedViewModel
import com.navi.payment.utils.Constants.CHANNEL_PL
import com.navi.payment.utils.Constants.CLIENT
import com.navi.payment.utils.Constants.CLIENT_STATUS_POLL_API_FAILURE
import com.navi.payment.utils.Constants.FLOW_PAYMENT_LOADER_RESPONSE
import com.navi.payment.utils.Constants.KEY_CTA_URL
@@ -216,13 +214,7 @@ class PaymentLoaderFragment : PaymentScreenBaseFragment(), PaymentBackListener {
if (response.clientPollRequired.orTrue()) {
// The below check is for legacy handling, going forward clients need to
// handle the client polling to their BE
if (
viewModel.loaderScreenBundleData.value
?.paymentSource
?.equals(CHANNEL_PL, true) == true
) {
apiPollInitForClientOrderStatus(type = CLIENT)
} else if (response.data?.metadata == null) {
if (response.data?.metadata == null) {
postResultAndFinish(response.data, TRANSACTION_SUCCESS)
} else {
showPaymentSuccessLoader(