Updated on 2026-08-14

This commit is contained in:
Tangem 2026-04-29 20:50:41 +05:00
parent f086d6bb74
commit 40fe8bb5cb
56 changed files with 82 additions and 1491 deletions

View file

@ -36,8 +36,6 @@ dependencies {
api(projects.domain.visa)
// endregion
implementation(projects.features.tangempay.details.api) // Remove after TANGEM_PAY_ACCOUNTS_REFACTOR_ENABLED
// region Project - Data
implementation(projects.data.common)
// endregion

View file

@ -11,7 +11,6 @@ import com.tangem.domain.common.wallets.getSyncStrict
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.features.tangempay.TangemPayFeatureToggles
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
@ -36,7 +35,6 @@ internal class DefaultSingleAccountListProducer @AssistedInject constructor(
@Assisted val params: SingleAccountListProducer.Params,
override val flowProducerTools: FlowProducerTools,
private val walletAccountListFlowFactory: WalletAccountListFlowFactory,
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
private val userWalletsListRepository: UserWalletsListRepository,
private val dispatchers: CoroutineDispatcherProvider,
) : SingleAccountListProducer {
@ -45,16 +43,6 @@ internal class DefaultSingleAccountListProducer @AssistedInject constructor(
@OptIn(ExperimentalCoroutinesApi::class)
override fun produce(): Flow<AccountList> {
val accountListFlow: Flow<AccountList> = if (tangemPayFeatureToggles.isTangemPayAccountsRefactorEnabled) {
combineWithPaymentAccount()
} else {
walletAccountListFlowFactory.create(userWalletId = params.userWalletId)
}
return accountListFlow.flowOn(dispatchers.default)
}
private fun combineWithPaymentAccount(): Flow<AccountList> {
return walletAccountListFlowFactory.create(params.userWalletId)
.map { accountList ->
val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId)
@ -66,6 +54,7 @@ internal class DefaultSingleAccountListProducer @AssistedInject constructor(
accountList
}
}
.flowOn(dispatchers.default)
}
private fun UserWallet.isPaymentAccountSupported(): Boolean = when (this) {

View file

@ -8,7 +8,7 @@ import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.tangempay.TangemPayFeatureToggles
import com.tangem.hot.sdk.model.HotWalletId
import com.tangem.test.core.getEmittedValues
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.*
@ -31,21 +31,22 @@ class DefaultSingleAccountListProducerTest {
private val userWalletId = UserWalletId("011")
private val flowProducerTools: FlowProducerTools = mockk()
private val tangemPayFeatureToggles = mockk<TangemPayFeatureToggles> {
every { this@mockk.isTangemPayAccountsRefactorEnabled } returns false
private val userWallet = mockk<UserWallet.Hot> {
every { walletId } returns userWalletId
every { hotWalletId } returns mockk {
every { authType } returns HotWalletId.AuthType.NoPassword
}
}
private val userWalletsListRepository = mockk<UserWalletsListRepository>()
private val userWallet = mockk<UserWallet> {
every { this@mockk.walletId } returns userWalletId
private val userWalletsListRepository = mockk<UserWalletsListRepository> {
every { userWallets } returns MutableStateFlow<List<UserWallet>?>(value = listOf(userWallet))
}
private val producer = DefaultSingleAccountListProducer(
params = SingleAccountListProducer.Params(userWalletId = userWalletId),
walletAccountListFlowFactory = walletAccountListFlowFactory,
dispatchers = TestingCoroutineDispatcherProvider(),
flowProducerTools = flowProducerTools,
tangemPayFeatureToggles = tangemPayFeatureToggles,
userWalletsListRepository = userWalletsListRepository,
dispatchers = TestingCoroutineDispatcherProvider(),
)
@AfterEach
@ -56,8 +57,6 @@ class DefaultSingleAccountListProducerTest {
@Test
fun produce() = runTest {
// Arrange
MutableStateFlow(listOf(userWallet))
val accountList = AccountList.empty(userWalletId)
every { walletAccountListFlowFactory.create(userWalletId) } returns flowOf(accountList)

View file

@ -11,7 +11,6 @@ import com.tangem.data.pay.converter.PaymentAccountStatusValueDMConverter
import com.tangem.data.pay.flow.DefaultPaymentAccountStatusFetcher
import com.tangem.data.pay.flow.DefaultPaymentAccountStatusProducer
import com.tangem.data.pay.repository.*
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
import com.tangem.data.pay.store.PaymentAccountStatusesStore
import com.tangem.data.pay.usecase.DefaultGetTangemPayCurrencyStatusUseCase
import com.tangem.data.pay.usecase.DefaultGetTangemPayCustomerIdUseCase
@ -30,12 +29,10 @@ import com.tangem.domain.pay.repository.*
import com.tangem.domain.pay.usecase.GetPaymentAccountCryptoCurrencyStatusUseCase
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
import com.tangem.domain.pay.usecase.SetTangemPayCardLimitUseCase
import com.tangem.domain.pay.usecase.TangemPayMainScreenCustomerInfoUseCase
import com.tangem.domain.tangempay.GetTangemPayCurrencyStatusUseCase
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
import com.tangem.security.DeviceSecurityInfoProvider
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Binds
@ -167,23 +164,6 @@ internal interface TangemPayDataModule {
return GetPaymentAccountCryptoCurrencyStatusUseCase(paymentAccountStatusSupplier)
}
@Provides
@Singleton
fun provideTangemPayMainScreenCustomerInfoUseCase(
repository: OnboardingRepository,
customerOrderRepository: CustomerOrderRepository,
tangemPayOnboardingRepository: OnboardingRepository,
eligibilityManager: TangemPayEligibilityManager,
deviceSecurity: DeviceSecurityInfoProvider,
): TangemPayMainScreenCustomerInfoUseCase {
return TangemPayMainScreenCustomerInfoUseCase(
onboardingRepository = repository,
customerOrderRepository = customerOrderRepository,
eligibilityManager = eligibilityManager,
deviceSecurity = deviceSecurity,
)
}
@Provides
@Singleton
fun provideProduceTangemPayInitialDataUseCase(

View file

@ -11,8 +11,8 @@ 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.pay.TangemPayEligibilityManager
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.TangemPayEligibilityManager
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
import com.tangem.domain.pay.model.CustomerInfo
import com.tangem.domain.pay.model.OrderData
@ -188,7 +188,6 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
when (orderData.status) {
OrderStatus.CANCELED -> handleCanceledOrder(account, orderData)
OrderStatus.COMPLETED -> handleCompletedOrder(account)
OrderStatus.UNKNOWN -> PaymentAccountStatusValue.Error.Unavailable
OrderStatus.NEW,
OrderStatus.PROCESSING,
-> {
@ -228,7 +227,6 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
OrderStatus.COMPLETED -> return handleCompletedOrder(account)
OrderStatus.NEW,
OrderStatus.PROCESSING,
OrderStatus.UNKNOWN,
-> Unit // Continue polling
}
},

View file

@ -1,8 +1,8 @@
package com.tangem.data.pay.repository
import arrow.core.Either
import com.tangem.data.pay.util.OrderStatusConverter
import com.tangem.datasource.api.pay.TangemPayApi
import com.tangem.datasource.api.pay.models.response.OrderResponse
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.pay.model.OrderData
import com.tangem.domain.pay.model.OrderStatus
@ -19,13 +19,7 @@ internal class DefaultCustomerOrderRepository @Inject constructor(
return requestHelper.performRequest(userWalletId) { authHeader ->
tangemPayApi.getOrder(authHeader = authHeader, orderId = orderId)
}.map { response ->
val status = when (response.result?.status) {
null -> OrderStatus.PROCESSING
OrderResponse.Result.Status.NEW -> OrderStatus.NEW
OrderResponse.Result.Status.PROCESSING -> OrderStatus.PROCESSING
OrderResponse.Result.Status.COMPLETED -> OrderStatus.COMPLETED
OrderResponse.Result.Status.CANCELED -> OrderStatus.CANCELED
}
val status = response.result?.status?.let(OrderStatusConverter::convert) ?: OrderStatus.PROCESSING
OrderData(
customerId = response.result?.customerId.orEmpty(),
status = status,

View file

@ -4,6 +4,7 @@ import arrow.core.Either
import arrow.core.raise.either
import arrow.core.right
import com.tangem.core.error.UniversalError
import com.tangem.data.pay.util.OrderStatusConverter
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
@ -59,8 +60,10 @@ internal class DefaultReissueCardRepository @Inject constructor(
body = ReissueCardRequest(cardId = cardId),
)
}.bind()
TangemPayReissueOrderInfo(response.result.orderId, OrderStatus.fromString(response.result.status))
TangemPayReissueOrderInfo(
orderId = response.result.orderId,
orderStatus = OrderStatusConverter.convert(response.result.status),
)
}
override suspend fun storeReissueOrderId(cardId: String, orderId: String): Either<UniversalError, Unit> =

View file

@ -0,0 +1,16 @@
package com.tangem.data.pay.util
import com.tangem.datasource.api.pay.models.response.OrderResponse
import com.tangem.domain.pay.model.OrderStatus
import com.tangem.utils.converter.Converter
internal object OrderStatusConverter : Converter<OrderResponse.Result.Status, OrderStatus> {
override fun convert(value: OrderResponse.Result.Status): OrderStatus {
return when (value) {
OrderResponse.Result.Status.PROCESSING -> OrderStatus.PROCESSING
OrderResponse.Result.Status.COMPLETED -> OrderStatus.COMPLETED
OrderResponse.Result.Status.NEW -> OrderStatus.NEW
OrderResponse.Result.Status.CANCELED -> OrderStatus.CANCELED
}
}
}