diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 38b59392d3..eeb613a920 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -2015,6 +2015,7 @@
We\'ll set up a wallet
Get your Tangem Pay Card in minutes
Pay Support
+ Select plan
Payment account
Session expired
Invalid PIN: avoid sequences or repeats
diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt
index 77beec76bc..5f184ef3ce 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverter.kt
@@ -68,6 +68,7 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
)
// Transient statuses are not persisted
is PaymentAccountStatusValue.Loading,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
is PaymentAccountStatusValue.Error.ExposedDevice,
is PaymentAccountStatusValue.Error.Unavailable,
is PaymentAccountStatusValue.Error.NotSynced,
diff --git a/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt b/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt
index 25a40bb989..386ef7303b 100644
--- a/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt
+++ b/data/visa/src/test/kotlin/com/tangem/data/pay/converter/PaymentAccountStatusValueDMConverterTest.kt
@@ -103,6 +103,21 @@ internal class PaymentAccountStatusValueDMConverterTest {
assertThat(result).isNull()
}
+ @Test
+ fun `GIVEN domain AwaitingPlanSelection WHEN convert THEN returns null (transient, not persisted)`() {
+ // GIVEN
+ val domain = PaymentAccountStatusValue.AwaitingPlanSelection(
+ source = StatusSource.ACTUAL,
+ tariffPlan = null,
+ )
+
+ // WHEN
+ val result = converter.convert(domain)
+
+ // THEN
+ assertThat(result).isNull()
+ }
+
@Test
fun `GIVEN domain Error Unavailable WHEN convert THEN returns null (transient, not persisted)`() {
// GIVEN
diff --git a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt
index 5433fc0409..4b1037eb1b 100644
--- a/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt
+++ b/domain/account/status/src/main/java/com/tangem/domain/account/status/usecase/IsAccountsModeEnabledUseCase.kt
@@ -108,6 +108,7 @@ class IsAccountsModeEnabledUseCase(
-> false
is PaymentAccountStatusValue.Error,
is PaymentAccountStatusValue.IssuingCard,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
is PaymentAccountStatusValue.Loaded,
is PaymentAccountStatusValue.Loading,
is PaymentAccountStatusValue.UnderReview,
diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt
index 4c38b2adc2..6240266c9c 100644
--- a/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt
+++ b/domain/models/src/main/kotlin/com/tangem/domain/models/account/PaymentAccountStatusValue.kt
@@ -27,6 +27,7 @@ sealed class PaymentAccountStatusValue {
get() = when (this) {
is Error,
is IssuingCard,
+ is AwaitingPlanSelection,
is Empty,
is NotCreated,
is UnderReview,
@@ -54,6 +55,7 @@ sealed class PaymentAccountStatusValue {
is UnderReview -> copy(source = source)
is Deactivated -> copy(source = source, error = error ?: this.error)
is Loading,
+ is AwaitingPlanSelection,
is Empty,
is NotCreated,
is Error,
@@ -101,6 +103,19 @@ sealed class PaymentAccountStatusValue {
@Serializable
data class IssuingCard(override val source: StatusSource) : PaymentAccountStatusValue()
+ /**
+ * Represents a state where KYC is approved but no tariff plan has been selected yet
+ *
+ * @property source The source of the status information.
+ * @property tariffPlan Current tariff plan (fallback Basic) if the backend already returns one
+ * Transient: not persisted in the local cache.
+ */
+ @Serializable
+ data class AwaitingPlanSelection(
+ override val source: StatusSource,
+ val tariffPlan: TangemPayCustomerTariffPlan?,
+ ) : PaymentAccountStatusValue()
+
/**
* Represents a state where the account is deactivated.
*
diff --git a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt
index 84238b8387..dc1253f1df 100644
--- a/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt
+++ b/features/common-features/impl/src/main/java/com/tangem/features/commonfeatures/impl/choosetoken/converter/ChooseTokenListItemConverter.kt
@@ -182,6 +182,7 @@ internal class ChooseTokenListItemConverter(
val paymentCurrency: CryptoCurrencyStatus = when (val status = this.value) {
is PaymentAccountStatusValue.Error,
is PaymentAccountStatusValue.IssuingCard,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
PaymentAccountStatusValue.NotCreated,
is PaymentAccountStatusValue.UnderReview,
PaymentAccountStatusValue.Loading,
diff --git a/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt b/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt
index 977ce0927e..0998520796 100644
--- a/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt
+++ b/features/tangempay/main/api/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayMainUM.kt
@@ -8,6 +8,7 @@ sealed class TangemPayMainUM {
data object Empty : TangemPayMainUM()
data object Loading : TangemPayMainUM()
+ data class SelectPlan(val onClick: () -> Unit) : TangemPayMainUM()
data class UnderReview(val subtitle: TextReference, val onClick: () -> Unit) : TangemPayMainUM()
data class IssuingCard(val onClick: () -> Unit) : TangemPayMainUM()
data class FailedToIssue(val onClick: () -> Unit) : TangemPayMainUM()
diff --git a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt
index ec5d9d03c8..bdb78bf1a1 100644
--- a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt
+++ b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContent.kt
@@ -50,6 +50,11 @@ internal fun TangemPayMainBlockContent(
when (state) {
is TangemPayMainUM.Empty -> Unit
is TangemPayMainUM.Loading -> TangemPayMainLoading(modifier)
+ is TangemPayMainUM.SelectPlan -> TangemPayStateRow(
+ subtitle = resourceReference(R.string.tangempay_main_select_plan),
+ modifier = modifier,
+ onClick = state.onClick,
+ )
is TangemPayMainUM.UnderReview -> TangemPayStateRow(
subtitle = state.subtitle,
modifier = modifier,
@@ -303,6 +308,7 @@ private class TangemPayMainBlockContentPreviewParameterProvider : CollectionPrev
TangemPayMainUM.ExposedDevice,
TangemPayMainUM.FailedToIssue(onClick = {}),
TangemPayMainUM.UnderReview(subtitle = resourceReference(R.string.tangempay_kyc_in_progress), onClick = {}),
+ TangemPayMainUM.SelectPlan(onClick = {}),
TangemPayMainUM.IssuingCard(onClick = {}),
TangemPayMainUM.Content(
subtitle = TextReference.Str("*1234"),
diff --git a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt
index f72aecb6f4..3a5ba77e2e 100644
--- a/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt
+++ b/features/tangempay/main/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangemPayMainBlockContentLegacy.kt
@@ -42,6 +42,7 @@ internal fun TangemPayMainBlockItem(state: TangemPayMainUM, isBalanceHidden: Boo
when (state) {
is TangemPayMainUM.Empty -> Unit
is TangemPayMainUM.Loading -> TangemPayMainLoadingItem(modifier)
+ is TangemPayMainUM.SelectPlan -> TangemPayMainSelectPlanItem(state, modifier)
is TangemPayMainUM.UnderReview -> TangemPayMainUnderReviewItem(state, modifier)
is TangemPayMainUM.IssuingCard -> TangemPayMainIssuingCardItem(state, modifier)
is TangemPayMainUM.FailedToIssue -> TangemPayMainFailedIssueItem(state, modifier)
@@ -194,6 +195,25 @@ private fun TangemPayMainTempUnavailableItem(modifier: Modifier = Modifier) {
}
}
+@Composable
+private fun TangemPayMainSelectPlanItem(state: TangemPayMainUM.SelectPlan, modifier: Modifier = Modifier) {
+ BlockCard(
+ modifier = modifier
+ .clip(RoundedCornerShape(size = TangemTheme.dimens.radius14))
+ .background(TangemTheme.colors.background.primary),
+ onClick = state.onClick,
+ ) {
+ InputRowImageBase(
+ modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
+ subtitle = resourceReference(R.string.tangempay_payment_account),
+ caption = resourceReference(R.string.tangempay_main_select_plan),
+ subtitleColor = TangemTheme.colors.text.primary1,
+ captionColor = TangemTheme.colors.text.tertiary,
+ iconResWebp = R.drawable.img_visa_36,
+ )
+ }
+}
+
@Composable
private fun TangemPayMainIssuingCardItem(state: TangemPayMainUM.IssuingCard, modifier: Modifier = Modifier) {
BlockCard(
@@ -344,6 +364,7 @@ private class TangemPayMainUMPreviewParameterProvider : CollectionPreviewParamet
TangemPayMainUM.ExposedDevice,
TangemPayMainUM.FailedToIssue(onClick = {}),
TangemPayMainUM.UnderReview(subtitle = resourceReference(R.string.tangempay_kyc_in_progress), onClick = {}),
+ TangemPayMainUM.SelectPlan(onClick = {}),
TangemPayMainUM.IssuingCard(onClick = {}),
TangemPayMainUM.Content(
subtitle = TextReference.Str("*1234"),
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 83770da949..5c5652c633 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
@@ -42,6 +42,8 @@ internal interface TangemPayIntents {
fun openDetails(status: AccountStatus.Payment)
+ fun onSelectPlanClicked(status: AccountStatus.Payment)
+
fun onKycProgressClicked(userWalletId: UserWalletId)
fun onKycRejectedClicked(userWalletId: UserWalletId, customerId: String)
@@ -114,6 +116,10 @@ internal class TangemPayClickIntentsImplementor @Inject constructor(
router.openTangemPayDetails(status = status)
}
+ override fun onSelectPlanClicked(status: AccountStatus.Payment) {
+ router.openTangemPaySelectPlan(status = status)
+ }
+
override fun onKycProgressClicked(userWalletId: UserWalletId) {
val cancelKycConfirmDialogMessage = DialogMessage(
title = resourceReference(R.string.tangempay_kyc_confirm_cancellation_alert_title),
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
index 10e80ff7c5..c97cb0afee 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt
@@ -158,6 +158,10 @@ internal class DefaultWalletRouter @Inject constructor(
router.push(AppRoute.TangemPayDetails(status = status))
}
+ override fun openTangemPaySelectPlan(status: AccountStatus.Payment) {
+ // TODO v_rodionov: [REDACTED_TASK_KEY] Tiers Onboarding - part 2
+ }
+
override fun openYieldSupplyBottomSheet(
cryptoCurrency: CryptoCurrency,
tokenAction: TokenAction,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt
index eed653fcfe..5258923d61 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt
@@ -84,6 +84,8 @@ internal interface InnerWalletRouter {
fun openTangemPayDetails(status: AccountStatus.Payment)
+ fun openTangemPaySelectPlan(status: AccountStatus.Payment)
+
/** Open BS abput yield supply active and all money deposited in AAVE */
fun openYieldSupplyBottomSheet(
cryptoCurrency: CryptoCurrency,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt
index bd8b2197a6..373932d2ef 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/analytics/utils/WalletTangemPayAnalyticsEventSender.kt
@@ -26,6 +26,7 @@ internal class WalletTangemPayAnalyticsEventSender @Inject constructor(
PaymentAccountStatusValue.Loading,
PaymentAccountStatusValue.NotCreated,
is PaymentAccountStatusValue.UnderReview,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
is PaymentAccountStatusValue.Deactivated,
-> return
}
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt
index 192bb989bc..f0c06b23eb 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetMultiWalletWarningsFactory.kt
@@ -236,6 +236,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
is PaymentAccountStatusValue.Error.CardIssueFailed,
is PaymentAccountStatusValue.Error.ExposedDevice,
is PaymentAccountStatusValue.IssuingCard,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
is PaymentAccountStatusValue.Loaded,
is PaymentAccountStatusValue.Loading,
is PaymentAccountStatusValue.UnderReview,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt
index 003cfb3498..e1f9cf149f 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/GetWalletNotificationsFactory.kt
@@ -284,6 +284,7 @@ internal class GetWalletNotificationsFactory @Inject constructor(
is PaymentAccountStatusValue.Error.CardIssueFailed,
is PaymentAccountStatusValue.Error.ExposedDevice,
is PaymentAccountStatusValue.IssuingCard,
+ is PaymentAccountStatusValue.AwaitingPlanSelection,
is PaymentAccountStatusValue.Loaded,
is PaymentAccountStatusValue.Loading,
is PaymentAccountStatusValue.UnderReview,
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt
index d44992bdbd..2d99c25335 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/converter/TangemPayMainBlockConverter.kt
@@ -35,6 +35,9 @@ internal class TangemPayMainBlockConverter(
is PaymentAccountStatusValue.IssuingCard -> TangemPayMainUM.IssuingCard(
onClick = { tangemPayClickIntents.onIssuingCardClicked() },
)
+ is PaymentAccountStatusValue.AwaitingPlanSelection -> TangemPayMainUM.SelectPlan(
+ onClick = { tangemPayClickIntents.onSelectPlanClicked(value) },
+ )
is PaymentAccountStatusValue.UnderReview -> TangemPayMainUM.UnderReview(
subtitle = when (statusValue.kycStatus) {
KycStatus.REJECTED -> TextReference.Res(R.string.tangempay_kyc_has_failed)