diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt index 719542728a..500e5fa50d 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt @@ -4,6 +4,7 @@ import com.tangem.data.pay.DefaultTangemPayCryptoCurrencyFactory import com.tangem.data.pay.DefaultTangemPayEligibilityManager import com.tangem.data.pay.repository.* import com.tangem.data.pay.usecase.DefaultGetTangemPayCurrencyStatusUseCase +import com.tangem.data.pay.usecase.DefaultGetTangemPayCustomerIdUseCase import com.tangem.data.pay.usecase.DefaultTangemPayWithdrawUseCase import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory import com.tangem.domain.pay.TangemPayEligibilityManager @@ -11,6 +12,7 @@ import com.tangem.domain.pay.repository.* import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase +import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase import com.tangem.domain.tangempay.TangemPayWithdrawUseCase import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository import com.tangem.security.DeviceSecurityInfoProvider @@ -65,6 +67,10 @@ internal interface TangemPayDataModule { @Singleton fun bindTangemPayWithdrawUseCase(impl: DefaultTangemPayWithdrawUseCase): TangemPayWithdrawUseCase + @Binds + @Singleton + fun bindGetTangemPayCustomerIdUseCase(impl: DefaultGetTangemPayCustomerIdUseCase): GetTangemPayCustomerIdUseCase + @Binds @Singleton fun bindTangemPayEligibilityManager(impl: DefaultTangemPayEligibilityManager): TangemPayEligibilityManager diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/usecase/DefaultGetTangemPayCustomerIdUseCase.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/usecase/DefaultGetTangemPayCustomerIdUseCase.kt new file mode 100644 index 0000000000..b4da25e73f --- /dev/null +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/usecase/DefaultGetTangemPayCustomerIdUseCase.kt @@ -0,0 +1,25 @@ +package com.tangem.data.pay.usecase + +import arrow.core.Either +import arrow.core.left +import arrow.core.right +import com.tangem.core.error.UniversalError +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.repository.OnboardingRepository +import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase +import com.tangem.domain.visa.error.VisaApiError +import javax.inject.Inject + +internal class DefaultGetTangemPayCustomerIdUseCase @Inject constructor( + private val tangemPayOnboardingRepository: OnboardingRepository, +) : GetTangemPayCustomerIdUseCase { + + override fun invoke(userWalletId: UserWalletId): Either { + val customerId = tangemPayOnboardingRepository.getSavedCustomerInfo(userWalletId)?.customerId + return if (customerId.isNullOrEmpty()) { + VisaApiError.CustomerIdUnavailable.left() + } else { + customerId.right() + } + } +} \ No newline at end of file diff --git a/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt b/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt index 1dae5fb656..7b74739db5 100644 --- a/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt +++ b/domain/feedback/models/src/main/kotlin/com/tangem/domain/feedback/models/FeedbackEmailType.kt @@ -60,31 +60,50 @@ sealed interface FeedbackEmailType { } sealed class Visa : FeedbackEmailType { + abstract val customerId: String - data class DirectUserRequest(override val walletMetaInfo: WalletMetaInfo) : Visa() + data class DirectUserRequest( + override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, + ) : Visa() - data class Activation(override val walletMetaInfo: WalletMetaInfo) : Visa() + data class Activation( + override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, + ) : Visa() data class Dispute( val visaTxDetails: VisaTxDetails, override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, ) : Visa() - data class FailedIssueCard(override val walletMetaInfo: WalletMetaInfo) : Visa() + data class FailedIssueCard( + override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, + ) : Visa() data class DisputeV2( val item: TangemPayTxHistoryItem, override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, ) : Visa() data class Withdrawal( override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, val providerName: String, val txId: String, ) : Visa() - data class FeatureIsBeta(override val walletMetaInfo: WalletMetaInfo) : Visa() + data class FeatureIsBeta( + override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, + ) : Visa() - data class KycRejected(override val walletMetaInfo: WalletMetaInfo, val customerId: String) : Visa() + data class KycRejected( + override val walletMetaInfo: WalletMetaInfo, + override val customerId: String, + ) : Visa() } } \ No newline at end of file diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt index d10954f517..b44422a99a 100644 --- a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt +++ b/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackDataBuilder.kt @@ -55,7 +55,7 @@ internal class FeedbackDataBuilder { } fun addCustomerId(customerId: String) { - builder.appendKeyValue("ID: ", customerId) + builder.appendKeyValue("Tangem Pay Customer ID", customerId) } fun addUserWalletMetaInfo(walletMetaInfo: WalletMetaInfo) { diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt index f9307e7914..04228907bc 100644 --- a/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt +++ b/domain/feedback/src/main/java/com/tangem/domain/feedback/utils/EmailMessageBodyResolver.kt @@ -34,7 +34,11 @@ class EmailMessageBodyResolver( -> addPhoneInfoBody() is FeedbackEmailType.Visa.Activation -> addUserRequestBody(type.walletMetaInfo) is FeedbackEmailType.Visa.DirectUserRequest -> addUserRequestBody(type.walletMetaInfo) - is FeedbackEmailType.Visa.Dispute -> addVisaRequestBody(type.walletMetaInfo, type.visaTxDetails) + is FeedbackEmailType.Visa.Dispute -> addVisaRequestBody( + walletMetaInfo = type.walletMetaInfo, + customerId = type.customerId, + visaTxDetails = type.visaTxDetails, + ) is FeedbackEmailType.Visa.FailedIssueCard -> addTangemPayFailedIssuingCardBody(type) is FeedbackEmailType.Visa.DisputeV2 -> addTangemPayDisputeRequestBody(type) is FeedbackEmailType.Visa.Withdrawal -> addTangemPayWithdrawalRequestBody(type) @@ -48,6 +52,7 @@ class EmailMessageBodyResolver( private fun FeedbackDataBuilder.addTangemPayFailedIssuingCardBody(type: FeedbackEmailType.Visa.FailedIssueCard) { addTangemPayPhoneInfoBody(type) addDelimiter() + addCustomerId(customerId = type.customerId) type.walletMetaInfo.userWalletId?.let { userWalletId -> addUserWalletId(userWalletId = userWalletId.stringValue) } @@ -58,6 +63,7 @@ class EmailMessageBodyResolver( addDelimiter() addTangemPayTxInfo(type.item) addDelimiter() + addCustomerId(customerId = type.customerId) type.walletMetaInfo.userWalletId?.let { userWalletId -> addUserWalletId(userWalletId = userWalletId.stringValue) } @@ -66,6 +72,7 @@ class EmailMessageBodyResolver( private fun FeedbackDataBuilder.addTangemPayBetaRequestBody(type: FeedbackEmailType.Visa) { addTangemPayPhoneInfoBody(type) addDelimiter() + addCustomerId(customerId = type.customerId) type.walletMetaInfo?.userWalletId?.let { userWalletId -> addUserWalletId(userWalletId = userWalletId.stringValue) } @@ -82,6 +89,7 @@ class EmailMessageBodyResolver( ) { addUserWalletMetaInfo(type.walletMetaInfo) addDelimiter() + addCustomerId(customerId = type.customerId) val userWalletId = requireNotNull(type.walletMetaInfo.userWalletId) { "UserWalletId must be not null" } val blockchainError = feedbackRepository.getBlockchainErrorInfo(userWalletId = userWalletId) @@ -107,9 +115,11 @@ class EmailMessageBodyResolver( private suspend fun FeedbackDataBuilder.addVisaRequestBody( walletMetaInfo: WalletMetaInfo, visaTxDetails: VisaTxDetails, + customerId: String, ) { addUserRequestBody(walletMetaInfo) addDelimiter() + addCustomerId(customerId = customerId) addVisaTxInfo(visaTxDetails) } diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/pay/TangemPayDetailsConfig.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/pay/TangemPayDetailsConfig.kt index 88f7b5556c..14edae3667 100644 --- a/domain/visa/models/src/main/kotlin/com/tangem/domain/pay/TangemPayDetailsConfig.kt +++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/pay/TangemPayDetailsConfig.kt @@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable @Serializable data class TangemPayDetailsConfig( + val customerId: String, val cardId: String, val isPinSet: Boolean, val cardFrozenState: TangemPayCardFrozenState, diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/error/VisaError.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/error/VisaError.kt index 412045caff..be321d6b33 100644 --- a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/error/VisaError.kt +++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/error/VisaError.kt @@ -66,6 +66,7 @@ sealed class VisaApiError( data object SignWithdrawError : VisaApiError(104004004) data object WithdrawError : VisaApiError(104004005) data object ServerUnavailable : VisaApiError(104004006) + data object CustomerIdUnavailable : VisaApiError(104004007) companion object { fun fromBackendError(backendErrorCode: Int): VisaApiError { diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/tangempay/GetTangemPayCustomerIdUseCase.kt b/domain/visa/src/main/kotlin/com/tangem/domain/tangempay/GetTangemPayCustomerIdUseCase.kt new file mode 100644 index 0000000000..af30a64af0 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/tangempay/GetTangemPayCustomerIdUseCase.kt @@ -0,0 +1,10 @@ +package com.tangem.domain.tangempay + +import arrow.core.Either +import com.tangem.core.error.UniversalError +import com.tangem.domain.models.wallet.UserWalletId + +interface GetTangemPayCustomerIdUseCase { + + operator fun invoke(userWalletId: UserWalletId): Either +} \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 4abde012d5..f31f23da03 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -23,6 +23,7 @@ import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.pay.TangemPayEligibilityManager import com.tangem.domain.redux.LegacyAction import com.tangem.domain.redux.ReduxStateHolder +import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase import com.tangem.domain.wallets.usecase.GenerateBuyTangemCardLinkUseCase import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase @@ -63,6 +64,7 @@ internal class DetailsModel @Inject constructor( private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val appStateHolder: ReduxStateHolder, private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase, + private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val getWalletsUseCase: GetWalletsUseCase, override val dispatchers: CoroutineDispatcherProvider, @@ -134,14 +136,20 @@ internal class DetailsModel @Inject constructor( ?: error("Selected wallet is null") val metaInfo = getWalletMetaInfoUseCase(selectedUserWallet.walletId).getOrNull() ?: return@launch + val visaCustomerId = getTangemPayCustomerIdUseCase(selectedUserWallet.walletId).getOrNull() val feedbackType = when { - userWallets.all { it is UserWallet.Cold && it.scanResponse.card.isVisa } -> - FeedbackEmailType.Visa.DirectUserRequest(metaInfo) + userWallets.all { + it is UserWallet.Cold && it.scanResponse.card.isVisa && !visaCustomerId.isNullOrEmpty() + } -> + FeedbackEmailType.Visa.DirectUserRequest( + walletMetaInfo = metaInfo, + customerId = requireNotNull(visaCustomerId), + ) userWallets.all { it !is UserWallet.Cold || it.scanResponse.card.isVisa.not() } -> FeedbackEmailType.DirectUserRequest(metaInfo) else -> { - showFeedbackEmailTypeOptionBS(metaInfo) + showFeedbackEmailTypeOptionBS(selectedWalletMetaInfo = metaInfo, visaCustomerId = visaCustomerId) return@launch } } @@ -158,16 +166,16 @@ internal class DetailsModel @Inject constructor( } } - private fun showFeedbackEmailTypeOptionBS(selectedWalletMetaInfo: WalletMetaInfo) { - state.update { - it.copy( + private fun showFeedbackEmailTypeOptionBS(selectedWalletMetaInfo: WalletMetaInfo, visaCustomerId: String?) { + state.update { current -> + current.copy( selectFeedbackEmailTypeBSConfig = TangemBottomSheetConfig( isShown = true, onDismissRequest = { state.update { - it.copy( + current.copy( selectFeedbackEmailTypeBSConfig = - it.selectFeedbackEmailTypeBSConfig.copy(isShown = false), + current.selectFeedbackEmailTypeBSConfig.copy(isShown = false), ) } }, @@ -176,6 +184,7 @@ internal class DetailsModel @Inject constructor( onEmailFeedbackTypeOptionSelected( selectedWalletMetaInfo = selectedWalletMetaInfo, option = option, + visaCustomerId = visaCustomerId, ) state.update { @@ -194,6 +203,7 @@ internal class DetailsModel @Inject constructor( private fun onEmailFeedbackTypeOptionSelected( selectedWalletMetaInfo: WalletMetaInfo, option: SelectEmailFeedbackTypeBS.Option, + visaCustomerId: String?, ) { modelScope.launch { val feedbackType = when (option) { @@ -211,14 +221,15 @@ internal class DetailsModel @Inject constructor( } } SelectEmailFeedbackTypeBS.Option.Visa -> { - if (selectedWalletMetaInfo.isVisa == true) { - FeedbackEmailType.Visa.DirectUserRequest(selectedWalletMetaInfo) + if (selectedWalletMetaInfo.isVisa == true && !visaCustomerId.isNullOrEmpty()) { + FeedbackEmailType.Visa.DirectUserRequest(selectedWalletMetaInfo, visaCustomerId) } else { val userWallet = getWalletsUseCase.invokeSync() .firstOrNull { it is UserWallet.Cold && it.scanResponse.card.isVisa } ?: return@launch val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return@launch - FeedbackEmailType.Visa.DirectUserRequest(metaInfo) + val customerId = getTangemPayCustomerIdUseCase(userWallet.walletId).getOrNull() ?: return@launch + FeedbackEmailType.Visa.DirectUserRequest(metaInfo, customerId) } } } diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt index af0fadb5fb..03d7c218c2 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/impl/DefaultOnboardingStepperComponent.kt @@ -13,6 +13,7 @@ import com.tangem.domain.card.common.TapWorkarounds.isVisa import com.tangem.domain.feedback.GetWalletMetaInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType +import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase import com.tangem.features.onboarding.v2.stepper.api.OnboardingStepperComponent import com.tangem.features.onboarding.v2.stepper.impl.ui.OnboardingStepper import dagger.assisted.Assisted @@ -27,6 +28,7 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor( private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val analyticsHandler: AnalyticsEventHandler, + private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase, ) : OnboardingStepperComponent, AppComponentContext by context { override val state = instanceKeeper.getOrCreateSimple { MutableStateFlow(params.initState) } @@ -41,11 +43,13 @@ internal class DefaultOnboardingStepperComponent @AssistedInject constructor( componentScope.launch { val cardInfo = getWalletMetaInfoUseCase(params.scanResponse).getOrNull() ?: return@launch + val userWalletId = cardInfo.userWalletId ?: return@launch + val visaCustomerId = getTangemPayCustomerIdUseCase(userWalletId).getOrNull() sendFeedbackEmailUseCase( - if (params.scanResponse.card.isVisa) { - FeedbackEmailType.Visa.Activation(cardInfo) + if (params.scanResponse.card.isVisa && !visaCustomerId.isNullOrEmpty()) { + FeedbackEmailType.Visa.Activation(walletMetaInfo = cardInfo, customerId = visaCustomerId) } else { - FeedbackEmailType.DirectUserRequest(cardInfo) + FeedbackEmailType.DirectUserRequest(walletMetaInfo = cardInfo) }, ) } diff --git a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt index b51473e5c1..104034768e 100644 --- a/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt +++ b/features/swap/impl/src/main/java/com/tangem/feature/swap/model/SwapModel.kt @@ -56,6 +56,7 @@ import com.tangem.domain.settings.usercountry.GetUserCountryUseCase import com.tangem.domain.settings.usercountry.models.UserCountry import com.tangem.domain.settings.usercountry.models.needApplyFCARestrictions import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase +import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase import com.tangem.domain.tangempay.TangemPayWithdrawUseCase import com.tangem.domain.tokens.GetFeePaidCryptoCurrencyStatusSyncUseCase import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase @@ -156,6 +157,7 @@ internal class SwapModel @Inject constructor( private val getTokenMarketInfoUseCase: GetTokenMarketInfoUseCase, private val excludedBlockchains: ExcludedBlockchains, private val getUserWalletsUseCase: GetWalletsUseCase, + private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase, ) : Model() { private val params = paramsContainer.require() @@ -1995,16 +1997,20 @@ internal class SwapModel @Inject constructor( uiState = uiState, error = SwapTransactionState.Error.TangemPayWithdrawalError(txId.orEmpty()), onDismiss = { uiState = stateBuilder.clearAlert(uiState) }, - onSupportClick = ::onTangemPaySupportClick, + onSupportClick = { + val customerId = getTangemPayCustomerIdUseCase(userWallet.walletId).getOrNull() ?: "Unknown" + onTangemPaySupportClick(customerId = customerId, txId = txId) + }, isReverseSwapPossible = isReverseSwapPossible(), ) } - private fun onTangemPaySupportClick(txId: String?) { + private fun onTangemPaySupportClick(customerId: String, txId: String?) { modelScope.launch { val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return@launch val email = FeedbackEmailType.Visa.Withdrawal( walletMetaInfo = metaInfo, + customerId = customerId, providerName = dataState.selectedProvider?.name.orEmpty(), txId = txId.orEmpty(), ) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt index a4e44f025e..2b5736147e 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayDetailsComponent.kt @@ -105,6 +105,7 @@ internal class TangemPayDetailsComponent( transaction = navigation.transaction, isBalanceHidden = navigation.isBalanceHidden, userWalletId = params.userWalletId, + customerId = params.config.customerId, onDismiss = model.bottomSheetNavigation::dismiss, ), ) diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt index eeb2b77c8f..c2792e7e33 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/txHistory/TangemPayTxHistoryDetailsComponent.kt @@ -32,6 +32,7 @@ internal class TangemPayTxHistoryDetailsComponent( val transaction: TangemPayTxHistoryItem, val isBalanceHidden: Boolean, val userWalletId: UserWalletId, + val customerId: String, val onDismiss: () -> Unit, ) } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt index d2f9137ae1..8dfb45c420 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayDetailsModel.kt @@ -371,6 +371,7 @@ internal class TangemPayDetailsModel @Inject constructor( sendFeedbackEmailUseCase.invoke( type = FeedbackEmailType.Visa.FeatureIsBeta( walletMetaInfo = WalletMetaInfo(userWalletId = params.userWalletId), + customerId = params.config.customerId, ), ) } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt index 1d6f1f82fa..4e815c1f1a 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayTxHistoryDetailsModel.kt @@ -40,7 +40,7 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor( item = params.transaction, isBalanceHidden = params.isBalanceHidden, onExplorerClick = ::openExplorer, - onDisputeClick = ::dispute, + onDisputeClick = { dispute(customerId = params.customerId) }, onDismiss = ::dismiss, ), ), @@ -64,7 +64,7 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor( txHash?.let(urlOpener::openUrlExternalBrowser) } - private fun dispute() { + private fun dispute(customerId: String) { analytics.send(TangemPayAnalyticsEvents.SupportOnTransactionPopupClicked()) modelScope.launch { val walletMetaInfo = getWalletMetaInfoUseCase.invoke(params.userWalletId).getOrNull() ?: return@launch @@ -73,6 +73,7 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor( FeedbackEmailType.Visa.DisputeV2( item = params.transaction, walletMetaInfo = walletMetaInfo, + customerId = customerId, ), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt index 1318303b1a..1638e3ed00 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/child/wallet/model/intents/TangemPayClickIntents.kt @@ -51,9 +51,9 @@ internal interface TangemPayIntents { fun onIssuingCardClicked() - fun onIssuingFailedClicked() + fun onIssuingFailedClicked(customerId: String) - fun onPaySupportClick() + fun onPaySupportClick(customerId: String) fun onOnboardingBannerClick(userWalletId: UserWalletId) @@ -203,7 +203,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( uiMessageSender.send(issuingBottomSheet) } - override fun onIssuingFailedClicked() { + override fun onIssuingFailedClicked(customerId: String) { val issuingBottomSheet = bottomSheetMessage { infoBlock { icon(com.tangem.core.ui.R.drawable.ic_alert_24) { @@ -216,7 +216,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( secondaryButton { text = resourceReference(R.string.tangempay_go_to_support) onClick { - onPaySupportClick() + onPaySupportClick(customerId) closeBs() } } @@ -225,7 +225,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( uiMessageSender.send(issuingBottomSheet) } - override fun onPaySupportClick() { + override fun onPaySupportClick(customerId: String) { modelScope.launch { val cardInfo = getWalletMetainfoUseCase.invoke( userWalletId = stateHolder.getSelectedWalletId(), @@ -234,6 +234,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( sendFeedbackEmailUseCase( FeedbackEmailType.Visa.FailedIssueCard( walletMetaInfo = cardInfo, + customerId = customerId, ), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayUpdateInfoStateTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayUpdateInfoStateTransformer.kt index 9a9ce4feee..c995e3dd44 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayUpdateInfoStateTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/TangemPayUpdateInfoStateTransformer.kt @@ -45,37 +45,42 @@ internal class TangemPayUpdateInfoStateTransformer( private fun createInitialState(): TangemPayState { val cardInfo = value.info.cardInfo val productInstance = value.info.productInstance - val customerId = value.info.customerId + val customerId = value.info.customerId ?: "Unknown" // when statement copied to WalletTangemPayAnalyticsEventSender. Be careful when editing. return when { - value.orderStatus == OrderStatus.CANCELED -> createCancelledState() - value.info.kycStatus != APPROVED && !customerId.isNullOrEmpty() -> + value.orderStatus == OrderStatus.CANCELED -> createCancelledState(customerId) + value.info.kycStatus != APPROVED && !value.info.customerId.isNullOrEmpty() -> createKycInProgressState(kycStatus = value.info.kycStatus, customerId = customerId) - cardInfo != null && productInstance != null -> getCardInfoState(cardInfo, productInstance) + cardInfo != null && productInstance != null -> + getCardInfoState(customerId, cardInfo, productInstance) else -> createIssueProgressState() } } - private fun getCardInfoState(cardInfo: CardInfo, productInstance: ProductInstance): TangemPayState = - TangemPayState.Card( - lastFourDigits = TextReference.Str("*${cardInfo.lastFourDigits}"), - balanceText = TextReference.Str(getBalanceText(cardInfo)), - balanceSymbol = stringReference("USDC"), // TODO hardcode for now - onClick = { - tangemPayClickIntents.openDetails( - userWalletId, - TangemPayDetailsConfig( - cardId = productInstance.cardId, - isPinSet = cardInfo.isPinSet, - cardFrozenState = cardFrozenState, - customerWalletAddress = cardInfo.customerWalletAddress, - cardNumberEnd = cardInfo.lastFourDigits, - chainId = POLYGON_CHAIN_ID, - ), - ) - }, - ) + private fun getCardInfoState( + customerId: String, + cardInfo: CardInfo, + productInstance: ProductInstance, + ): TangemPayState = TangemPayState.Card( + lastFourDigits = TextReference.Str("*${cardInfo.lastFourDigits}"), + balanceText = TextReference.Str(getBalanceText(cardInfo)), + balanceSymbol = stringReference("USDC"), // TODO hardcode for now + onClick = { + tangemPayClickIntents.openDetails( + userWalletId, + TangemPayDetailsConfig( + customerId = customerId, + cardId = productInstance.cardId, + isPinSet = cardInfo.isPinSet, + cardFrozenState = cardFrozenState, + customerWalletAddress = cardInfo.customerWalletAddress, + cardNumberEnd = cardInfo.lastFourDigits, + chainId = POLYGON_CHAIN_ID, + ), + ) + }, + ) private fun getBalanceText(cardInfo: CardInfo): String { val currency = Currency.getInstance(cardInfo.currencyCode) @@ -113,10 +118,10 @@ internal class TangemPayUpdateInfoStateTransformer( showProgress = true, ) - private fun createCancelledState(): TangemPayState = TangemPayState.FailedIssue( + private fun createCancelledState(customerId: String): TangemPayState = TangemPayState.FailedIssue( title = TextReference.Res(R.string.tangempay_payment_account), description = TextReference.Res(R.string.tangempay_failed_to_issue_card), iconRes = R.drawable.ic_alert_24, - onButtonClick = tangemPayClickIntents::onIssuingFailedClicked, + onButtonClick = { tangemPayClickIntents.onIssuingFailedClicked(customerId) }, ) } \ No newline at end of file