From 737bb507d902f0faa0020357851b14f6f06a0ece Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 23 Dec 2025 18:54:08 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/data/DefaultTangemPayStorage.kt | 11 ++++ .../tangem/datasource/api/pay/TangemPayApi.kt | 6 ++ .../request/SetTangemPayEnabledRequest.kt | 9 +++ .../response/CheckCustomerWalletResponse.kt | 1 + .../datasource/local/visa/TangemPayStorage.kt | 3 + core/res/src/main/res/values-de/strings.xml | 3 + core/res/src/main/res/values-es/strings.xml | 2 + core/res/src/main/res/values-ja/strings.xml | 2 +- core/res/src/main/res/values-ru/strings.xml | 2 +- core/res/src/main/res/values/strings.xml | 4 +- .../message/MessageBottomSheetUMV2.kt | 8 +++ .../message/MessageBottomSheetV2.kt | 57 +++++++++++++++++- .../repository/DefaultOnboardingRepository.kt | 21 ++++++- .../tokens/GetWalletTotalBalanceUseCase.kt | 4 +- .../pay/repository/OnboardingRepository.kt | 2 + .../model/intents/TangemPayClickIntents.kt | 60 +++++++++++++++++++ .../TangemPayUpdateInfoStateTransformer.kt | 51 +++++++++++----- .../state/util/TangemPayStateCreator.kt | 33 ---------- .../subscribers/TangemPayMainSubscriber.kt | 17 +----- 19 files changed, 221 insertions(+), 75 deletions(-) create mode 100644 core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/SetTangemPayEnabledRequest.kt delete mode 100644 features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/util/TangemPayStateCreator.kt diff --git a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt index 80e06699c1..a6f6497a39 100644 --- a/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt +++ b/app/src/main/java/com/tangem/tap/data/DefaultTangemPayStorage.kt @@ -53,6 +53,12 @@ internal class DefaultTangemPayStorage @Inject constructor( } } + override suspend fun clearCustomerWalletAddress(userWalletId: UserWalletId) { + withContext(dispatcherProvider.io) { + appPreferencesStore.store(PreferencesKeys.getTangemPayCustomerWalletAddressKey(userWalletId), "") + } + } + override suspend fun storeAuthTokens(customerWalletAddress: String, tokens: TangemPayAuthTokens) = withContext(dispatcherProvider.io) { val json = tokensAdapter.toJson(tokens) @@ -70,6 +76,10 @@ internal class DefaultTangemPayStorage @Inject constructor( ?.let(tokensAdapter::fromJson) } + override suspend fun clearAuthTokens(customerWalletAddress: String) { + secureStorage.delete(createAuthTokensKey(customerWalletAddress)) + } + override suspend fun storeOrderId(customerWalletAddress: String, orderId: String) { withContext(dispatcherProvider.io) { appPreferencesStore.store(PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress), orderId) @@ -112,6 +122,7 @@ internal class DefaultTangemPayStorage @Inject constructor( override suspend fun clearAll(userWalletId: UserWalletId, customerWalletAddress: String) = withContext(dispatcherProvider.io) { secureStorage.delete(createAuthTokensKey(customerWalletAddress)) + appPreferencesStore.store(PreferencesKeys.getTangemPayCheckCustomerByWalletId(userWalletId), false) appPreferencesStore.store(PreferencesKeys.getTangemPayCustomerWalletAddressKey(userWalletId), "") appPreferencesStore.store(PreferencesKeys.getTangemPayOrderIdKey(customerWalletAddress), "") appPreferencesStore.store(PreferencesKeys.getTangemPayAddToWalletKey(customerWalletAddress), false) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt index 07719ff953..1054ffef58 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt @@ -29,6 +29,12 @@ interface TangemPayApi { @Path("customer_wallet_id") customerWalletId: String, ): ApiResponse + @PATCH("v1/customer/pay-enabled") + suspend fun setTangemPayEnabledStatus( + @Header("Authorization") authHeader: String, + @Body body: SetTangemPayEnabledRequest, + ): ApiResponse + @POST("v1/deeplink/validate") suspend fun validateDeeplink(@Body body: DeeplinkValidityRequest): ApiResponse diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/SetTangemPayEnabledRequest.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/SetTangemPayEnabledRequest.kt new file mode 100644 index 0000000000..c159a2418b --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/request/SetTangemPayEnabledRequest.kt @@ -0,0 +1,9 @@ +package com.tangem.datasource.api.pay.models.request + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class SetTangemPayEnabledRequest( + @Json(name = "is_tangem_pay_enabled") val isTangemPayEnabled: Boolean, +) \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CheckCustomerWalletResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CheckCustomerWalletResponse.kt index 01ee25582c..0a522486f5 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CheckCustomerWalletResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CheckCustomerWalletResponse.kt @@ -9,5 +9,6 @@ data class CheckCustomerWalletResponse( ) { data class Result( @Json(name = "id") val id: String?, + @Json(name = "is_tangem_pay_enabled") val isTangemPayEnabled: Boolean?, ) } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt b/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt index a9279e9193..a048c54414 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/local/visa/TangemPayStorage.kt @@ -8,9 +8,12 @@ interface TangemPayStorage { suspend fun storeCustomerWalletAddress(userWalletId: UserWalletId, customerWalletAddress: String) suspend fun getCustomerWalletAddress(userWalletId: UserWalletId): String? + suspend fun clearCustomerWalletAddress(userWalletId: UserWalletId) + suspend fun storeAuthTokens(customerWalletAddress: String, tokens: TangemPayAuthTokens) suspend fun getAuthTokens(customerWalletAddress: String): TangemPayAuthTokens? + suspend fun clearAuthTokens(customerWalletAddress: String) suspend fun storeOrderId(customerWalletAddress: String, orderId: String) diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index af3e4fd8d7..be2b45ae50 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -1072,6 +1072,8 @@ Bitte setze das nächste Gerät zurück, um fortzufahren. Ringbesitzer erhalten bis zum 15.11. 3 provisionsfreie Swaps auf Changelly! Jetzt mit 0 % Gebühren tauschen! + Geräte mit Root-Zugriff gelten als weniger sicher. Deine Daten können zusätzlichen Risiken ausgesetzt sein. + Root-Zugriff erkannt Melde dich bei der App an und überprüfe dein Guthaben, ohne die Karte oder Ring zu scannen Zugriff auf die App Nutzung biometrischer Daten zulassen @@ -1990,6 +1992,7 @@ Gebührenpolitik Tangem erhebt außerdem eine Servicegebühr von 15% auf den erzielten Ertrag. Deine Gelder werden automatisch an Aave überwiesen, sobald die Netzwerkgebühren niedriger sind oder Dein Guthaben den erforderlichen Mindestbetrag erreicht. + Die Gebühren sind aufgrund der hohen Marktaktivität derzeit höher als üblich. Du kannst jetzt fortfahren oder später noch einmal vorbeischauen, wenn die Gebühren niedriger sind. Hohe Netzwerkgebühren Historische Renditen Aktiviere %1$s%% Jahreszins auf Dein Guthaben diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index e99920eeb5..92108a3ab5 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -916,6 +916,8 @@ El reseteo a valores de fábrica eliminará completamente la billetera de la tarjeta/anillo seleccionado y lo eliminará de la app. No podrá restaurar la billetera actual. Si tiene un Anillo Tangem, ¡3 swaps sin comisión en Changelly hasta el 15/11! ¡Intercambia con 0% de comisión! + Los dispositivos con jailbreak se consideran menos seguros. Sus datos podrían estar expuestos a riesgos adicionales. + Acceso root detectado Inicie sesión en la app y comprueba su saldo sin escanear la tarjeta o el anillo Acceder a la app Permitir el uso de biometría diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 70f1b95349..dbc266076b 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -1617,7 +1617,7 @@ ロック解除 カードをスキャンしてアクセスロックを解除する ロック解除が必要 - ウォレットの追加方法を選択してください + ウォレットの種類を選択します Tangemカードまたはリングをスキャンして復元するか、別のウォレットからインポートしてください。 ハードウェアウォレットを作成 Tangemウォレットを購入しますか? diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 036b504b45..537e6d8e15 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -1634,7 +1634,7 @@ ПИН не принят. Попробуйте ещё раз или введите другой код. Слабый ПИН: не используйте повторы или последовательности. Разблокировать - Выберите способ добавления кошелька + Выберите тип кошелька Отсканируйте вашу карту или кольцо Tangem, чтобы восстановить её или импортировать из другого кошелька. Создать аппаратный кошелёк Хотите приобрести кошелек Tangem? diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index eaddf5b46e..2598e6fe4b 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1501,6 +1501,8 @@ Issuing your card We’re getting your card ready. This may take a little time. Tangem Pay + Confirm Cancellation + Are you sure you want to stop the KYC process? You can return to it anytime. We could not verify your profile. If you have any questions, please contact support. Unfortunately, we couldn\'t verify your identity KYC in progress @@ -1686,7 +1688,7 @@ Unlock Scan your card to unlock access Needed unlock - Choose how to add your wallet + Choose your wallet type Scan your Tangem card or ring to restore it or import from another wallet. Create Hardware Wallet Want to purchase a Tangem Wallet? diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetUMV2.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetUMV2.kt index 0fc219bba4..a776ddd445 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetUMV2.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetUMV2.kt @@ -41,6 +41,9 @@ data class MessageBottomSheetUMV2( } } + @Immutable + data class IconImage(@DrawableRes internal var res: Int) : Element + @Immutable data class Chip( internal var text: TextReference, @@ -54,6 +57,7 @@ data class MessageBottomSheetUMV2( @Immutable data class InfoBlock( internal var icon: Icon? = null, + internal var iconImage: IconImage? = null, internal var chip: Chip? = null, var title: TextReference? = null, var body: TextReference? = null, @@ -106,6 +110,10 @@ fun MessageBottomSheetUMV2.InfoBlock.icon(@DrawableRes res: Int, init: MessageBo icon = MessageBottomSheetUMV2.Icon(res).apply(init) } +fun MessageBottomSheetUMV2.InfoBlock.iconImage(@DrawableRes res: Int) = apply { + iconImage = MessageBottomSheetUMV2.IconImage(res) +} + fun MessageBottomSheetUMV2.InfoBlock.chip(text: TextReference, init: MessageBottomSheetUMV2.Chip.() -> Unit = {}) = apply { chip = MessageBottomSheetUMV2.Chip(text).apply(init) diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetV2.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetV2.kt index cb3f2c538d..7b3ab2dd0b 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetV2.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/message/MessageBottomSheetV2.kt @@ -1,14 +1,18 @@ package com.tangem.core.ui.components.bottomsheets.message +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -88,9 +92,7 @@ fun MessageBottomSheetV2Content(state: MessageBottomSheetUMV2, modifier: Modifie @Composable private fun ContentContainer(state: MessageBottomSheetUMV2.InfoBlock, modifier: Modifier = Modifier) { Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) { - state.icon?.let { - BottomSheetIcon(it) - } + BottomSheetIconContainer(state.icon, state.iconImage) state.title?.let { title -> Text( modifier = Modifier @@ -122,6 +124,26 @@ private fun ContentContainer(state: MessageBottomSheetUMV2.InfoBlock, modifier: } } +@Suppress("CanBeNonNullable") +@Composable +private fun BottomSheetIconContainer( + icon: MessageBottomSheetUMV2.Icon?, + iconImage: MessageBottomSheetUMV2.IconImage?, + modifier: Modifier = Modifier, +) { + if (icon != null) { + BottomSheetIcon(icon, modifier) + } else if (iconImage != null) { + Image( + modifier = modifier + .size(TangemTheme.dimens.size56) + .clip(CircleShape), + painter = painterResource(id = iconImage.res), + contentDescription = null, + ) + } +} + @Composable private fun BottomSheetIcon(icon: MessageBottomSheetUMV2.Icon, modifier: Modifier = Modifier) { val tint = when (icon.type) { @@ -236,4 +258,33 @@ private fun Preview() { onDismissRequest = {}, ) } +} + +@Preview +@Composable +private fun Preview2() { + TangemThemePreview { + MessageBottomSheetV2( + messageBottomSheetUM { + infoBlock { + iconImage = MessageBottomSheetUMV2.IconImage(R.drawable.img_visa_notification) + title = TextReference.Str("Title Title Title") + body = TextReference.Str("Body") + chip(text = TextReference.Str("Some chip information")) + } + primaryButton { + text = TextReference.Str("Test") + icon = R.drawable.ic_tangem_24 + } + secondaryButton { + icon = R.drawable.ic_tangem_24 + text = TextReference.Str("asdasd") + onClick { + closeBs() + } + } + }, + onDismissRequest = {}, + ) + } } \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt index e11aa1c09b..79fed1dc36 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultOnboardingRepository.kt @@ -4,6 +4,7 @@ import arrow.core.Either import com.tangem.datasource.api.pay.TangemPayApi import com.tangem.datasource.api.pay.models.request.DeeplinkValidityRequest import com.tangem.datasource.api.pay.models.request.OrderRequest +import com.tangem.datasource.api.pay.models.request.SetTangemPayEnabledRequest import com.tangem.datasource.api.pay.models.response.CustomerMeResponse import com.tangem.datasource.local.visa.TangemPayCardFrozenStateStore import com.tangem.datasource.local.visa.TangemPayStorage @@ -180,9 +181,10 @@ internal class DefaultOnboardingRepository @Inject constructor( ) }.map { response -> val id = response.result?.id - val isPaeraCustomer = !id.isNullOrEmpty() - tangemPayStorage.storeCheckCustomerWalletResult(userWalletId = userWalletId, isPaeraCustomer) - isPaeraCustomer + val isTangemPayEnabled = response.result?.isTangemPayEnabled == true + val shouldShowTangemPayBlock = !id.isNullOrEmpty() && isTangemPayEnabled + tangemPayStorage.storeCheckCustomerWalletResult(userWalletId = userWalletId, shouldShowTangemPayBlock) + shouldShowTangemPayBlock }.mapLeft { error -> if (error is VisaApiError.NotPaeraCustomer) { tangemPayStorage.storeCheckCustomerWalletResult(userWalletId = userWalletId, false) @@ -205,4 +207,17 @@ internal class DefaultOnboardingRepository @Inject constructor( override suspend fun setHideMainOnboardingBanner(userWalletId: UserWalletId) { tangemPayStorage.storeHideOnboardingBanner(userWalletId, hide = true) } + + override suspend fun disableTangemPay(userWalletId: UserWalletId): Either { + return requestHelper.performRequest(userWalletId) { authHeader -> + tangemPayApi.setTangemPayEnabledStatus( + authHeader = authHeader, + body = SetTangemPayEnabledRequest(isTangemPayEnabled = false), + ) + }.onRight { + val address = requestHelper.getCustomerWalletAddress(userWalletId) + tangemPayStorage.clearAll(userWalletId = userWalletId, customerWalletAddress = address) + setHideMainOnboardingBanner(userWalletId) + } + } } \ No newline at end of file diff --git a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt index 18401f9621..11760b5e2f 100644 --- a/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt +++ b/domain/tokens/src/main/kotlin/com/tangem/domain/tokens/GetWalletTotalBalanceUseCase.kt @@ -26,9 +26,9 @@ class GetWalletTotalBalanceUseCase( private val walletBalanceCache = ConcurrentHashMap() operator fun invoke( - userTallestIds: Collection, + userWalletsIds: Collection, ): LceFlow> { - val flows = userTallestIds.distinct() + val flows = userWalletsIds.distinct() .map { userWalletId -> invoke(userWalletId).map { maybeBalance -> userWalletId to maybeBalance diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt index e3fc78e653..6a304dbfbb 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/OnboardingRepository.kt @@ -32,4 +32,6 @@ interface OnboardingRepository { suspend fun getHideMainOnboardingBanner(userWalletId: UserWalletId): Boolean suspend fun setHideMainOnboardingBanner(userWalletId: UserWalletId) + + suspend fun disableTangemPay(userWalletId: UserWalletId): Either } \ No newline at end of file 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 b00b4b5886..7fc89a52ab 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 @@ -6,11 +6,14 @@ import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.res.R import com.tangem.core.ui.components.bottomsheets.message.* import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.message.DialogMessage +import com.tangem.core.ui.message.EventMessageAction import com.tangem.core.ui.message.bottomSheetMessage import com.tangem.domain.feedback.GetWalletMetaInfoUseCase import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.TangemPayDetailsConfig import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase @@ -26,6 +29,10 @@ internal interface TangemPayIntents { fun onRefreshPayToken(userWalletId: UserWalletId) + fun openDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig) + + fun onKycProgressClicked(userWalletId: UserWalletId) + fun onIssuingCardClicked() fun onIssuingFailedClicked() @@ -47,6 +54,7 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( private val getWalletMetainfoUseCase: GetWalletMetaInfoUseCase, private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase, + private val tangemPayOnboardingRepository: OnboardingRepository, private val uiMessageSender: UiMessageSender, ) : BaseWalletClickIntents(), TangemPayIntents { @@ -67,6 +75,51 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( } } + override fun openDetails(userWalletId: UserWalletId, config: TangemPayDetailsConfig) { + router.openTangemPayDetails( + userWalletId = userWalletId, + config = config, + ) + } + + override fun onKycProgressClicked(userWalletId: UserWalletId) { + val cancelKycConfirmDialogMessage = DialogMessage( + title = resourceReference(R.string.tangempay_kyc_confirm_cancellation_alert_title), + message = resourceReference(R.string.tangempay_kyc_confirm_cancellation_description), + firstAction = EventMessageAction( + title = resourceReference(R.string.common_not_now), + onClick = { }, + ), + secondAction = EventMessageAction( + title = resourceReference(R.string.common_confirm), + onClick = { disableTangemPay(userWalletId) }, + ), + ) + val kycInfoBottomSheet = bottomSheetMessage { + infoBlock { + iconImage(res = com.tangem.core.ui.R.drawable.img_visa_notification) + title = resourceReference(R.string.tangempay_kyc_in_progress) + body = resourceReference(R.string.tangempay_kyc_in_progress_popup_description) + } + primaryButton { + text = resourceReference(R.string.tangempay_kyc_in_progress_notification_button) + onClick = { + router.openTangemPayOnboarding(AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding(userWalletId)) + closeBs() + } + } + secondaryButton { + text = resourceReference(R.string.tangempay_cancel_kyc) + onClick = { + uiMessageSender.send(cancelKycConfirmDialogMessage) + closeBs() + } + } + } + + uiMessageSender.send(kycInfoBottomSheet) + } + override fun onIssuingCardClicked() { val issuingBottomSheet = bottomSheetMessage { infoBlock { @@ -132,4 +185,11 @@ internal class TangemPayClickIntentsImplementor @Inject constructor( onboardingRepository.setHideMainOnboardingBanner(userWalletId) } } + + private fun disableTangemPay(userWalletId: UserWalletId) { + modelScope.launch { + tangemPayOnboardingRepository.disableTangemPay(userWalletId) + .onRight { tangemPayMainScreenCustomerInfoUseCase.fetch(userWalletId) } + } + } } \ No newline at end of file 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 a47a0aec3a..b6ad2482ff 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 @@ -1,5 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.state.transformers +import com.tangem.common.ui.R import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.stringReference import com.tangem.core.ui.format.bigdecimal.fiat @@ -11,11 +12,10 @@ import com.tangem.domain.pay.model.CustomerInfo.ProductInstance import com.tangem.domain.pay.model.MainScreenCustomerInfo import com.tangem.domain.pay.model.OrderStatus import com.tangem.domain.visa.model.TangemPayCardFrozenState +import com.tangem.feature.wallet.child.wallet.model.intents.TangemPayIntents import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState +import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState.Progress import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState -import com.tangem.feature.wallet.presentation.wallet.state.util.TangemPayStateCreator.createCancelledState -import com.tangem.feature.wallet.presentation.wallet.state.util.TangemPayStateCreator.createIssueProgressState -import com.tangem.feature.wallet.presentation.wallet.state.util.TangemPayStateCreator.createKycInProgressState import java.util.Currency /** @@ -26,12 +26,9 @@ private const val POLYGON_CHAIN_ID = 137 internal class TangemPayUpdateInfoStateTransformer( userWalletId: UserWalletId, - private val value: MainScreenCustomerInfo? = null, + private val value: MainScreenCustomerInfo, private val cardFrozenState: TangemPayCardFrozenState, - private val onClickKyc: () -> Unit = {}, - private val onIssuingCard: () -> Unit = {}, - private val onIssuingFailed: () -> Unit = {}, - private val openDetails: (config: TangemPayDetailsConfig) -> Unit = {}, + private val tangemPayClickIntents: TangemPayIntents, ) : WalletStateTransformer(userWalletId = userWalletId) { override fun transform(prevState: WalletState): WalletState { @@ -44,16 +41,15 @@ internal class TangemPayUpdateInfoStateTransformer( } private fun createInitialState(): TangemPayState { - val cardInfo = value?.info?.cardInfo - val productInstance = value?.info?.productInstance + val cardInfo = value.info.cardInfo + val productInstance = value.info.productInstance // when statement copied to WalletTangemPayAnalyticsEventSender. Be careful when editing. return when { - value == null -> TangemPayState.Empty - value.orderStatus == OrderStatus.CANCELED -> createCancelledState(onIssuingFailed) - !value.info.isKycApproved -> createKycInProgressState(onClickKyc) + value.orderStatus == OrderStatus.CANCELED -> createCancelledState() + !value.info.isKycApproved -> createKycInProgressState() cardInfo != null && productInstance != null -> getCardInfoState(cardInfo, productInstance) - else -> createIssueProgressState(onIssuingCard) + else -> createIssueProgressState() } } @@ -63,7 +59,8 @@ internal class TangemPayUpdateInfoStateTransformer( balanceText = TextReference.Str(getBalanceText(cardInfo)), balanceSymbol = stringReference("USDC"), // TODO hardcode for now onClick = { - openDetails( + tangemPayClickIntents.openDetails( + userWalletId, TangemPayDetailsConfig( cardId = productInstance.cardId, isPinSet = cardInfo.isPinSet, @@ -82,4 +79,28 @@ internal class TangemPayUpdateInfoStateTransformer( fiat(fiatCurrencyCode = currency.currencyCode, fiatCurrencySymbol = currency.symbol) } } + + private fun createKycInProgressState(): TangemPayState = Progress( + title = TextReference.Res(R.string.tangempay_payment_account), + description = TextReference.Res(R.string.tangempay_kyc_in_progress), + buttonText = TextReference.Res(R.string.tangempay_kyc_in_progress_notification_button), + iconRes = R.drawable.ic_promo_kyc_36, + onButtonClick = { tangemPayClickIntents.onKycProgressClicked(userWalletId) }, + ) + + private fun createIssueProgressState(): TangemPayState = Progress( + title = TextReference.Res(R.string.tangempay_payment_account), + description = TextReference.Res(R.string.tangempay_issuing_your_card), + buttonText = TextReference.EMPTY, + iconRes = R.drawable.ic_tangem_pay_promo_card_36, + onButtonClick = tangemPayClickIntents::onIssuingCardClicked, + showProgress = true, + ) + + private fun createCancelledState(): 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, + ) } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/util/TangemPayStateCreator.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/util/TangemPayStateCreator.kt deleted file mode 100644 index 51b584d38f..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/util/TangemPayStateCreator.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.tangem.feature.wallet.presentation.wallet.state.util - -import com.tangem.common.ui.R -import com.tangem.core.ui.extensions.TextReference -import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState -import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState.Progress - -internal object TangemPayStateCreator { - - fun createKycInProgressState(onClickKyc: () -> Unit): TangemPayState = Progress( - title = TextReference.Res(R.string.tangempay_payment_account), - description = TextReference.Res(R.string.tangempay_kyc_in_progress), - buttonText = TextReference.Res(R.string.tangempay_kyc_in_progress_notification_button), - iconRes = R.drawable.ic_promo_kyc_36, - onButtonClick = onClickKyc, - ) - - fun createIssueProgressState(onIssuingCardClick: () -> Unit): TangemPayState = Progress( - title = TextReference.Res(R.string.tangempay_payment_account), - description = TextReference.Res(R.string.tangempay_issuing_your_card), - buttonText = TextReference.EMPTY, - iconRes = R.drawable.ic_tangem_pay_promo_card_36, - onButtonClick = onIssuingCardClick, - showProgress = true, - ) - - fun createCancelledState(onIssueFailedClick: () -> Unit): 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 = onIssueFailedClick, - ) -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TangemPayMainSubscriber.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TangemPayMainSubscriber.kt index 6a7cf0a950..8b890929a2 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TangemPayMainSubscriber.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/subscribers/TangemPayMainSubscriber.kt @@ -1,6 +1,5 @@ package com.tangem.feature.wallet.presentation.wallet.subscribers -import com.tangem.common.routing.AppRoute import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.model.MainCustomerInfoContentState @@ -10,7 +9,6 @@ import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase import com.tangem.domain.visa.model.TangemPayCardFrozenState import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents -import com.tangem.feature.wallet.presentation.router.InnerWalletRouter import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletTangemPayAnalyticsEventSender import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.transformers.* @@ -28,7 +26,6 @@ internal class TangemPayMainSubscriber @AssistedInject constructor( @Assisted private val userWallet: UserWallet, private val stateController: WalletStateController, private val clickIntents: WalletClickIntents, - private val innerWalletRouter: InnerWalletRouter, private val cardDetailsRepository: TangemPayCardDetailsRepository, private val tangemPayMainScreenCustomerInfoUseCase: TangemPayMainScreenCustomerInfoUseCase, private val analytics: WalletTangemPayAnalyticsEventSender, @@ -102,19 +99,7 @@ internal class TangemPayMainSubscriber @AssistedInject constructor( userWalletId = userWalletId, value = data, cardFrozenState = cardFrozenState, - onClickKyc = { - innerWalletRouter.openTangemPayOnboarding( - mode = AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding(userWalletId), - ) - }, - onIssuingCard = clickIntents::onIssuingCardClicked, - onIssuingFailed = clickIntents::onIssuingFailedClicked, - openDetails = { config -> - innerWalletRouter.openTangemPayDetails( - userWalletId = userWalletId, - config = config, - ) - }, + tangemPayClickIntents = clickIntents, ), ) }