Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-23 03:02:00 -07:00
parent e1c819d421
commit 53b02cfb10
31 changed files with 286 additions and 346 deletions

View file

@ -2,7 +2,7 @@ package com.tangem.data.pay
import com.tangem.common.card.FirmwareVersion
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.TangemPayEligibilityType
import com.tangem.domain.models.pay.TangemPayEligibilityType
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId

View file

@ -1,11 +1,15 @@
package com.tangem.data.pay.converter
import com.tangem.data.pay.entity.TangemPayCurrencyFactory
import arrow.core.getOrElse
import com.tangem.data.pay.entity.TangemPayCurrencyFactory
import com.tangem.datasource.local.visa.entity.PaymentAccountStatusValueDM
import com.tangem.domain.models.StatusSource
import com.tangem.domain.models.account.CardDisplayName
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.pay.TangemPayCard
import com.tangem.domain.models.pay.TangemPayCardLimit
import com.tangem.domain.models.pay.TangemPayCardLimitData
import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
import com.tangem.domain.models.wallet.UserWalletId
import javax.inject.Inject
import javax.inject.Singleton
@ -31,29 +35,23 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
customerId = value.customerId,
)
is PaymentAccountStatusValue.IssuingCard -> PaymentAccountStatusValueDM.IssuingCard()
is PaymentAccountStatusValue.Locked -> PaymentAccountStatusValueDM.ActiveCard(
isLocked = true,
is PaymentAccountStatusValue.Loaded -> PaymentAccountStatusValueDM.ActiveAccount(
customerId = value.customerId,
cardId = value.cardId,
lastFourDigits = value.lastFourDigits,
currencyCode = value.currencyCode,
depositAddress = value.depositAddress,
isPinSet = value.isPinSet,
fiatBalance = value.fiatBalance.toDM(),
cryptoBalance = value.cryptoBalance.toDM(),
displayName = value.displayName?.value,
)
is PaymentAccountStatusValue.Loaded -> PaymentAccountStatusValueDM.ActiveCard(
isLocked = false,
customerId = value.customerId,
cardId = value.cardId,
lastFourDigits = value.lastFourDigits,
currencyCode = value.currencyCode,
depositAddress = value.depositAddress,
isPinSet = value.isPinSet,
fiatBalance = value.fiatBalance.toDM(),
cryptoBalance = value.cryptoBalance.toDM(),
displayName = value.displayName?.value,
cards = value.cards.map { card ->
PaymentAccountStatusValueDM.TangemPayCard(
id = card.id,
hasPinCode = card.hasPinCode,
displayName = card.displayName?.value,
actualDailyLimit = card.limit?.actualCardLimit?.amount,
adminDailyLimit = card.limit?.adminCardLimit?.amount,
isFrozen = card.isFrozen,
lastDigits = card.lastDigits,
)
},
)
is PaymentAccountStatusValue.Error.CardIssueFailed -> PaymentAccountStatusValueDM.CardIssueFailed(
customerId = value.customerId,
@ -76,35 +74,32 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
is PaymentAccountStatusValueDM.IssuingCard -> PaymentAccountStatusValue.IssuingCard(
source = StatusSource.CACHE,
)
is PaymentAccountStatusValueDM.ActiveCard -> if (value.isLocked) {
PaymentAccountStatusValue.Locked(
source = StatusSource.CACHE,
customerId = value.customerId,
cardId = value.cardId,
lastFourDigits = value.lastFourDigits,
currencyCode = value.currencyCode,
depositAddress = value.depositAddress,
isPinSet = value.isPinSet,
fiatBalance = value.fiatBalance.toDomain(),
cryptoBalance = value.cryptoBalance.toDomain(),
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
displayName = value.displayName?.let { CardDisplayName(it).getOrElse { null } },
)
} else {
PaymentAccountStatusValue.Loaded(
source = StatusSource.CACHE,
customerId = value.customerId,
cardId = value.cardId,
lastFourDigits = value.lastFourDigits,
currencyCode = value.currencyCode,
depositAddress = value.depositAddress,
isPinSet = value.isPinSet,
fiatBalance = value.fiatBalance.toDomain(),
cryptoBalance = value.cryptoBalance.toDomain(),
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
displayName = value.displayName?.let { CardDisplayName(it).getOrElse { null } },
)
}
is PaymentAccountStatusValueDM.ActiveAccount -> PaymentAccountStatusValue.Loaded(
source = StatusSource.CACHE,
customerId = value.customerId,
currencyCode = value.currencyCode,
depositAddress = value.depositAddress,
fiatBalance = value.fiatBalance.toDomain(),
cryptoBalance = value.cryptoBalance.toDomain(),
cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId),
cards = value.cards.map { card ->
TangemPayCard(
id = card.id,
hasPinCode = card.hasPinCode,
displayName = card.displayName?.let { CardDisplayName(it).getOrElse { null } },
limit = TangemPayCardLimitData(
actualCardLimit = card.actualDailyLimit?.let { limit ->
TangemPayCardLimit(limit, TangemPayCardLimitPeriod.DAY)
},
adminCardLimit = card.adminDailyLimit?.let { limit ->
TangemPayCardLimit(limit, TangemPayCardLimitPeriod.DAY)
},
),
isFrozen = card.isFrozen,
lastDigits = card.lastDigits,
)
},
)
is PaymentAccountStatusValueDM.UnderReview -> PaymentAccountStatusValue.UnderReview(
source = StatusSource.CACHE,
kycStatus = value.kycStatus,

View file

@ -2,6 +2,7 @@ package com.tangem.data.pay.di
import android.content.Context
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.dataStoreFile
import com.squareup.moshi.Moshi
import com.tangem.data.pay.DefaultTangemPayCryptoCurrencyFactory
@ -129,6 +130,7 @@ internal interface TangemPayDataModule {
types = mapWithStringKeyTypes<PaymentAccountStatusValueDM>(),
defaultValue = emptyMap(),
),
corruptionHandler = ReplaceFileCorruptionHandler { emptyMap() },
produceFile = { context.dataStoreFile(fileName = "payment_account_statuses") },
scope = scope,
),

View file

@ -9,6 +9,8 @@ import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.kyc.KycStatus
import com.tangem.domain.models.pay.TangemPayCard
import com.tangem.domain.models.pay.TangemPayCardLimitData
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
import com.tangem.domain.pay.model.CustomerInfo
@ -277,34 +279,28 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
customerId: String,
): PaymentAccountStatusValue {
val cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId)
return when (productInstance.frozenState) {
TangemPayCardFrozenState.Frozen -> PaymentAccountStatusValue.Locked(
source = StatusSource.ACTUAL,
customerId = customerId,
cardId = productInstance.cardId,
lastFourDigits = cardInfo.lastFourDigits,
currencyCode = cardInfo.currencyCode,
depositAddress = cardInfo.depositAddress,
isPinSet = cardInfo.isPinSet,
fiatBalance = cardInfo.fiatBalance,
cryptoBalance = cardInfo.cryptoBalance,
cryptoCurrency = cryptoCurrency,
displayName = productInstance.displayName,
)
else -> PaymentAccountStatusValue.Loaded(
source = StatusSource.ACTUAL,
customerId = customerId,
cardId = productInstance.cardId,
lastFourDigits = cardInfo.lastFourDigits,
currencyCode = cardInfo.currencyCode,
depositAddress = cardInfo.depositAddress,
isPinSet = cardInfo.isPinSet,
fiatBalance = cardInfo.fiatBalance,
cryptoBalance = cardInfo.cryptoBalance,
cryptoCurrency = cryptoCurrency,
displayName = productInstance.displayName,
)
}
return PaymentAccountStatusValue.Loaded(
source = StatusSource.ACTUAL,
customerId = customerId,
currencyCode = cardInfo.currencyCode,
depositAddress = cardInfo.depositAddress,
fiatBalance = cardInfo.fiatBalance,
cryptoBalance = cardInfo.cryptoBalance,
cryptoCurrency = cryptoCurrency,
cards = listOf(
TangemPayCard(
id = productInstance.cardId,
hasPinCode = cardInfo.isPinSet,
displayName = productInstance.displayName,
limit = TangemPayCardLimitData(
actualCardLimit = productInstance.actualCardLimit,
adminCardLimit = productInstance.adminCardLimit,
),
isFrozen = productInstance.frozenState is TangemPayCardFrozenState.Frozen,
lastDigits = cardInfo.lastFourDigits,
),
),
)
}
private fun VisaApiError.mapToPaymentAccountStatus(): PaymentAccountStatusValue {

View file

@ -15,7 +15,7 @@ import com.tangem.datasource.api.pay.models.response.OrderResponse
import com.tangem.datasource.local.visa.TangemPayCardFrozenStateStore
import com.tangem.datasource.local.visa.TangemPayStorage
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.TangemPayEligibilityType
import com.tangem.domain.models.pay.TangemPayEligibilityType
import com.tangem.domain.models.account.CardDisplayName
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.kyc.KycStatus
@ -25,8 +25,8 @@ import com.tangem.domain.pay.datasource.TangemPayAuthDataSource
import com.tangem.domain.pay.model.CustomerInfo
import com.tangem.domain.pay.model.CustomerInfo.CardInfo
import com.tangem.domain.pay.model.CustomerInfo.ProductInstance
import com.tangem.domain.pay.model.TangemPayCardLimit
import com.tangem.domain.pay.model.TangemPayCardLimitPeriod
import com.tangem.domain.models.pay.TangemPayCardLimit
import com.tangem.domain.models.pay.TangemPayCardLimitPeriod
import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.domain.tangempay.TangemPayAnalyticsEvents
import com.tangem.domain.visa.error.VisaApiError

View file

@ -8,7 +8,7 @@ import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.request.ReissueCardRequest
import com.tangem.datasource.api.pay.models.response.OrderResponse
import com.tangem.datasource.local.visa.TangemPayReissueCardStore
import com.tangem.domain.models.TangemPayReissueCardFee
import com.tangem.domain.models.pay.TangemPayReissueCardFee
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.model.OrderStatus
import com.tangem.domain.pay.model.TangemPayReissueOrderInfo

View file

@ -10,6 +10,7 @@ import com.tangem.domain.models.account.AccountStatus
import com.tangem.domain.models.account.PaymentAccountStatusValue
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.runSuspendCatching
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
@ -45,6 +46,7 @@ internal class PaymentAccountStatusesStore(
},
)
} catch (e: Exception) {
runSuspendCatching { persistenceDataStore.updateData { emptyMap() } }
TangemLogger.e("Error while loading cached payment account statuses", e)
}
}