diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 7806491a95..18fff34c69 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -1677,7 +1677,7 @@
Unable to rename card
Card frozen
Card payment
- It will disappear from payment account
+ It will disappear from the app
Close card
Go back
Close your card?
@@ -1698,6 +1698,7 @@
MCC %s
Other
PIN-code
+ Purchase
Unable to use on rooted devices
Completed
Declined
@@ -1706,6 +1707,8 @@
Terms, Fees & Limits
Terms and fees
The bank rejected this transaction request.
+ Category
+ MCC
A fee is charged in accordance with the service tariffs
The transaction was partially or fully reversed by the merchant
Keep using your money. You can freeze anytime.
@@ -1824,6 +1827,24 @@
your profile.
You can have up to 3 cards. Delete one to add a new card.
Maximum Cards Issued
+ Yes – to operate a regulated Visa card, identity verification is mandatory. KYC is handled by Sumsub (compliance partner).
+ Do I have to share my docs?
+ No. KYC applies only to the Tangem Pay account. Your Tangem Wallet itself remains a separate, self-custodial, non-KYC environment.
+ Does the KYC associate with my wallet?
+ Sumsub – a globally regulated KYC provider, trusted by 4,000+ financial institutions – verifies your identity and securely stores the results under ISO 27001 and SOC 2 standards.
+ Who stores my personal data and how is it protected?
+ Card balance nominated in USDC on Polygon, but you can use any asset (USDT, SOL, ETH, BTC, XRP etc.) to fund it using Tangem\'s convenient built-in swap mechanisms.
+ What crypto can I spend?
+ Spend crypto anywhere — no banks, no middlemen, no exchanges. The power of self-custody meets everyday payments.
+ Buy online and via Apple Pay
+ Accepted worldwide
+ Use anywhere in the world
+ FX fee is just 1%
+ Get your Tangem Pay Card
+ Pay what you see
+ No purchase fees, \n1 USDC = 1 USD
+ No surprises
+ $0 monthly fee\n$0 topup fee
Get your free Tangem Visa virtual card
Use USDC for everyday payments
Get card
@@ -1852,16 +1873,16 @@
Replace your card?
We’re fixing a technical issue. Please try again later.
Service temporarily unavailable
- Unable to display details. However, card payments are still working.
+ The service is currently unreachable. Please try again later.
Set \nPIN code
- Card deactivated
+ Account closed
Replacing your card
Use your card or ring to renew session
Use your card or ring to renew session
Renew session
Payment account session expired
Use USDC for everyday payments
- Tangem Pay is temporarily unreachable
+ Tangem Pay is temporarily unavailable
Tangem Pay
Send USDC Polygon to your account’s address
From another wallet or exchange
diff --git a/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt b/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt
index 8a6e16455b..126d853eb8 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/ds2/surface/TangemSurface.kt
@@ -1,21 +1,14 @@
package com.tangem.core.ui.ds2.surface
-import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.LocalIndication
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
+import androidx.compose.foundation.*
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.RippleAlpha
import androidx.compose.material3.LocalRippleConfiguration
import androidx.compose.material3.RippleConfiguration
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.NonRestartableComposable
-import androidx.compose.runtime.ReadOnlyComposable
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
@@ -94,6 +87,7 @@ fun TangemSurface(
onClick = onClick!!,
)
},
+ contentAlignment = Alignment.Center,
) {
content()
}
diff --git a/core/ui/src/main/res/drawable/ic_replace_20.xml b/core/ui/src/main/res/drawable/ic_replace_20.xml
deleted file mode 100644
index 3fdf7b9e3d..0000000000
--- a/core/ui/src/main/res/drawable/ic_replace_20.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt
index 3512628da8..0ea33aafcd 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt
@@ -7,5 +7,6 @@ internal class DefaultTangemPayFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) : TangemPayFeatureToggles {
override val isRedesignEnabled: Boolean
- get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15368_VISA_PAY_REDESIGN)
+ get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_15368_VISA_PAY_REDESIGN) &&
+ featureTogglesManager.isFeatureEnabled(FeatureToggles.APP_REDESIGN_ENABLED)
}
\ No newline at end of file
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 b0a795d1af..5b6e5d8793 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
@@ -5,9 +5,12 @@ import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
+import com.tangem.core.ui.res.LocalVisaRedesignEnabled
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiState
import com.tangem.features.tangempay.model.TangemPayTxHistoryDetailsModel
import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContent
+import com.tangem.features.tangempay.ui.TangemPayTxHistoryDetailsContentV2
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -25,8 +28,15 @@ internal class TangemPayTxHistoryDetailsComponent @AssistedInject constructor(
@Composable
override fun BottomSheet() {
- val state by model.uiState.collectAsStateWithLifecycle()
- TangemPayTxHistoryDetailsContent(state = state)
+ val states by model.uiState.collectAsStateWithLifecycle()
+ when (val uiState = states.toUiState(isRedesignEnabled = LocalVisaRedesignEnabled.current)) {
+ is TangemPayTxHistoryDetailsUiState.Legacy -> {
+ TangemPayTxHistoryDetailsContent(state = uiState.state)
+ }
+ is TangemPayTxHistoryDetailsUiState.Redesign -> {
+ TangemPayTxHistoryDetailsContentV2(state = uiState.state)
+ }
+ }
}
@AssistedFactory
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt
index b240e9c159..aa732fd535 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/entity/TangemPayTxHistoryDetailsUM.kt
@@ -1,7 +1,9 @@
package com.tangem.features.tangempay.entity
+import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.notifications.NotificationConfig
+import com.tangem.core.ui.ds.image.TangemIconUM
import com.tangem.core.ui.extensions.ColorReference
import com.tangem.core.ui.extensions.ImageReference
import com.tangem.core.ui.extensions.TextReference
@@ -28,6 +30,58 @@ internal data class TangemPayTxHistoryDetailsUM(
val iconTint: ColorReference,
val containerColor: ColorReference?,
)
+}
- data class ButtonState(val text: TextReference, val onClick: () -> Unit, val startIcon: ImageReference.Res? = null)
+internal data class ButtonState(
+ val text: TextReference,
+ val onClick: () -> Unit,
+ val startIcon: ImageReference.Res? = null,
+)
+
+internal data class TangemPayTxHistoryDetailsUMV2(
+ val isBalanceHidden: Boolean,
+ val title: TextReference,
+ val subtitle: TextReference,
+ val iconState: TangemIconUM,
+ val transactionTitle: TextReference,
+ val transactionCategory: TextReference,
+ val mcc: TextReference?,
+ val transactionAmount: String,
+ val localTransactionText: String?,
+ val label: TransactionLabelUM?,
+ val buttonState: ButtonState,
+ val dismiss: () -> Unit,
+)
+
+internal data class TransactionLabelUM(
+ val transactionStateType: TransactionStateType,
+ val icon: TangemIconUM,
+ val title: TextReference,
+ val subtitle: TextReference? = null,
+)
+
+internal enum class TransactionStateType {
+ Completed,
+ InProgress,
+ Rejected,
+ Reversed,
+}
+
+@Immutable
+internal sealed interface TangemPayTxHistoryDetailsUiState {
+ data class Legacy(val state: TangemPayTxHistoryDetailsUM) : TangemPayTxHistoryDetailsUiState
+ data class Redesign(val state: TangemPayTxHistoryDetailsUMV2) : TangemPayTxHistoryDetailsUiState
+}
+
+internal data class TangemPayTxHistoryDetailsUiStates(
+ val legacy: TangemPayTxHistoryDetailsUM,
+ val redesign: TangemPayTxHistoryDetailsUMV2,
+) {
+ fun toUiState(isRedesignEnabled: Boolean): TangemPayTxHistoryDetailsUiState {
+ return if (isRedesignEnabled) {
+ TangemPayTxHistoryDetailsUiState.Redesign(redesign)
+ } else {
+ TangemPayTxHistoryDetailsUiState.Legacy(legacy)
+ }
+ }
}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt
index cae5f6b219..97dcffc0fd 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt
@@ -21,6 +21,8 @@ import com.tangem.core.ui.format.bigdecimal.getJavaCurrencyByCode
import com.tangem.core.ui.format.bigdecimal.optionalDecimals
import com.tangem.core.ui.message.SnackbarMessage
import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.generated.icons.Icons
+import com.tangem.core.ui.res.generated.icons.ic_arrow_refresh_20
import com.tangem.core.ui.test.TangemPayTestTags
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.TokenReceiveConfig
@@ -222,7 +224,7 @@ internal class TangemPayCardPageModel @Inject constructor(
title = TextReference.Res(R.string.tangempay_card_details_reissue_card),
onClick = ::onClickReissueCard,
icon = TangemIconUM.Icon(
- iconRes = CoreUiR.drawable.ic_replace_20,
+ imageVector = Icons.ic_arrow_refresh_20,
tintReference = {
TangemTheme.colors3.icon.primary
},
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 e430f443af..ca8d041322 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
@@ -14,8 +14,9 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
import com.tangem.domain.feedback.models.FeedbackEmailType
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.features.tangempay.components.TangemPayTransactionBottomSheetComponent
-import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUiStates
import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverter
+import com.tangem.features.tangempay.model.transformers.TangemPayTxHistoryDetailsConverterV2
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
@@ -35,18 +36,8 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
) : Model() {
private val params = paramsContainer.require()
- val uiState: StateFlow
- field = MutableStateFlow(
- value = TangemPayTxHistoryDetailsConverter.convert(
- value = TangemPayTxHistoryDetailsConverter.Input(
- item = params.transaction,
- isBalanceHidden = params.isBalanceHidden,
- onExplorerClick = ::openExplorer,
- onDisputeClick = { dispute(customerId = params.customerId) },
- onDismiss = ::dismiss,
- ),
- ),
- )
+ val uiState: StateFlow
+ field = MutableStateFlow(buildUiStates(isBalanceHidden = params.isBalanceHidden))
init {
subscribeToBalanceHiding()
@@ -58,10 +49,32 @@ internal class TangemPayTxHistoryDetailsModel @Inject constructor(
private fun subscribeToBalanceHiding() {
balanceHidingSettings.isBalanceHidden()
- .onEach { isBalanceHidden -> uiState.update { it.copy(isBalanceHidden = isBalanceHidden) } }
+ .onEach { isBalanceHidden -> uiState.update { buildUiStates(isBalanceHidden) } }
.launchIn(modelScope)
}
+ private fun buildUiStates(isBalanceHidden: Boolean): TangemPayTxHistoryDetailsUiStates {
+ val converterInput = TangemPayTxHistoryDetailsConverter.Input(
+ item = params.transaction,
+ isBalanceHidden = isBalanceHidden,
+ onExplorerClick = ::openExplorer,
+ onDisputeClick = { dispute(customerId = params.customerId) },
+ onDismiss = ::dismiss,
+ )
+ return TangemPayTxHistoryDetailsUiStates(
+ legacy = TangemPayTxHistoryDetailsConverter.convert(converterInput),
+ redesign = TangemPayTxHistoryDetailsConverterV2.convert(
+ value = TangemPayTxHistoryDetailsConverterV2.Input(
+ item = converterInput.item,
+ isBalanceHidden = converterInput.isBalanceHidden,
+ onExplorerClick = converterInput.onExplorerClick,
+ onDisputeClick = converterInput.onDisputeClick,
+ onDismiss = converterInput.onDismiss,
+ ),
+ ),
+ )
+ }
+
private fun openExplorer(txHash: String?) {
txHash?.let(urlOpener::openUrlExternalBrowser)
}
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt
index b15f718595..e4f3db8c2e 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverter.kt
@@ -12,8 +12,8 @@ import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
import com.tangem.features.tangempay.details.impl.R
+import com.tangem.features.tangempay.entity.ButtonState
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
-import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM.ButtonState
import com.tangem.utils.StringsSigns
import com.tangem.utils.converter.Converter
import com.tangem.utils.extensions.isPositive
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverterV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverterV2.kt
new file mode 100644
index 0000000000..7ce966bf8b
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryDetailsConverterV2.kt
@@ -0,0 +1,322 @@
+package com.tangem.features.tangempay.model.transformers
+
+import com.tangem.core.ui.ds.image.TangemIconUM
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.core.ui.format.bigdecimal.fiat
+import com.tangem.core.ui.format.bigdecimal.format
+import com.tangem.core.ui.format.bigdecimal.price
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.generated.icons.*
+import com.tangem.core.ui.utils.DateTimeFormatters
+import com.tangem.domain.visa.model.TangemPayTxHistoryItem
+import com.tangem.features.tangempay.details.impl.R
+import com.tangem.features.tangempay.entity.ButtonState
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2
+import com.tangem.features.tangempay.entity.TransactionLabelUM
+import com.tangem.features.tangempay.entity.TransactionStateType
+import com.tangem.utils.StringsSigns
+import com.tangem.utils.converter.Converter
+import com.tangem.utils.extensions.isPositive
+import com.tangem.utils.extensions.isZero
+
+internal object TangemPayTxHistoryDetailsConverterV2 :
+ Converter {
+ private val dateFormatter = DateTimeFormatters.getBestFormatterBySkeleton("MMM dd yyyy, HH:mm")
+
+ override fun convert(value: Input): TangemPayTxHistoryDetailsUMV2 {
+ val transaction = value.item
+ return TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = value.isBalanceHidden,
+ title = transaction.extractBottomSheetTitle(),
+ subtitle = transaction.extractDate(),
+ iconState = transaction.extractIcon(),
+ transactionTitle = transaction.extractTransactionTitle(),
+ transactionCategory = transaction.extractTransactionCategory(),
+ mcc = transaction.extractMcc(),
+ transactionAmount = transaction.extractAmount(),
+ localTransactionText = transaction.extractLocalAmount(),
+ label = transaction.extractTransactionLabel(),
+ buttonState = value.extractButtonState(),
+ dismiss = value.onDismiss,
+ )
+ }
+
+ private fun TangemPayTxHistoryItem.extractDate(): TextReference {
+ val date = DateTimeFormatters.formatDate(this.date, dateFormatter)
+ return stringReference(date)
+ }
+
+ private fun TangemPayTxHistoryItem.extractBottomSheetTitle(): TextReference {
+ return when (this) {
+ is TangemPayTxHistoryItem.Spend -> resourceReference(R.string.tangem_pay_purchase)
+ is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.tangem_pay_withdrawal)
+ is TangemPayTxHistoryItem.Collateral -> when (this.type) {
+ TangemPayTxHistoryItem.Type.Deposit -> resourceReference(R.string.tangem_pay_deposit)
+ TangemPayTxHistoryItem.Type.Withdrawal -> resourceReference(R.string.tangem_pay_withdrawal)
+ }
+ is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_title)
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractIcon(): TangemIconUM {
+ return when (this) {
+ is TangemPayTxHistoryItem.Collateral -> when (this.type) {
+ TangemPayTxHistoryItem.Type.Deposit -> TangemIconUM.Icon(
+ imageVector = Icons.ic_arrow_down_24,
+ tintReference = {
+ TangemTheme.colors3.icon.secondary
+ },
+ )
+ TangemPayTxHistoryItem.Type.Withdrawal -> TangemIconUM.Icon(
+ imageVector = Icons.ic_arrow_up_24,
+ tintReference = {
+ TangemTheme.colors3.icon.secondary
+ },
+ )
+ }
+ is TangemPayTxHistoryItem.Fee -> {
+ TangemIconUM.Icon(
+ iconRes = R.drawable.ic_percent_24,
+ tintReference = {
+ TangemTheme.colors3.icon.secondary
+ },
+ )
+ }
+ is TangemPayTxHistoryItem.Payment -> TangemIconUM.Icon(
+ imageVector = Icons.ic_arrow_up_24,
+ tintReference = {
+ TangemTheme.colors3.icon.secondary
+ },
+ )
+ is TangemPayTxHistoryItem.Spend -> {
+ val merchantIcon = this.enrichedMerchantIconUrl
+ if (merchantIcon != null) {
+ TangemIconUM.Url(merchantIcon, R.drawable.ic_category_24)
+ } else {
+ TangemIconUM.Icon(
+ iconRes = R.drawable.ic_category_24,
+ tintReference = {
+ TangemTheme.colors3.icon.secondary
+ },
+ )
+ }
+ }
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractTransactionTitle(): TextReference {
+ return when (this) {
+ is TangemPayTxHistoryItem.Spend -> stringReference(this.enrichedMerchantName ?: this.merchantName)
+ is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
+ is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
+ is TangemPayTxHistoryItem.Fee -> {
+ this.description?.let(::stringReference) ?: resourceReference(R.string.tangem_pay_fee_subtitle)
+ }
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractTransactionCategory(): TextReference {
+ return when (this) {
+ is TangemPayTxHistoryItem.Fee -> resourceReference(R.string.tangem_pay_fee_subtitle)
+ is TangemPayTxHistoryItem.Payment -> resourceReference(R.string.common_transfer)
+ is TangemPayTxHistoryItem.Collateral -> resourceReference(R.string.common_transfer)
+ is TangemPayTxHistoryItem.Spend -> extractSpendCategory()
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.Spend.extractSpendCategory(): TextReference {
+ val merchantCategory = merchantCategory
+ val enrichedMerchantCategory = enrichedMerchantCategory
+ return when {
+ !merchantCategory.isNullOrEmpty() -> stringReference(merchantCategory)
+ !enrichedMerchantCategory.isNullOrEmpty() -> stringReference(enrichedMerchantCategory)
+ else -> resourceReference(R.string.tangem_pay_other)
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractMcc(): TextReference? {
+ return when (this) {
+ is TangemPayTxHistoryItem.Spend -> merchantCategoryCode
+ ?.takeIf { it.isNotEmpty() }
+ ?.let(::stringReference)
+ is TangemPayTxHistoryItem.Fee,
+ is TangemPayTxHistoryItem.Payment,
+ is TangemPayTxHistoryItem.Collateral,
+ -> null
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractAmount(): String {
+ return when (this) {
+ is TangemPayTxHistoryItem.Fee,
+ is TangemPayTxHistoryItem.Payment,
+ -> {
+ val amount = this.amount.format {
+ fiat(
+ fiatCurrencyCode = this@extractAmount.currency.currencyCode,
+ fiatCurrencySymbol = this@extractAmount.currency.symbol,
+ )
+ }
+ StringsSigns.MINUS + amount
+ }
+ is TangemPayTxHistoryItem.Spend -> {
+ val amountPrefix = when {
+ this.amount.isZero() -> ""
+ this.status == TangemPayTxHistoryItem.Status.REVERSED -> StringsSigns.MINUS
+ this.status == TangemPayTxHistoryItem.Status.DECLINED ||
+ this.amount.isPositive() -> StringsSigns.MINUS
+ else -> StringsSigns.PLUS
+ }
+ val amount = when (this.status) {
+ TangemPayTxHistoryItem.Status.DECLINED -> this.authorizedAmount
+ else -> this.amount
+ }
+ val formattedAmount = amount.abs().format {
+ fiat(
+ fiatCurrencyCode = this@extractAmount.currency.currencyCode,
+ fiatCurrencySymbol = this@extractAmount.currency.symbol,
+ )
+ }
+ amountPrefix + formattedAmount
+ }
+ is TangemPayTxHistoryItem.Collateral -> {
+ val amountPrefix = when {
+ this.amount.isZero() -> ""
+ this.amount.isPositive() -> StringsSigns.PLUS
+ else -> StringsSigns.MINUS
+ }
+ val amount = this.amount.abs().format {
+ fiat(
+ fiatCurrencyCode = this@extractAmount.currency.currencyCode,
+ fiatCurrencySymbol = this@extractAmount.currency.symbol,
+ )
+ }
+ amountPrefix + amount
+ }
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractLocalAmount(): String? {
+ return when (this) {
+ is TangemPayTxHistoryItem.Collateral,
+ is TangemPayTxHistoryItem.Fee,
+ is TangemPayTxHistoryItem.Payment,
+ -> null
+ is TangemPayTxHistoryItem.Spend -> {
+ val localCurrency = this.localCurrency
+ val localAmount = this.localAmount
+ if (localCurrency != null && localAmount != null && localCurrency != currency) {
+ val amountPrefix = when {
+ localAmount.isZero() -> ""
+ this.status == TangemPayTxHistoryItem.Status.DECLINED ||
+ localAmount.isPositive() -> StringsSigns.MINUS
+ else -> StringsSigns.PLUS
+ }
+ val amount = localAmount.abs().format {
+ fiat(
+ fiatCurrencyCode = localCurrency.currencyCode,
+ fiatCurrencySymbol = localCurrency.symbol,
+ ).price()
+ }
+ amountPrefix + amount
+ } else {
+ null
+ }
+ }
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.extractTransactionLabel(): TransactionLabelUM? {
+ return when (this) {
+ is TangemPayTxHistoryItem.Payment,
+ is TangemPayTxHistoryItem.Collateral,
+ -> {
+ TransactionLabelUM(
+ transactionStateType = TransactionStateType.Completed,
+ icon = TangemIconUM.Icon(
+ imageVector = Icons.ic_success_24,
+ tintReference = { TangemTheme.colors3.icon.status.success },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_completed),
+ )
+ }
+ is TangemPayTxHistoryItem.Fee -> TransactionLabelUM(
+ transactionStateType = TransactionStateType.Completed,
+ icon = TangemIconUM.Icon(
+ imageVector = Icons.ic_success_24,
+ tintReference = { TangemTheme.colors3.icon.status.success },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_completed),
+ subtitle = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
+ )
+ is TangemPayTxHistoryItem.Spend -> when (this.status) {
+ TangemPayTxHistoryItem.Status.COMPLETED -> TransactionLabelUM(
+ transactionStateType = TransactionStateType.Completed,
+ icon = TangemIconUM.Icon(
+ imageVector = Icons.ic_success_24,
+ tintReference = { TangemTheme.colors3.icon.status.success },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_completed),
+ )
+ TangemPayTxHistoryItem.Status.PENDING,
+ TangemPayTxHistoryItem.Status.RESERVED,
+ -> TransactionLabelUM(
+ transactionStateType = TransactionStateType.InProgress,
+ icon = TangemIconUM.Icon(
+ imageVector = Icons.ic_clock_24,
+ tintReference = { TangemTheme.colors3.icon.status.info },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_pending),
+ )
+ TangemPayTxHistoryItem.Status.DECLINED -> TransactionLabelUM(
+ transactionStateType = TransactionStateType.Rejected,
+ icon = TangemIconUM.Icon(
+ iconRes = R.drawable.ic_warning_20,
+ tintReference = { TangemTheme.colors3.icon.status.error },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_declined),
+ subtitle = extractDeclinedSubtitle(),
+ )
+ TangemPayTxHistoryItem.Status.REVERSED -> TransactionLabelUM(
+ transactionStateType = TransactionStateType.Reversed,
+ icon = TangemIconUM.Icon(
+ imageVector = Icons.ic_success_24,
+ tintReference = { TangemTheme.colors3.icon.status.success },
+ ),
+ title = resourceReference(R.string.tangem_pay_status_reversed),
+ subtitle = resourceReference(R.string.tangem_pay_transaction_reversed_notification_text),
+ )
+ TangemPayTxHistoryItem.Status.UNKNOWN -> null
+ }
+ }
+ }
+
+ private fun TangemPayTxHistoryItem.Spend.extractDeclinedSubtitle(): TextReference {
+ return if (declinedReason.isNullOrEmpty()) {
+ resourceReference(R.string.tangem_pay_transaction_declined_notification_text)
+ } else {
+ resourceReference(
+ id = R.string.tangem_pay_history_item_spend_mc_declined_reason,
+ formatArgs = wrappedList(requireNotNull(declinedReason)),
+ )
+ }
+ }
+
+ private fun Input.extractButtonState(): ButtonState {
+ return ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = this.onDisputeClick,
+ )
+ }
+
+ data class Input(
+ val item: TangemPayTxHistoryItem,
+ val isBalanceHidden: Boolean,
+ val onExplorerClick: (String?) -> Unit,
+ val onDisputeClick: () -> Unit,
+ val onDismiss: () -> Unit,
+ )
+}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
index 111edfb273..42f821bf8a 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUi.kt
@@ -30,6 +30,7 @@ import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.tangempay.details.impl.R
+import com.tangem.features.tangempay.entity.ButtonState
import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUM
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@@ -115,10 +116,7 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
}
@Composable
-private fun ButtonsContainer(
- buttons: ImmutableList,
- modifier: Modifier = Modifier,
-) {
+private fun ButtonsContainer(buttons: ImmutableList, modifier: Modifier = Modifier) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(8.dp),
@@ -179,7 +177,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
),
notification = null,
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
@@ -210,7 +208,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
),
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
@@ -232,7 +230,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
),
notification = null,
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
@@ -260,7 +258,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
containerColor = null,
),
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_dispute),
onClick = {},
),
@@ -279,7 +277,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
labelState = null,
notification = null,
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_get_help),
onClick = {},
),
@@ -298,7 +296,7 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
labelState = null,
notification = null,
buttons = persistentListOf(
- TangemPayTxHistoryDetailsUM.ButtonState(
+ ButtonState(
text = resourceReference(R.string.tangem_pay_get_help),
onClick = {},
),
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt
new file mode 100644
index 0000000000..3629c40907
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/ui/TangempayTxDetailsUiV2.kt
@@ -0,0 +1,389 @@
+package com.tangem.features.tangempay.ui
+
+import android.content.res.Configuration
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.TextAutoSize
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Devices
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import com.tangem.core.ui.components.SpacerW
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
+import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetType
+import com.tangem.core.ui.ds.image.TangemIcon
+import com.tangem.core.ui.ds.image.TangemIconUM
+import com.tangem.core.ui.ds.topbar.TangemTopBar
+import com.tangem.core.ui.ds.topbar.TangemTopBarType
+import com.tangem.core.ui.ds2.button.TangemButton
+import com.tangem.core.ui.ds2.row.TangemRow
+import com.tangem.core.ui.ds2.row.TangemRowContentLead
+import com.tangem.core.ui.ds2.row.TangemRowText
+import com.tangem.core.ui.ds2.row.TangemRowTextRole
+import com.tangem.core.ui.extensions.orMaskWithStars
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreviewRedesign
+import com.tangem.core.ui.res.generated.icons.Icons
+import com.tangem.core.ui.res.generated.icons.ic_arrow_down_24
+import com.tangem.features.tangempay.details.impl.R
+import com.tangem.features.tangempay.entity.ButtonState
+import com.tangem.features.tangempay.entity.TangemPayTxHistoryDetailsUMV2
+import com.tangem.features.tangempay.entity.TransactionLabelUM
+import com.tangem.features.tangempay.entity.TransactionStateType
+
+@Suppress("LongMethod")
+@Composable
+internal fun TangemPayTxHistoryDetailsContentV2(state: TangemPayTxHistoryDetailsUMV2) {
+ TangemBottomSheet(
+ config = TangemBottomSheetConfig(
+ isShown = true,
+ onDismissRequest = state.dismiss,
+ content = TangemBottomSheetConfigContent.Empty,
+ ),
+ type = TangemBottomSheetType.Modal,
+ containerColor = TangemTheme.colors3.bg.secondary,
+ title = {
+ TangemTopBar(
+ title = state.title,
+ subtitle = state.subtitle,
+ type = TangemTopBarType.BottomSheet,
+ endContent = {
+ TangemButton(
+ iconStart = TangemIconUM.Icon(iconRes = R.drawable.ic_close_24),
+ onClick = state.dismiss,
+ size = TangemButton.Size.X11,
+ variant = TangemButton.Variant.Material,
+ )
+ },
+ )
+ },
+ content = {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .verticalScroll(rememberScrollState())
+ .padding(horizontal = TangemTheme.dimens2.x4)
+ .padding(bottom = TangemTheme.dimens2.x4),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ TransactionIcon(
+ iconState = state.iconState,
+ modifier = Modifier.padding(top = TangemTheme.dimens2.x12),
+ )
+ Text(
+ modifier = Modifier.padding(top = TangemTheme.dimens2.x6),
+ text = state.transactionAmount.orMaskWithStars(state.isBalanceHidden),
+ style = TangemTheme.typography3.display.medium,
+ color = TangemTheme.colors3.text.primary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ autoSize = TextAutoSize.StepBased(
+ minFontSize = TangemTheme.typography3.body.medium.fontSize,
+ maxFontSize = TangemTheme.typography3.display.medium.fontSize,
+ ),
+ )
+ TransactionSecondaryLine(
+ state = state,
+ modifier = Modifier.padding(top = TangemTheme.dimens2.x1),
+ )
+ if (state.label != null) {
+ TransactionLabel(
+ label = state.label,
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens2.x12)
+ .fillMaxWidth(),
+ )
+ }
+ TransactionDetailsBlock(
+ state = state,
+ modifier = Modifier
+ .padding(top = TangemTheme.dimens2.x4, bottom = TangemTheme.dimens2.x2)
+ .fillMaxWidth(),
+ )
+ TangemButton(
+ modifier = Modifier
+ .padding(vertical = TangemTheme.dimens2.x4)
+ .fillMaxWidth(),
+ text = state.buttonState.text,
+ onClick = state.buttonState.onClick,
+ size = TangemButton.Size.X12,
+ )
+ }
+ },
+ )
+}
+
+@Composable
+private fun TransactionIcon(iconState: TangemIconUM, modifier: Modifier = Modifier) {
+ Box(
+ modifier = modifier
+ .size(TangemTheme.dimens2.x20)
+ .clip(CircleShape)
+ .background(TangemTheme.colors3.bg.opaque.primary),
+ contentAlignment = Alignment.Center,
+ ) {
+ TangemIcon(
+ tangemIconUM = iconState,
+ modifier = Modifier.size(
+ if (iconState is TangemIconUM.Icon) {
+ TangemTheme.dimens2.x12
+ } else {
+ TangemTheme.dimens2.x20
+ },
+ ),
+ )
+ }
+}
+
+@Composable
+private fun TransactionSecondaryLine(state: TangemPayTxHistoryDetailsUMV2, modifier: Modifier = Modifier) {
+ val secondaryText = when {
+ state.localTransactionText != null -> {
+ buildString {
+ append(state.localTransactionText.orMaskWithStars(state.isBalanceHidden))
+ append(" · ")
+ append(state.transactionTitle.resolveReference())
+ }
+ }
+ else -> state.transactionTitle.resolveReference()
+ }
+ Text(
+ modifier = modifier,
+ text = secondaryText,
+ style = TangemTheme.typography3.subheading.medium,
+ color = TangemTheme.colors3.text.secondary,
+ textAlign = TextAlign.Center,
+ maxLines = 2,
+ overflow = TextOverflow.Ellipsis,
+ )
+}
+
+@Composable
+internal fun TransactionLabel(label: TransactionLabelUM, modifier: Modifier = Modifier) {
+ val (backgroundColor, textColor) = when (label.transactionStateType) {
+ TransactionStateType.Completed,
+ TransactionStateType.Reversed,
+ -> {
+ TangemTheme.colors3.bg.status.successSubtle to TangemTheme.colors3.text.status.success
+ }
+ TransactionStateType.InProgress -> {
+ TangemTheme.colors3.bg.status.infoSubtle to TangemTheme.colors3.text.status.info
+ }
+ TransactionStateType.Rejected -> {
+ TangemTheme.colors3.bg.status.errorSubtle to TangemTheme.colors3.text.status.error
+ }
+ }
+
+ Row(
+ modifier = modifier
+ .background(
+ color = backgroundColor,
+ shape = RoundedCornerShape(TangemTheme.dimens3.borderRadius.b250),
+ )
+ .padding(
+ vertical = TangemTheme.dimens2.x3,
+ horizontal = TangemTheme.dimens2.x4,
+ ),
+ ) {
+ Column(
+ modifier = Modifier.weight(1f),
+ verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens2.x1),
+ ) {
+ Text(
+ text = label.title.resolveReference(),
+ style = TangemTheme.typography3.body.medium,
+ color = textColor,
+ )
+
+ label.subtitle?.let { text ->
+ Text(
+ text = text.resolveReference(),
+ style = TangemTheme.typography3.caption.medium,
+ color = textColor,
+ )
+ }
+ }
+
+ SpacerW(TangemTheme.dimens2.x1)
+
+ TangemIcon(
+ tangemIconUM = label.icon,
+ modifier = Modifier.size(TangemTheme.dimens2.x5),
+ )
+ }
+}
+
+@Composable
+private fun TransactionDetailsBlock(state: TangemPayTxHistoryDetailsUMV2, modifier: Modifier = Modifier) {
+ Column(modifier = modifier) {
+ TangemRow(
+ divider = state.mcc != null,
+ contentLead = TangemRowContentLead.Start,
+ titleSlot = {
+ TangemRowText(
+ text = resourceReference(R.string.tangem_pay_transaction_details_category),
+ role = TangemRowTextRole.Title,
+ )
+ },
+ valueSlot = {
+ TangemRowText(
+ text = state.transactionCategory,
+ role = TangemRowTextRole.Value,
+ )
+ },
+ )
+ if (state.mcc != null) {
+ TangemRow(
+ contentLead = TangemRowContentLead.Start,
+ titleSlot = {
+ TangemRowText(
+ text = resourceReference(R.string.tangem_pay_transaction_details_mcc),
+ role = TangemRowTextRole.Title,
+ )
+ },
+ valueSlot = {
+ TangemRowText(
+ text = state.mcc,
+ role = TangemRowTextRole.Value,
+ )
+ },
+ )
+ }
+ }
+}
+
+@Preview(device = Devices.PIXEL_7_PRO)
+@Preview(device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun TangemPayTxHistoryDetailsContentPreview(
+ @PreviewParameter(TangemPayTxHistoryDetailsUMProviderV2::class) state: TangemPayTxHistoryDetailsUMV2,
+) {
+ TangemThemePreviewRedesign {
+ TangemPayTxHistoryDetailsContentV2(state = state)
+ }
+}
+
+private class TangemPayTxHistoryDetailsUMProviderV2 :
+ CollectionPreviewParameterProvider(
+ listOf(
+ TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = true,
+ title = resourceReference(R.string.tangem_pay_purchase),
+ subtitle = stringReference("12 June 2026, 12:40"),
+ iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
+ transactionTitle = stringReference("Starbucks"),
+ transactionCategory = stringReference("Food and drinks"),
+ mcc = stringReference("5814"),
+ transactionAmount = "-$5.86",
+ localTransactionText = null,
+ label = TransactionLabelUM(
+ transactionStateType = TransactionStateType.InProgress,
+ icon = TangemIconUM.Icon(iconRes = com.tangem.core.ui.R.drawable.ic_clock_24),
+ title = resourceReference(R.string.tangem_pay_status_pending),
+ ),
+ buttonState = ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = {},
+ ),
+ dismiss = {},
+ ),
+ TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = true,
+ title = resourceReference(R.string.tangem_pay_purchase),
+ subtitle = stringReference("12 June 2026, 12:40"),
+ iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
+ transactionTitle = stringReference("NuCaloric"),
+ transactionCategory = stringReference("Groceries"),
+ mcc = stringReference("0000"),
+ transactionAmount = "-$820.52",
+ localTransactionText = "-€696,52",
+ label = TransactionLabelUM(
+ transactionStateType = TransactionStateType.Rejected,
+ icon = TangemIconUM.Icon(iconRes = R.drawable.ic_token_info_24),
+ title = resourceReference(R.string.tangem_pay_status_declined),
+ subtitle = stringReference("Reason: account credit limit exceeded"),
+ ),
+ buttonState = ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = {},
+ ),
+ dismiss = {},
+ ),
+ TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = true,
+ title = resourceReference(R.string.tangem_pay_purchase),
+ subtitle = stringReference("12 June 2026, 12:40"),
+ iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_category_24),
+ transactionTitle = stringReference("Starbucks"),
+ transactionCategory = stringReference("Food and drinks"),
+ mcc = null,
+ transactionAmount = "-$5.86",
+ localTransactionText = "€ 5.36",
+ label = TransactionLabelUM(
+ transactionStateType = TransactionStateType.Completed,
+ icon = TangemIconUM.Empty,
+ title = resourceReference(R.string.tangem_pay_status_completed),
+ ),
+ buttonState = ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = {},
+ ),
+ dismiss = {},
+ ),
+ TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = false,
+ title = resourceReference(R.string.tangem_pay_fee_title),
+ subtitle = stringReference("12 June 2026, 12:40"),
+ iconState = TangemIconUM.Icon(iconRes = R.drawable.ic_percent_24),
+ transactionTitle = stringReference("Service fees"),
+ transactionCategory = stringReference("Service fees"),
+ mcc = null,
+ transactionAmount = "-$5.86",
+ localTransactionText = null,
+ label = TransactionLabelUM(
+ transactionStateType = TransactionStateType.Completed,
+ icon = TangemIconUM.Icon(iconRes = R.drawable.ic_token_info_24),
+ title = resourceReference(R.string.tangem_pay_fee_title),
+ subtitle = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
+ ),
+ buttonState = ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = {},
+ ),
+ dismiss = {},
+ ),
+ TangemPayTxHistoryDetailsUMV2(
+ isBalanceHidden = false,
+ title = resourceReference(R.string.tangem_pay_deposit),
+ subtitle = stringReference("12 June 2026, 12:40"),
+ iconState = TangemIconUM.Icon(imageVector = Icons.ic_arrow_down_24),
+ transactionTitle = resourceReference(R.string.common_transfer),
+ transactionCategory = resourceReference(R.string.common_transfer),
+ mcc = null,
+ transactionAmount = "+$20",
+ localTransactionText = null,
+ label = null,
+ buttonState = ButtonState(
+ text = resourceReference(R.string.tangem_pay_get_help),
+ onClick = {},
+ ),
+ dismiss = {},
+ ),
+ ),
+ )
\ No newline at end of file