diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index 900691f421..f583c64401 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -1469,6 +1469,9 @@
Freeze
Your card is frozen.
Get Help
+ Reason: %s
+ %s ยท %s
+ MCC %s
Other
Unable to use on rooted devices
Completed
diff --git a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
index b8ecc58913..23187867a8 100644
--- a/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
+++ b/data/visa/src/main/kotlin/com/tangem/data/visa/utils/TangemPayTxHistoryItemConverter.kt
@@ -46,6 +46,7 @@ internal class TangemPayTxHistoryItemConverter(moshi: Moshi) :
merchantCategory = spend.merchantCategory,
status = TangemPayTxHistoryItemStatusConverter.convert(spend.status),
enrichedMerchantIconUrl = spend.enrichedMerchantIcon,
+ declinedReason = spend.declinedReason,
)
}
diff --git a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
index c272305d75..9741b0d593 100644
--- a/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
+++ b/domain/visa/models/src/main/kotlin/com/tangem/domain/visa/model/TangemPayTxHistoryItem.kt
@@ -29,6 +29,7 @@ sealed class TangemPayTxHistoryItem {
val merchantCategory: String?,
val status: Status,
val enrichedMerchantIconUrl: String?,
+ val declinedReason: String?,
) : TangemPayTxHistoryItem()
@Serializable
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 4d2aa7c66e..b240e9c159 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
@@ -17,10 +17,17 @@ internal data class TangemPayTxHistoryDetailsUM(
val transactionAmountColor: ColorReference,
val localTransactionText: String?,
val labelState: LabelUM?,
- val notification: NotificationConfig?,
+ val notification: NotificationState?,
val buttons: ImmutableList,
val dismiss: () -> Unit,
) {
+ data class NotificationState(
+ val config: NotificationConfig,
+ val titleColor: ColorReference,
+ val iconTint: ColorReference,
+ val containerColor: ColorReference?,
+ )
+
data class ButtonState(val text: TextReference, val onClick: () -> Unit, val startIcon: ImageReference.Res? = null)
}
\ No newline at end of file
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/PayDetailsSpendSubtitleConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/PayDetailsSpendSubtitleConverter.kt
new file mode 100644
index 0000000000..26f54a975c
--- /dev/null
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/PayDetailsSpendSubtitleConverter.kt
@@ -0,0 +1,46 @@
+package com.tangem.features.tangempay.model.transformers
+
+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.domain.visa.model.TangemPayTxHistoryItem
+import com.tangem.features.tangempay.details.impl.R
+import com.tangem.utils.converter.Converter
+
+internal object PayDetailsSpendSubtitleConverter : Converter {
+
+ override fun convert(value: TangemPayTxHistoryItem.Spend): TextReference {
+ val merchantCategory = value.merchantCategory
+ val enrichedMerchantCategory = value.enrichedMerchantCategory
+ val merchantCategoryCode = value.merchantCategoryCode
+
+ val categoryCodeText = if (!merchantCategoryCode.isNullOrEmpty()) {
+ resourceReference(
+ id = R.string.tangem_pay_history_item_spend_mcc,
+ formatArgs = wrappedList(merchantCategoryCode),
+ )
+ } else {
+ null
+ }
+
+ val categoryText = when {
+ // if merchantCategory isNotEmpty use this
+ !merchantCategory.isNullOrEmpty() -> stringReference(merchantCategory)
+
+ // If merchantCategory empty or null but enrichedMerchantCategory is not empty
+ !enrichedMerchantCategory.isNullOrEmpty() -> stringReference(enrichedMerchantCategory)
+
+ else -> resourceReference(R.string.tangem_pay_other)
+ }
+
+ return if (categoryCodeText != null) {
+ resourceReference(
+ id = R.string.tangem_pay_history_item_spend_mc_title_format,
+ formatArgs = wrappedList(categoryText, categoryCodeText),
+ )
+ } else {
+ categoryText
+ }
+ }
+}
\ No newline at end of file
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 28706d2143..8269d2423a 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
@@ -7,6 +7,7 @@ import com.tangem.core.ui.extensions.*
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.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.utils.DateTimeFormatters
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
@@ -24,7 +25,7 @@ internal object TangemPayTxHistoryDetailsConverter :
Converter {
private val dateFormatter = DateTimeFormatters.getBestFormatterBySkeleton("dd MMMM")
- private val paySpendSubtitleConverter = PaySpendSubtitleConverter
+ private val paySpendSubtitleConverter = PayDetailsSpendSubtitleConverter
override fun convert(value: Input): TangemPayTxHistoryDetailsUM {
val transaction = value.item
@@ -140,13 +141,16 @@ internal object TangemPayTxHistoryDetailsConverter :
private fun TangemPayTxHistoryItem.extractAmountColor(): ColorReference {
return when (this) {
is TangemPayTxHistoryItem.Fee,
- is TangemPayTxHistoryItem.Spend,
is TangemPayTxHistoryItem.Payment,
-> themedColor { TangemTheme.colors.text.primary1 }
is TangemPayTxHistoryItem.Collateral -> when (this.type) {
TangemPayTxHistoryItem.Type.Deposit -> themedColor { TangemTheme.colors.text.accent }
TangemPayTxHistoryItem.Type.Withdrawal -> themedColor { TangemTheme.colors.text.primary1 }
}
+ is TangemPayTxHistoryItem.Spend -> when (this.status) {
+ TangemPayTxHistoryItem.Status.DECLINED -> themedColor { TangemTheme.colors.text.warning }
+ else -> themedColor { TangemTheme.colors.text.primary1 }
+ }
}
}
@@ -200,21 +204,39 @@ internal object TangemPayTxHistoryDetailsConverter :
}
}
- private fun TangemPayTxHistoryItem.extractNotification(): NotificationConfig? {
+ private fun TangemPayTxHistoryItem.extractNotification(): TangemPayTxHistoryDetailsUM.NotificationState? {
return when (this) {
is TangemPayTxHistoryItem.Payment -> null
is TangemPayTxHistoryItem.Collateral -> null
- is TangemPayTxHistoryItem.Fee -> NotificationConfig(
- title = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
- subtitle = TextReference.EMPTY,
- iconResId = R.drawable.ic_token_info_24,
- )
- is TangemPayTxHistoryItem.Spend -> when (this.status) {
- TangemPayTxHistoryItem.Status.DECLINED -> NotificationConfig(
- title = resourceReference(R.string.tangem_pay_transaction_declined_notification_text),
+ is TangemPayTxHistoryItem.Fee -> TangemPayTxHistoryDetailsUM.NotificationState(
+ config = NotificationConfig(
+ title = resourceReference(R.string.tangem_pay_transaction_fee_notification_text),
subtitle = TextReference.EMPTY,
iconResId = R.drawable.ic_token_info_24,
- )
+ ),
+ titleColor = themedColor { TangemTheme.colors.text.tertiary },
+ iconTint = themedColor { TangemTheme.colors.icon.secondary },
+ containerColor = null,
+ )
+ is TangemPayTxHistoryItem.Spend -> when (this.status) {
+ TangemPayTxHistoryItem.Status.DECLINED ->
+ TangemPayTxHistoryDetailsUM.NotificationState(
+ config = NotificationConfig(
+ title = 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)),
+ )
+ },
+ subtitle = TextReference.EMPTY,
+ iconResId = R.drawable.ic_token_info_24,
+ ),
+ titleColor = themedColor { TangemTheme.colors.text.warning },
+ iconTint = themedColor { TangemTheme.colors.icon.warning },
+ containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
+ )
TangemPayTxHistoryItem.Status.PENDING,
TangemPayTxHistoryItem.Status.COMPLETED,
TangemPayTxHistoryItem.Status.RESERVED,
diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
index a546d5abea..bf0f79c163 100644
--- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
+++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/transformers/TangemPayTxHistoryItemsConverter.kt
@@ -37,10 +37,10 @@ internal class TangemPayTxHistoryItemsConverter(
val localDate = spend.date.withZone(DateTimeZone.getDefault())
val amountPrefix = when {
spend.amount.isZero() -> ""
- spend.status == TangemPayTxHistoryItem.Status.DECLINED -> ""
- else -> StringsSigns.MINUS
+ spend.status == TangemPayTxHistoryItem.Status.DECLINED || spend.amount.isPositive() -> StringsSigns.MINUS
+ else -> StringsSigns.PLUS
}
- val amount = amountPrefix + spend.amount.format {
+ val amount = amountPrefix + spend.amount.abs().format {
fiat(fiatCurrencyCode = spend.currency.currencyCode, fiatCurrencySymbol = spend.currency.symbol)
}
return TangemPayTransactionState.Content.Spend(
@@ -48,8 +48,9 @@ internal class TangemPayTxHistoryItemsConverter(
onClick = { txHistoryUiActions.onTransactionClick(spend) },
amount = amount,
amountColor = themedColor {
- when (spend.status) {
- TangemPayTxHistoryItem.Status.DECLINED -> TangemTheme.colors.text.warning
+ when {
+ spend.status == TangemPayTxHistoryItem.Status.DECLINED -> TangemTheme.colors.text.warning
+ amountPrefix == StringsSigns.PLUS -> TangemTheme.colors.text.accent
else -> TangemTheme.colors.text.primary1
}
},
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 c406c83696..111edfb273 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
@@ -26,6 +26,7 @@ import com.tangem.core.ui.components.label.entity.LabelUM
import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.components.notifications.NotificationConfig
import com.tangem.core.ui.extensions.*
+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
@@ -83,21 +84,24 @@ internal fun TangemPayTxHistoryDetailsContent(state: TangemPayTxHistoryDetailsUM
style = TangemTheme.typography.head,
color = state.transactionAmountColor.resolveReference(),
)
- state.localTransactionText?.let { localTransaction ->
+ if (state.localTransactionText != null) {
Text(
modifier = Modifier.padding(top = 4.dp),
- text = localTransaction.orMaskWithStars(state.isBalanceHidden),
+ text = state.localTransactionText.orMaskWithStars(state.isBalanceHidden),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.tertiary,
)
}
- state.labelState?.let { Label(state = state.labelState, modifier = Modifier.padding(top = 12.dp)) }
+ if (state.labelState != null) {
+ Label(state = state.labelState, modifier = Modifier.padding(top = 12.dp))
+ }
SpacerH32()
- state.notification?.let {
+ if (state.notification != null) {
Notification(
- config = state.notification,
- titleColor = TangemTheme.colors.text.tertiary,
- iconTint = TangemTheme.colors.icon.secondary,
+ config = state.notification.config,
+ titleColor = state.notification.titleColor.resolveReference(),
+ iconTint = state.notification.iconTint.resolveReference(),
+ containerColor = state.notification.containerColor?.resolveReference(),
)
}
ButtonsContainer(
@@ -195,10 +199,15 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
text = resourceReference(R.string.tangem_pay_status_declined),
style = LabelStyle.WARNING,
),
- notification = NotificationConfig(
- title = stringReference("The bank rejected this transaction request."),
- subtitle = TextReference.EMPTY,
- iconResId = R.drawable.ic_token_info_24,
+ notification = TangemPayTxHistoryDetailsUM.NotificationState(
+ config = NotificationConfig(
+ title = stringReference("The bank rejected this transaction request."),
+ subtitle = TextReference.EMPTY,
+ iconResId = R.drawable.ic_token_info_24,
+ ),
+ titleColor = themedColor { TangemTheme.colors.text.warning },
+ iconTint = themedColor { TangemTheme.colors.icon.warning },
+ containerColor = themedColor { TangemColorPalette.Amaranth.copy(alpha = 0.1F) },
),
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(
@@ -240,10 +249,15 @@ private class TangemPayTxHistoryDetailsUMProvider : CollectionPreviewParameterPr
transactionAmountColor = themedColor { TangemTheme.colors.text.primary1 },
localTransactionText = null,
labelState = null,
- notification = NotificationConfig(
- title = stringReference("This fee goes to cover the cost of handling your transfer."),
- subtitle = TextReference.EMPTY,
- iconResId = R.drawable.ic_token_info_24,
+ notification = TangemPayTxHistoryDetailsUM.NotificationState(
+ config = NotificationConfig(
+ title = stringReference("This fee goes to cover the cost of handling your transfer."),
+ subtitle = TextReference.EMPTY,
+ iconResId = R.drawable.ic_token_info_24,
+ ),
+ titleColor = themedColor { TangemTheme.colors.text.tertiary },
+ iconTint = themedColor { TangemTheme.colors.icon.secondary },
+ containerColor = null,
),
buttons = persistentListOf(
TangemPayTxHistoryDetailsUM.ButtonState(