TP-62796 | Payment migration (#10380)
Co-authored-by: Prajjaval Verma <prajjaval.verma@navi.com>
This commit is contained in:
committed by
GitHub
parent
9885c977be
commit
eb2ddb355c
@@ -266,6 +266,12 @@
|
||||
android:exported="false"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name=".paymentreview.autopayoption.ui.PaymentStatusActivity"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/GiAppThemeBlue" />
|
||||
|
||||
<activity
|
||||
android:name=".notifications.DeepLinkActivity"
|
||||
android:exported="true"
|
||||
|
||||
@@ -391,5 +391,6 @@ class NavigationHandler @Inject constructor(private val uiControllerUtil: UiCont
|
||||
const val HEADER_WITH_ITEMS_AND_FOOTER_BOTTOM_SHEET = "header_with_items_and_footer_bottomsheet"
|
||||
const val CHECKBOX_WITH_DROPDOWN_BOTTOMSHEET = "checkbox_with_dropdown_bottomsheet"
|
||||
const val TRIAL_INFO_BOTTOM_SHEET = "trial_info_bottom_sheet"
|
||||
const val URL_PAYMENT_STATUS_SCREEN = "payment_status_screen"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,10 @@ constructor(context: Context, attrs: AttributeSet? = null) : BaseNaviWidgetView(
|
||||
}
|
||||
}
|
||||
|
||||
fun showLoader(boolean: Boolean){
|
||||
binding?.loadingButton?.isVisible = boolean
|
||||
}
|
||||
|
||||
override fun enableLayout(isEnabled: Boolean, showLoader: Boolean) {
|
||||
if (isEnabled) {
|
||||
binding?.button?.enableView()
|
||||
|
||||
@@ -16,6 +16,7 @@ import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.CtaType
|
||||
@@ -31,15 +32,18 @@ import com.navi.insurance.databinding.ActivityInsuranceContainerBinding
|
||||
import com.navi.insurance.health.viewmodel.InsuranceContainerActivityVM
|
||||
import com.navi.insurance.navigator.NaviInsuranceDeeplinkNavigator
|
||||
import com.navi.insurance.payment.PaymentStatusBottomSheet
|
||||
import com.navi.insurance.paymentreview.autopayoption.ui.PaymentReviewFragment
|
||||
import com.navi.insurance.paymentreview.autopayoption.ui.PaymentStatusListener
|
||||
import com.navi.insurance.util.AMOUNT
|
||||
import com.navi.insurance.util.Constants
|
||||
import com.navi.naviwidgets.utils.PAN_VERIFICATION_REQUEST_CODE
|
||||
import com.navi.payment.utils.Constants.PAYMENT_METHOD_REQUEST_CODE
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import com.navi.insurance.R as NaviR
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class InsuranceContainerActivity : GiBaseActivity(), PaymentStatusBottomSheetListener {
|
||||
class InsuranceContainerActivity : GiBaseActivity(), PaymentStatusBottomSheetListener, PaymentStatusListener {
|
||||
|
||||
private lateinit var binding: ActivityInsuranceContainerBinding
|
||||
private val viewModel by viewModels<InsuranceContainerActivityVM>()
|
||||
@@ -64,11 +68,15 @@ class InsuranceContainerActivity : GiBaseActivity(), PaymentStatusBottomSheetLis
|
||||
)
|
||||
return
|
||||
}
|
||||
if (requestCode == PAYMENT_METHOD_REQUEST_CODE) {
|
||||
val fragment = supportFragmentManager.findFragmentByTag(PaymentReviewFragment.TAG)
|
||||
fragment?.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
if (requestCode == Constants.PAYMENT_ACTIVITY_REQUEST_CODE) {
|
||||
val paymentCta = viewModel.paymentRetryCta.value
|
||||
|
||||
val amountToPay =
|
||||
paymentCta?.parameters?.find { item -> item.key == AMOUNT }?.value?.toDoubleWithSafe()
|
||||
(paymentCta?.parameters?.find { item -> item.key == AMOUNT }?.value?:data?.getStringExtra(AMOUNT))?.toDoubleWithSafe()
|
||||
if (resultCode == RESULT_OK) {
|
||||
// Payment success, close activity
|
||||
finish()
|
||||
@@ -185,4 +193,44 @@ class InsuranceContainerActivity : GiBaseActivity(), PaymentStatusBottomSheetLis
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setPaymentResult(resultCode: Int, isCancelledByUser: Boolean, ctaData: CtaData?, bundle: Bundle?) {
|
||||
ctaData?.let { cta ->
|
||||
cta.analyticsEventProperties?.let { analyticsEvent ->
|
||||
NaviInsuranceAnalytics.postAnalyticsEvent(analyticsEvent.name.orEmpty(), analyticsEvent.properties)
|
||||
}
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity = this,
|
||||
ctaData = cta,
|
||||
finish = cta.finish.orFalse(),
|
||||
clearTask = cta.clearTask.orFalse()
|
||||
)
|
||||
return
|
||||
}
|
||||
val paymentCta = viewModel.paymentRetryCta.value
|
||||
|
||||
val amountToPay =
|
||||
(paymentCta?.parameters?.find { item -> item.key == AMOUNT }?.value?:bundle?.getString(AMOUNT))?.toDoubleWithSafe()
|
||||
if (resultCode == RESULT_OK) {
|
||||
// Payment success, close activity
|
||||
finish()
|
||||
} else {
|
||||
// Payment failed, show retry dialog
|
||||
viewModel.paymentFallbackCta?.let {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
this,
|
||||
it,
|
||||
finish = it.finish.orFalse(),
|
||||
clearTask = it.clearTask.orFalse()
|
||||
)
|
||||
} ?: run {
|
||||
PaymentStatusBottomSheet.getInstance(
|
||||
this,
|
||||
amountToPay,
|
||||
isCancelledByUser
|
||||
)
|
||||
.show(supportFragmentManager, PaymentStatusBottomSheet.TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.navi.common.network.retrofit.ResponseCallback
|
||||
import com.navi.insurance.models.AutoPayInitMandateResponse
|
||||
import com.navi.insurance.models.PaymentOrderDetail
|
||||
import com.navi.insurance.models.PaymentStateResponse
|
||||
import com.navi.insurance.models.TurboPaymentOrderDetail
|
||||
import com.navi.insurance.models.request.AutoPayHashRequest
|
||||
import com.navi.insurance.models.request.InitiateInstallmentPaymentRequest
|
||||
import com.navi.insurance.models.request.InitiatePaymentRequest
|
||||
@@ -54,6 +55,26 @@ class PaymentRepository @Inject constructor(private val retrofitService: Retrofi
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun initiatePaymentForInstallmentV2(
|
||||
policyId: String, request: InitiateInstallmentPaymentRequest
|
||||
): RepoResult<TurboPaymentOrderDetail> {
|
||||
return apiResponseCallback(
|
||||
retrofitService.initiatePaymentForInstallmentV2(policyId, request)
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun getPaymentStatusForCustomerV2(
|
||||
orderReferenceId: String,
|
||||
clientStatus: String?,
|
||||
pgClientStatus: String? = null,
|
||||
flowIdentifier: String?,
|
||||
policyId: String?
|
||||
) = apiResponseCallback(
|
||||
retrofitService.getPaymentStatusForCustomerV2(
|
||||
orderReferenceId, clientStatus, pgClientStatus, flowIdentifier, policyId
|
||||
)
|
||||
)
|
||||
|
||||
suspend fun generateHash(request: PaymentHashRequest) =
|
||||
apiResponseCallback<PaymentHashResponse>(retrofitService.generateHash(request))
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@
|
||||
|
||||
package com.navi.insurance.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.base.model.AnalyticsEvent
|
||||
import com.navi.base.model.CtaData
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
data class PaymentOrderDetail(
|
||||
@SerializedName("errorStateData") val errorStateData: ErrorStateData? = null,
|
||||
@@ -20,7 +22,7 @@ data class PaymentOrderDetail(
|
||||
@SerializedName("requestId") val requestId: String? = null,
|
||||
@SerializedName("quoteMetadata") val quoteMetaData: QuoteMetaData? = null,
|
||||
@SerializedName("paymentStatusAnalyticsEvents")
|
||||
var paymentStatusAnalyticsEvents: PaymentStatusAnalyticsEvents? = null
|
||||
var paymentStatusAnalyticsEvents: PaymentStatusAnalyticsEvents? = null,
|
||||
) {
|
||||
data class ErrorStateData(
|
||||
@SerializedName("errorMessage") val errorMessage: String? = null,
|
||||
@@ -28,6 +30,23 @@ data class PaymentOrderDetail(
|
||||
)
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class TurboPaymentOrderDetail(
|
||||
@SerializedName("requestId") val requestId: String? = null,
|
||||
@SerializedName("orderReferenceId") val orderReferenceId: String? = null,
|
||||
@SerializedName("paymentSdkToken") val paymentSdkToken: String? = null,
|
||||
@SerializedName("pollingConfig") val pollingConfig: PollingConfig,
|
||||
@SerializedName("nextPageCta") val nextPageCta: CtaData? = null,
|
||||
@SerializedName("apiFailureCta") val apiFailureCta: CtaData? = null
|
||||
) : Parcelable {
|
||||
@Parcelize
|
||||
data class PollingConfig(
|
||||
@SerializedName("initialDelay") val initialDelay: Long? = null,
|
||||
@SerializedName("pollingInterval") val pollingInterval: Long? = null,
|
||||
@SerializedName("maxNumberOfRetries") val maxNumberOfRetries: Int? = null
|
||||
) : Parcelable
|
||||
}
|
||||
|
||||
data class BillingDetails(
|
||||
val billingAmount: Double? = null,
|
||||
val currency: String? = null,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.navi.insurance.models.response
|
||||
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.navi.naviwidgets.models.LottieFieldData
|
||||
import com.navi.naviwidgets.models.response.TextFieldData
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class PaymentStatusScreenResponse(
|
||||
@SerializedName("lottieFieldData")
|
||||
val lottieFieldData: LottieFieldData? = null,
|
||||
@SerializedName("subTitle")
|
||||
val subTitle: TextFieldData? = null,
|
||||
@SerializedName("title")
|
||||
val title: TextFieldData? = null
|
||||
) : Parcelable
|
||||
@@ -119,6 +119,7 @@ import com.navi.insurance.health.fragment.UpdatedPremiumBottomSheet
|
||||
import com.navi.insurance.notifications.Screen
|
||||
import com.navi.insurance.payment.PaymentStatusBottomSheet
|
||||
import com.navi.insurance.payment.activity.PaymentReviewActivity
|
||||
import com.navi.insurance.paymentreview.autopayoption.ui.PaymentStatusActivity
|
||||
import com.navi.insurance.quoteredesign.QuoteActivity
|
||||
import com.navi.insurance.quoteredesign.fragments.QuotePremiumDetailsBottomSheet
|
||||
import com.navi.insurance.renewal.RenewalActivity
|
||||
@@ -476,6 +477,9 @@ object NaviInsuranceDeeplinkNavigator {
|
||||
intent = Intent(activity, PaymentActivity::class.java)
|
||||
bundle.putString(EXTRA_FROM, TAG)
|
||||
}
|
||||
NavigationHandler.URL_PAYMENT_STATUS_SCREEN -> {
|
||||
intent = Intent(activity, PaymentStatusActivity::class.java)
|
||||
}
|
||||
NavigationHandler.URL_PAYMENT_REVIEW_ACTIVITY -> {
|
||||
intent = Intent(activity, PaymentReviewActivity::class.java)
|
||||
}
|
||||
|
||||
@@ -111,6 +111,12 @@ interface RetrofitService {
|
||||
@Body data: InitiateInstallmentPaymentRequest
|
||||
): Response<GenericResponse<PaymentOrderDetail>>
|
||||
|
||||
@POST("/v2/payment/{policyId}/initiate")
|
||||
suspend fun initiatePaymentForInstallmentV2(
|
||||
@Path("policyId") policyId: String,
|
||||
@Body data: InitiateInstallmentPaymentRequest
|
||||
): Response<GenericResponse<TurboPaymentOrderDetail>>
|
||||
|
||||
@GET("/v1/payment/status")
|
||||
suspend fun getPaymentStatusV1(
|
||||
@Query("paymentReferenceId") paymentReferenceId: String,
|
||||
@@ -120,6 +126,15 @@ interface RetrofitService {
|
||||
@Query("flowIdentifier") flowIdentifier: String?
|
||||
): Response<GenericResponse<PaymentStateResponse>>
|
||||
|
||||
@GET("/v2/payment/{orderReferenceId}/status")
|
||||
suspend fun getPaymentStatusForCustomerV2(
|
||||
@Path("orderReferenceId") orderReferenceId: String,
|
||||
@Query("clientStatus") clientStatus: String?,
|
||||
@Query("pgClientStatus") pgClientStatus: String? = null,
|
||||
@Query("flowIdentifier") flowIdentifier: String?,
|
||||
@Query("policyId") policyId: String?,
|
||||
): Response<GenericResponse<PaymentStateResponse>>
|
||||
|
||||
@GET("/payment/{policyId}/status")
|
||||
suspend fun getPaymentStatusForInstallment(
|
||||
@Path("policyId") policyId: String,
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
package com.navi.insurance.paymentreview.autopayoption.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.children
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navi.base.model.*
|
||||
import com.navi.base.deeplink.DeepLinkManager
|
||||
import com.navi.base.model.AnalyticsEvent
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.base.model.CtaType
|
||||
import com.navi.base.model.NaviClickAction
|
||||
import com.navi.base.utils.isNull
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.common.ResponseState
|
||||
@@ -19,36 +32,51 @@ import com.navi.common.network.models.ErrorMessage
|
||||
import com.navi.design.utils.isValidHexColor
|
||||
import com.navi.insurance.R
|
||||
import com.navi.insurance.analytics.InsuranceAnalyticsConstants
|
||||
import com.navi.insurance.analytics.NaviInsuranceAnalytics
|
||||
import com.navi.insurance.common.GiBaseFragment
|
||||
import com.navi.insurance.common.GiBaseVM
|
||||
import com.navi.insurance.common.models.NaviWidgetData
|
||||
import com.navi.insurance.common.util.IdProvider
|
||||
import com.navi.insurance.common.widgets.BaseNaviWidgetView
|
||||
import com.navi.insurance.common.widgets.FooterWithTitleAndSubtitleLayout
|
||||
import com.navi.insurance.common.widgets.replaceLayout
|
||||
import com.navi.insurance.databinding.LayoutPaymentReviewFragmentBinding
|
||||
import com.navi.insurance.health.activity.BaseActivity
|
||||
import com.navi.insurance.health.activity.InsuranceContainerActivity
|
||||
import com.navi.insurance.health.viewmodel.InsuranceContainerActivityVM
|
||||
import com.navi.insurance.models.request.InitiateInstallmentPaymentRequest
|
||||
import com.navi.insurance.navigator.NaviInsuranceDeeplinkNavigator
|
||||
import com.navi.insurance.network.ApiErrorTagType
|
||||
import com.navi.insurance.paymentreview.autopayoption.viewmodel.PaymentInitState
|
||||
import com.navi.insurance.paymentreview.autopayoption.viewmodel.PaymentReviewVM
|
||||
import com.navi.insurance.util.*
|
||||
import com.navi.naviwidgets.adapters.NaviAdapter
|
||||
import com.navi.naviwidgets.callbacks.WidgetCallback
|
||||
import com.navi.naviwidgets.extensions.FloatingButtonOverlay
|
||||
import com.navi.naviwidgets.extensions.getJsonObject
|
||||
import com.navi.naviwidgets.extensions.setTextFieldData
|
||||
import com.navi.naviwidgets.models.GenericWidgetDataInfo
|
||||
import com.navi.naviwidgets.models.WidgetChangedData
|
||||
import com.navi.naviwidgets.models.response.TextFieldData
|
||||
import com.navi.naviwidgets.utils.UPDATE_WIDGET_DATA
|
||||
import com.navi.naviwidgets.viewholder.ViewHolderFactoryImpl
|
||||
import com.navi.naviwidgets.views.NaviErrorPageView
|
||||
import com.navi.payment.listener.PaymentResultListener
|
||||
import com.navi.payment.model.common.GenericErrorResponse
|
||||
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.paymenthandler.model.ClientScreenOwner
|
||||
import com.navi.payment.paymentscreen.utils.PaymentNavigator
|
||||
import com.navi.payment.utils.PaymentSource
|
||||
import com.navi.paymentclients.viewmodel.base.PaymentManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.set
|
||||
import com.navi.payment.utils.Constants as PaymentConstants
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
@@ -62,34 +90,70 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
private var applicationType: String? = null
|
||||
private var eventName: String? = null
|
||||
private var parentActivity: InsuranceContainerActivity? = null
|
||||
private val paymentManager: PaymentManager by lazy { ViewModelProvider(this)[PaymentManager::class.java] }
|
||||
private var amount = "0"
|
||||
|
||||
@Inject
|
||||
lateinit var idProvider: IdProvider
|
||||
|
||||
@Inject
|
||||
lateinit var paymentNavigator: PaymentNavigator
|
||||
|
||||
private var paymentStatusListener: PaymentStatusListener? = null
|
||||
|
||||
val paymentsResultLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
val status = data?.extras?.getString(Constants.STATUS.uppercase(Locale.getDefault()))
|
||||
when (status) {
|
||||
PaymentSdkTypes.DISMISS_LOADER.name -> {}
|
||||
|
||||
PaymentSdkTypes.TRANSACTION_SUCCESS.name, PaymentSdkTypes.TRANSACTION_FAILURE.name, PaymentSdkTypes.TRANSACTION_PENDING.name -> {
|
||||
activity?.let { activity ->
|
||||
DeepLinkManager.getDeepLinkListener()?.navigateTo(
|
||||
activity,
|
||||
(viewModel.paymentInitState.value as? PaymentInitState.Success)?.data?.nextPageCta ?: CtaData(),
|
||||
false,
|
||||
bundleOf(
|
||||
Pair(PAYMENT_FLOW_IDENTIFIER, arguments?.getString(PAYMENT_FLOW_IDENTIFIER)),
|
||||
Pair(PAYMENT_ORDER_DETAIL, (viewModel.paymentInitState.value as? PaymentInitState.Success)?.data),
|
||||
Pair(Constants.POLICY_ID, id),
|
||||
Pair(AMOUNT, amount)
|
||||
),
|
||||
requestCode = BaseActivity.GI_REQUEST_CODE,
|
||||
clearTask = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
paymentStatusListener = context as? PaymentStatusListener
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding =
|
||||
DataBindingUtil.inflate(
|
||||
inflater,
|
||||
R.layout.layout_payment_review_fragment,
|
||||
container,
|
||||
false
|
||||
)
|
||||
rvAdapter =
|
||||
NaviAdapter(
|
||||
widgetCallback = this,
|
||||
factory = ViewHolderFactoryImpl(),
|
||||
list = listOf(),
|
||||
isRecyclable = true
|
||||
)
|
||||
binding = DataBindingUtil.inflate(
|
||||
inflater, R.layout.layout_payment_review_fragment, container, false
|
||||
)
|
||||
rvAdapter = NaviAdapter(
|
||||
widgetCallback = this,
|
||||
factory = ViewHolderFactoryImpl(),
|
||||
list = listOf(),
|
||||
isRecyclable = true
|
||||
)
|
||||
id = arguments?.getString(ID)
|
||||
applicationType = arguments?.getString(APPLICATION_TYPE_EXTRA)
|
||||
?: run { activity?.intent?.getStringExtra(APPLICATION_TYPE_EXTRA) }
|
||||
eventName = arguments?.getString(EVENT_NAME_EXTRA)
|
||||
?: run { activity?.intent?.getStringExtra(EVENT_NAME_EXTRA) }
|
||||
applicationType = arguments?.getString(APPLICATION_TYPE_EXTRA) ?: run {
|
||||
activity?.intent?.getStringExtra(APPLICATION_TYPE_EXTRA)
|
||||
}
|
||||
eventName = arguments?.getString(EVENT_NAME_EXTRA) ?: run {
|
||||
activity?.intent?.getStringExtra(EVENT_NAME_EXTRA)
|
||||
}
|
||||
sendInitScreenEvent()
|
||||
paymentFlowIdentifier = arguments?.getString(PAYMENT_FLOW_IDENTIFIER)
|
||||
parentActivity = activity as? InsuranceContainerActivity
|
||||
@@ -109,6 +173,7 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initErrorView()
|
||||
observeResponse()
|
||||
addObservers()
|
||||
}
|
||||
|
||||
private fun initErrorView() {
|
||||
@@ -158,8 +223,7 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
}
|
||||
paymentReviewResponse.header?.getOrNull(0)?.widgetData?.let {
|
||||
updateContainer(
|
||||
it,
|
||||
binding.headerContainer
|
||||
it, binding.headerContainer
|
||||
)
|
||||
}
|
||||
if (paymentReviewResponse.content?.isEmpty() == false) {
|
||||
@@ -168,8 +232,7 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
paymentReviewResponse.footer?.getOrNull(0)?.widgetData?.let {
|
||||
footerData = it
|
||||
updateContainer(
|
||||
it,
|
||||
binding.footerContainer
|
||||
it, binding.footerContainer
|
||||
)
|
||||
}
|
||||
paymentReviewResponse.floatingButtonData?.let { fbButtonData ->
|
||||
@@ -197,9 +260,7 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
}
|
||||
|
||||
private fun updateContainer(
|
||||
naviWidgetData: NaviWidgetData,
|
||||
container: ViewGroup,
|
||||
clickableData: CtaData? = null
|
||||
naviWidgetData: NaviWidgetData, container: ViewGroup, clickableData: CtaData? = null
|
||||
) {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
val binding = container.replaceLayout(idProvider.getNaviWidgetLayoutId(naviWidgetData))
|
||||
@@ -216,34 +277,45 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
CtaType.HELP_BOTTOM_SHEET.value -> {
|
||||
openHelpCenter()
|
||||
}
|
||||
|
||||
CtaType.OPTION_SELECTED.value -> {
|
||||
handleFallBackCta(it)
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity,
|
||||
ctaData = it,
|
||||
finish = false,
|
||||
needsResult = true,
|
||||
requestCode = Constants.PAYMENT_ACTIVITY_REQUEST_CODE,
|
||||
callbackHandler = object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
if (it.parameters?.firstOrNull { params -> params.key == Constants.IS_TURBO_CHECKOUT }?.value.toBoolean()
|
||||
&& it.parameters?.firstOrNull {params -> params.key == Constants.IS_AUTOPAY }?.value.toBoolean().not()) {
|
||||
val policyId = getParameterFromCta(it, Constants.POLICY_ID)
|
||||
val request = InitiateInstallmentPaymentRequest(
|
||||
installmentNumber = getParameterFromCta(it, Constants.INSTALMENT_NUMBER)?.toInt(),
|
||||
paymentType = getParameterFromCta(it, Constants.PAYMENT_TYPE),
|
||||
installmentDate = getParameterFromCta(it, Constants.INSTALMENT_DATE),
|
||||
clientSuggestedPaymentProvider = null,
|
||||
)
|
||||
viewModel.initiatePayment(request, policyId.orEmpty())
|
||||
}
|
||||
else{
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity,
|
||||
ctaData = it,
|
||||
finish = false,
|
||||
needsResult = true,
|
||||
requestCode = Constants.PAYMENT_ACTIVITY_REQUEST_CODE,
|
||||
callbackHandler = object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
else ->
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity = activity,
|
||||
ctaData = it,
|
||||
bundle = Bundle(),
|
||||
finish = it.finish.orFalse(),
|
||||
clearTask = it.clearTask.orFalse(),
|
||||
callbackHandler = object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
}
|
||||
else -> NaviInsuranceDeeplinkNavigator.navigate(activity = activity,
|
||||
ctaData = it,
|
||||
bundle = Bundle(),
|
||||
finish = it.finish.orFalse(),
|
||||
clearTask = it.clearTask.orFalse(),
|
||||
callbackHandler = object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
(binding?.root as? BaseNaviWidgetView)?.setClickData(clickableData)
|
||||
@@ -255,8 +327,7 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
if (keyValue.key == Constants.PAYMENT_FALLBACK_CTA) {
|
||||
val dataType = object : TypeToken<CtaData>() {}.type
|
||||
val fallBackCta = getJsonObject<CtaData>(
|
||||
dataType,
|
||||
keyValue.value
|
||||
dataType, keyValue.value
|
||||
)
|
||||
activityViewModel.paymentFallbackCta = fallBackCta
|
||||
}
|
||||
@@ -281,6 +352,9 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
if (it.key == Constants.UPDATED_WIDGET_DATA) {
|
||||
data = it.value.toString()
|
||||
}
|
||||
if(it.key == AMOUNT){
|
||||
amount = it.value.toString()
|
||||
}
|
||||
}
|
||||
position?.let { itemPosition ->
|
||||
if (!binding.landingPageRv.isComputingLayout) {
|
||||
@@ -292,10 +366,8 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
// Retry the update later when the RecyclerView is in a stable state
|
||||
binding.landingPageRv.post {
|
||||
rvAdapter?.notifyItemChanged(
|
||||
itemPosition,
|
||||
WidgetChangedData(
|
||||
widgetAction = UPDATE_WIDGET_DATA,
|
||||
payload = data
|
||||
itemPosition, WidgetChangedData(
|
||||
widgetAction = UPDATE_WIDGET_DATA, payload = data
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -303,15 +375,13 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
}
|
||||
footerData?.let {
|
||||
updateContainer(
|
||||
it,
|
||||
binding.footerContainer,
|
||||
naviClickAction as? CtaData
|
||||
it, binding.footerContainer, naviClickAction as? CtaData
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CtaType.OPEN_PAYMENT.value -> {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity,
|
||||
NaviInsuranceDeeplinkNavigator.navigate(activity,
|
||||
naviClickAction,
|
||||
finish = naviClickAction.finish.orFalse(),
|
||||
clearTask = naviClickAction.clearTask.orFalse(),
|
||||
@@ -321,25 +391,114 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
else -> {
|
||||
NaviInsuranceDeeplinkNavigator.navigate(
|
||||
activity = activity,
|
||||
NaviInsuranceDeeplinkNavigator.navigate(activity = activity,
|
||||
ctaData = naviClickAction,
|
||||
bundle = bundle,
|
||||
callbackHandler = object : RequestToCallbackHandler {
|
||||
override fun onCallbackRaised() {
|
||||
viewModel.fetchPaymentReview(id, paymentFlowIdentifier)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addObservers() {
|
||||
lifecycleScope.launch {
|
||||
viewModel.paymentInitState.collect {
|
||||
binding.root.isClickable = it !is PaymentInitState.Loading
|
||||
when (it) {
|
||||
is PaymentInitState.Loading -> {
|
||||
viewModel.loadingScreen.value = true
|
||||
}
|
||||
|
||||
is PaymentInitState.Error -> {
|
||||
viewModel.loadingScreen.value = false
|
||||
}
|
||||
|
||||
is PaymentInitState.Success -> {
|
||||
initPaymentSDK(
|
||||
it.data.requestId.orEmpty(), it.data.paymentSdkToken.orEmpty(), it.data.nextPageCta
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
viewModel.loadingScreen.observeNonNull(this) {
|
||||
if (it) {
|
||||
binding.transparentLayout.visibility = View.VISIBLE
|
||||
(binding.footerContainer.children.first() as? FooterWithTitleAndSubtitleLayout)?.showLoader(
|
||||
true
|
||||
)
|
||||
} else {
|
||||
binding.transparentLayout.visibility = View.GONE
|
||||
(binding.footerContainer.children.first() as? FooterWithTitleAndSubtitleLayout)?.showLoader(
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
viewModel.errorResponse.observeNonNull(this) {
|
||||
paymentStatusListener?.setPaymentResult(Activity.RESULT_CANCELED, false, bundle = bundleOf(Pair(AMOUNT, amount)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initPaymentSDK(requestId: String, token: String, nextPageCta: CtaData?) {
|
||||
val paymentSdkInitParams = PaymentSdkInitParams(
|
||||
token = token,
|
||||
requestId = requestId,
|
||||
screenType = PaymentConstants.MINI_PAYMENT_SCREEN,
|
||||
paymentPreFetchMethodRequest = PaymentPrefetchMethodRequest(
|
||||
previousScreenName = "home"
|
||||
),
|
||||
paymentSource = PaymentSource.HI.name
|
||||
)
|
||||
|
||||
paymentManager.initPaymentsSdk(
|
||||
paymentSdkInitParams = paymentSdkInitParams,
|
||||
paymentResultListener = object : PaymentResultListener {
|
||||
override fun onResultLoading() {
|
||||
}
|
||||
|
||||
override fun onResultSuccess(payload: JSONObject?) {
|
||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
viewModel.loadingScreen.value = false
|
||||
}
|
||||
paymentNavigator.launchOrNavigateFromPaymentSdk(
|
||||
paymentSdkInitParams,
|
||||
payload,
|
||||
object : ClientScreenOwner {
|
||||
override fun getActivity() = activity
|
||||
|
||||
override fun getResultLauncher(): ActivityResultLauncher<Intent> {
|
||||
return paymentsResultLauncher
|
||||
}
|
||||
|
||||
override fun getFragManager() = childFragmentManager
|
||||
|
||||
override fun getContainerId() = R.id.container
|
||||
|
||||
override fun getFragment(): Fragment = this@PaymentReviewFragment
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResultFailed(error: GenericErrorResponse) {
|
||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
|
||||
viewModel.loadingScreen.value = false
|
||||
}
|
||||
paymentStatusListener?.setPaymentResult(Activity.RESULT_CANCELED, false, bundle = bundleOf(Pair(AMOUNT, amount)))
|
||||
}
|
||||
},
|
||||
activityResultLauncher = paymentsResultLauncher
|
||||
)
|
||||
}
|
||||
|
||||
private fun appendIdAndTypeToEvent(analyticsEvent: AnalyticsEvent): AnalyticsEvent {
|
||||
val analyticsEventProperties = analyticsEvent.properties ?: mutableMapOf()
|
||||
analyticsEventProperties[ID] = id.orEmpty()
|
||||
@@ -348,7 +507,8 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
return analyticsEvent.copy(properties = analyticsEventProperties)
|
||||
}
|
||||
|
||||
override fun widgetAnalytics(analyticsEvent: AnalyticsEvent?) { analyticsEvent?.let {
|
||||
override fun widgetAnalytics(analyticsEvent: AnalyticsEvent?) {
|
||||
analyticsEvent?.let {
|
||||
analyticsHandler.sendEvent(appendIdAndTypeToEvent(analyticsEvent), screenName)
|
||||
}
|
||||
}
|
||||
@@ -371,6 +531,15 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
binding.landingPageRv.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private fun getParameterFromCta(ctaData: CtaData?, property: String?): String? {
|
||||
ctaData?.parameters?.forEach { keyValue ->
|
||||
if (keyValue.key == property) {
|
||||
return keyValue.value
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override val screenName: String = TAG
|
||||
override fun getViewModel(): GiBaseVM = viewModel
|
||||
override fun getRetryAction(errorMessage: ErrorMessage?): () -> Unit = {}
|
||||
@@ -379,4 +548,13 @@ class PaymentReviewFragment : GiBaseFragment(), WidgetCallback {
|
||||
companion object {
|
||||
const val TAG = "paymentReviewScreen"
|
||||
}
|
||||
}
|
||||
|
||||
interface PaymentStatusListener {
|
||||
fun setPaymentResult(
|
||||
resultCode: Int,
|
||||
isCancelledByUser: Boolean = false,
|
||||
ctaData: CtaData? = null,
|
||||
bundle: Bundle? = null
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.navi.insurance.paymentreview.autopayoption.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.navi.base.model.CtaData
|
||||
import com.navi.insurance.common.GiBaseActivity
|
||||
import com.navi.insurance.common.util.NavigationHandler
|
||||
import com.navi.insurance.models.TurboPaymentOrderDetail
|
||||
import com.navi.insurance.models.response.PaymentStatusScreenResponse
|
||||
import com.navi.insurance.paymentreview.autopayoption.viewmodel.HITurboCheckoutVM
|
||||
import com.navi.insurance.paymentreview.autopayoption.viewmodel.PaymentInitState
|
||||
import com.navi.insurance.util.AMOUNT
|
||||
import com.navi.insurance.util.CONTENT_DATA_JSON_STRING
|
||||
import com.navi.insurance.util.Constants
|
||||
import com.navi.insurance.util.Constants.IS_AUTOPAY
|
||||
import com.navi.insurance.util.Constants.IS_INSTALMENT
|
||||
import com.navi.insurance.util.Constants.KEY_CTA_DATA
|
||||
import com.navi.insurance.util.Constants.PAYMENTS_STATUS_IS_USER_CANCELLED_EXTRA
|
||||
import com.navi.insurance.util.FAILURE
|
||||
import com.navi.insurance.util.PAYMENT_FLOW_IDENTIFIER
|
||||
import com.navi.insurance.util.PAYMENT_ORDER_DETAIL
|
||||
import com.navi.insurance.util.SUCCESS
|
||||
import com.navi.naviwidgets.extensions.NaviLottie
|
||||
import com.navi.naviwidgets.extensions.NaviTextWidgetized
|
||||
import com.navi.naviwidgets.extensions.getJsonObject
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PaymentStatusActivity : GiBaseActivity() {
|
||||
|
||||
private val viewModel by viewModels<HITurboCheckoutVM>()
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val dataType = object : TypeToken<PaymentStatusScreenResponse>() {}.type
|
||||
val paymentStatusScreenResponse = getJsonObject<PaymentStatusScreenResponse>(dataType, intent?.getStringExtra(
|
||||
CONTENT_DATA_JSON_STRING
|
||||
))
|
||||
setContent {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
NaviTextWidgetized(textFieldData = paymentStatusScreenResponse?.title)
|
||||
paymentStatusScreenResponse?.lottieFieldData?.let {
|
||||
NaviLottie(
|
||||
modifier = Modifier
|
||||
.width(200.dp)
|
||||
.height(200.dp)
|
||||
.padding(vertical = 16.dp), lottie = it
|
||||
)
|
||||
}
|
||||
NaviTextWidgetized(textFieldData = paymentStatusScreenResponse?.subTitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
val turboPaymentOrderDetail = intent?.getParcelableExtra<TurboPaymentOrderDetail>(
|
||||
PAYMENT_ORDER_DETAIL
|
||||
)
|
||||
viewModel.getPaymentStatus(
|
||||
orderReferenceId = turboPaymentOrderDetail?.orderReferenceId.orEmpty(),
|
||||
clientStatus = null,
|
||||
pgClientStatus = null,
|
||||
flowIdentifier = intent?.getStringExtra(PAYMENT_FLOW_IDENTIFIER),
|
||||
pollingConfig = turboPaymentOrderDetail?.pollingConfig,
|
||||
policyId = intent?.getStringExtra(Constants.POLICY_ID)
|
||||
)
|
||||
lifecycleScope.launch {
|
||||
viewModel.paymentStatus.collect {
|
||||
when(it){
|
||||
is PaymentInitState.Success -> {
|
||||
when (it.data?.status) {
|
||||
SUCCESS -> {
|
||||
setPaymentResult(Activity.RESULT_OK, ctaData = it.data.redirectionCta)
|
||||
}
|
||||
FAILURE -> {
|
||||
setPaymentResult(Activity.RESULT_CANCELED, false, it.data.fallbackCta)
|
||||
}
|
||||
}
|
||||
}
|
||||
is PaymentInitState.Error -> {
|
||||
setPaymentResult(Activity.RESULT_CANCELED, false, turboPaymentOrderDetail?.apiFailureCta)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setPaymentResult(
|
||||
result: Int,
|
||||
isCancelledByUser: Boolean = false,
|
||||
ctaData: CtaData? = null
|
||||
) {
|
||||
val resultIntent = getPaymentResultIntent(isCancelledByUser, ctaData)
|
||||
setResult(result, resultIntent)
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun getPaymentResultIntent(
|
||||
isCancelledByUser: Boolean,
|
||||
ctaData: CtaData? = null
|
||||
): Intent {
|
||||
val resultIntent = Intent()
|
||||
resultIntent.run {
|
||||
putExtra(AMOUNT, intent.getStringExtra(AMOUNT))
|
||||
putExtra(IS_AUTOPAY, intent.getStringExtra(IS_AUTOPAY).toBoolean())
|
||||
putExtra(IS_INSTALMENT, intent.getStringExtra(IS_INSTALMENT).toBoolean())
|
||||
putExtra(PAYMENTS_STATUS_IS_USER_CANCELLED_EXTRA, isCancelledByUser)
|
||||
putExtra(KEY_CTA_DATA, ctaData)
|
||||
}
|
||||
return resultIntent
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
//Back press is disable for this screen
|
||||
}
|
||||
|
||||
override val screenName: String = NavigationHandler.URL_PAYMENT_STATUS_SCREEN
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.navi.insurance.paymentreview.autopayoption.viewmodel
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.common.network.models.RepoResult
|
||||
import com.navi.insurance.common.GiBaseVM
|
||||
import com.navi.insurance.common.util.ActionHandler
|
||||
import com.navi.insurance.health.repository.PaymentRepository
|
||||
import com.navi.insurance.models.PaymentStateResponse
|
||||
import com.navi.insurance.models.TurboPaymentOrderDetail
|
||||
import com.navi.insurance.models.request.InitiateInstallmentPaymentRequest
|
||||
import com.navi.insurance.network.ApiErrorTagType
|
||||
import com.navi.insurance.util.FAILURE
|
||||
import com.navi.insurance.util.SUCCESS
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
open class HITurboCheckoutVM
|
||||
@Inject constructor(actionHandler: ActionHandler) : GiBaseVM(actionHandler) {
|
||||
private val _paymentInitState =
|
||||
MutableStateFlow<PaymentInitState<TurboPaymentOrderDetail>>(PaymentInitState.Initial)
|
||||
val paymentInitState: StateFlow<PaymentInitState<TurboPaymentOrderDetail>> = _paymentInitState
|
||||
|
||||
val loadingScreen =
|
||||
MutableLiveData<Boolean>()
|
||||
|
||||
private val _paymentStatus =
|
||||
MutableStateFlow<PaymentInitState<PaymentStateResponse?>>(PaymentInitState.Initial)
|
||||
val paymentStatus: StateFlow<PaymentInitState<PaymentStateResponse?>> = _paymentStatus
|
||||
|
||||
private var statusJob: Job? = null
|
||||
|
||||
@Inject
|
||||
lateinit var paymentRepository: PaymentRepository
|
||||
|
||||
|
||||
fun initiatePayment(
|
||||
request: InitiateInstallmentPaymentRequest, policyId: String
|
||||
) {
|
||||
viewModelScope.launch {
|
||||
_paymentInitState.value = PaymentInitState.Loading
|
||||
val response = paymentRepository.initiatePaymentForInstallmentV2(policyId, request)
|
||||
if (response.error == null && response.data != null) {
|
||||
_paymentInitState.value = PaymentInitState.Success(response.data!!)
|
||||
} else {
|
||||
_paymentInitState.value = PaymentInitState.Error(response.error?.message.orEmpty())
|
||||
updateErrorMessage(
|
||||
response.error, ApiErrorTagType.INITIATE_PAYMENT_ERROR.value, false
|
||||
)
|
||||
setError(response.errors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getPaymentStatus(
|
||||
orderReferenceId: String,
|
||||
clientStatus: String? = null,
|
||||
pgClientStatus: String? = null,
|
||||
flowIdentifier: String? = null,
|
||||
pollingConfig: TurboPaymentOrderDetail.PollingConfig? = null,
|
||||
policyId: String?
|
||||
) {
|
||||
_paymentStatus.value = PaymentInitState.Loading
|
||||
if (statusJob?.isActive.orFalse()) {
|
||||
statusJob?.cancel()
|
||||
}
|
||||
statusJob = viewModelScope.launch {
|
||||
val initialDelay = pollingConfig?.initialDelay ?: 5000L
|
||||
val interval = pollingConfig?.pollingInterval ?: 3000L
|
||||
val noOfRetries = pollingConfig?.maxNumberOfRetries ?: 10
|
||||
delay(initialDelay)
|
||||
var count = 0
|
||||
var response: RepoResult<PaymentStateResponse> = RepoResult()
|
||||
while (count < noOfRetries && isActive) {
|
||||
response = paymentRepository.getPaymentStatusForCustomerV2(
|
||||
orderReferenceId, clientStatus, pgClientStatus, flowIdentifier, policyId
|
||||
)
|
||||
if (response.error != null || listOf(
|
||||
SUCCESS,
|
||||
FAILURE
|
||||
).contains(response.data?.status)
|
||||
) break
|
||||
count++
|
||||
delay(interval)
|
||||
}
|
||||
if (isActive) {
|
||||
if (response.error == null) {
|
||||
_paymentStatus.value = PaymentInitState.Success(response.data)
|
||||
} else {
|
||||
_paymentStatus.value = PaymentInitState.Error()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class PaymentInitState<out T> {
|
||||
data object Loading : PaymentInitState<Nothing>()
|
||||
data class Error(val message: String? = null) : PaymentInitState<Nothing>()
|
||||
|
||||
data class Success<T>(val data: T) : PaymentInitState<T>()
|
||||
|
||||
data object Initial : PaymentInitState<Nothing>()
|
||||
}
|
||||
@@ -27,7 +27,7 @@ constructor(
|
||||
private val repository: PaymentReviewRepository,
|
||||
actionHandler: ActionHandler,
|
||||
private val dispatcher: CoroutineDispatcherProvider
|
||||
) : GiBaseVM(actionHandler) {
|
||||
) : HITurboCheckoutVM(actionHandler) {
|
||||
|
||||
private val _paymentRequestFlow =
|
||||
MutableStateFlow<ResponseState<PaymentReviewResponse>>(ResponseState.Idle)
|
||||
|
||||
@@ -135,6 +135,7 @@ object Constants {
|
||||
|
||||
const val FAQ_CONTEXT_SCREEN = "FAQ_CONTEXT_SCREEN"
|
||||
const val POLICY_ID = "policyId"
|
||||
const val EMI = "EMI"
|
||||
const val IS_CANCELLED = "IS_CANCELLED"
|
||||
const val EMI_DETAILS_DATA = "EMI_DETAILS_DATA"
|
||||
const val EMI_TIMELINE_DATA = "EMI_TIMELINE_DATA"
|
||||
@@ -151,6 +152,7 @@ object Constants {
|
||||
const val PAYMENT_FLOW = "paymentFlow"
|
||||
const val EMI_PREPAYMENT = "EMI_PREPAYMENT"
|
||||
const val IS_AUTOPAY = "isAutopay"
|
||||
const val IS_TURBO_CHECKOUT = "isTurboCheckout"
|
||||
const val IS_AUTOPAY_PROCESSING = "isAutoPayProcessing"
|
||||
const val IS_AUTOPAY_FROM_QUOTE = "isAutopayFromQuote"
|
||||
const val PAYMENT_SUCCESS_CTA = "paymentSuccessCta"
|
||||
|
||||
@@ -54,4 +54,5 @@ const val ID = "id"
|
||||
const val PAYMENT_FLOW_IDENTIFIER = "paymentFlowIdentifier"
|
||||
const val REDIRECTION_CTA = "redirectionCta"
|
||||
const val RELOAD_PARENT_SCREEN = "reloadParentScreen"
|
||||
const val PAYMENT_ORDER_DETAIL = "PAYMENT_ORDER_DETAIL"
|
||||
|
||||
|
||||
@@ -87,6 +87,22 @@
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="Pay now" />
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/loading_button"
|
||||
style="@style/ButtonFontStylePurple"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:paddingHorizontal="@dimen/dp_40"
|
||||
app:layout_constraintTop_toTopOf="@id/button"
|
||||
app:layout_constraintStart_toStartOf="@id/button"
|
||||
app:layout_constraintEnd_toEndOf="@id/button"
|
||||
app:layout_constraintBottom_toBottomOf="@id/button"
|
||||
app:lottie_url="https://public-assets.prod.navi-sa.in/home_uitron/cta_loader.json"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</com.navi.insurance.common.widgets.FooterWithTitleAndSubtitleLayout>
|
||||
|
||||
</layout>
|
||||
@@ -61,5 +61,13 @@
|
||||
android:id="@+id/floating_action_button_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/transparent_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
@@ -10,5 +10,6 @@ package com.navi.payment.utils;
|
||||
public enum PaymentSource {
|
||||
DG,
|
||||
BBPS,
|
||||
PL
|
||||
PL,
|
||||
HI
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user