Updated on 2026-08-14
This commit is contained in:
parent
b27ff31652
commit
ad0b09deae
24 changed files with 397 additions and 40 deletions
|
|
@ -11,6 +11,7 @@ import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
|||
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.pay.TangemPayCardState
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -52,7 +53,7 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
|
|||
adminDailyLimit = card.limit?.adminCardLimit?.amount,
|
||||
frozenState = card.frozenState.toString(),
|
||||
lastDigits = card.lastDigits,
|
||||
isReissuing = card.isReissuing,
|
||||
state = card.state.toString(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -108,7 +109,7 @@ internal class PaymentAccountStatusValueDMConverter @Inject constructor(
|
|||
),
|
||||
frozenState = TangemPayCardFrozenState.fromString(card.frozenState),
|
||||
lastDigits = card.lastDigits,
|
||||
isReissuing = card.isReissuing,
|
||||
state = TangemPayCardState.fromString(card.state),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.tangem.domain.pay.flow.PaymentAccountStatusProducer
|
|||
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||
import com.tangem.domain.pay.repository.*
|
||||
import com.tangem.domain.pay.usecase.ChangeCardFrozenStateUseCase
|
||||
import com.tangem.domain.pay.usecase.CloseTangemPayCardUseCase
|
||||
import com.tangem.domain.pay.usecase.GetPaymentAccountCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.pay.usecase.ProduceTangemPayInitialDataUseCase
|
||||
import com.tangem.domain.pay.usecase.ReissueTangemPayCardUseCase
|
||||
|
|
@ -73,6 +74,10 @@ internal interface TangemPayDataModule {
|
|||
@Singleton
|
||||
fun bindReissueCardRepository(repository: DefaultReissueCardRepository): TangemPayReissueCardRepository
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindCloseCardRepository(repository: DefaultCloseCardRepository): TangemPayCloseCardRepository
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindTangemPayCryptoCurrencyFactory(
|
||||
|
|
@ -220,5 +225,20 @@ internal interface TangemPayDataModule {
|
|||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideCloseTangemPayCardUseCase(
|
||||
closeCardRepository: TangemPayCloseCardRepository,
|
||||
startTangemPayOrderPollingUseCase: StartTangemPayOrderPollingUseCase,
|
||||
appCoroutineScope: AppCoroutineScope,
|
||||
paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
): CloseTangemPayCardUseCase {
|
||||
return CloseTangemPayCardUseCase(
|
||||
closeCardRepository = closeCardRepository,
|
||||
startTangemPayOrderPollingUseCase = startTangemPayOrderPollingUseCase,
|
||||
appCoroutineScope = appCoroutineScope,
|
||||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,10 @@ import com.tangem.domain.pay.repository.OnboardingRepository
|
|||
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
||||
import com.tangem.domain.models.pay.TangemPayCardState
|
||||
import com.tangem.domain.pay.model.isFinalStatus
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayCloseCardRepository
|
||||
import com.tangem.security.DeviceSecurityInfoProvider
|
||||
import com.tangem.security.isSecurityExposed
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -36,7 +39,7 @@ import kotlin.time.Duration.Companion.minutes
|
|||
|
||||
private const val TAG = "PaymentAccountStatusFetcher"
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
||||
private val paymentAccountStatusesStore: PaymentAccountStatusesStore,
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
|
|
@ -46,6 +49,7 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
|||
private val tangemPayCurrencyFactory: TangemPayCurrencyFactory,
|
||||
private val eligibilityManager: TangemPayEligibilityManager,
|
||||
private val reissueCardRepository: TangemPayReissueCardRepository,
|
||||
private val closeCardRepository: TangemPayCloseCardRepository,
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
) : PaymentAccountStatusFetcher {
|
||||
|
||||
|
|
@ -299,16 +303,9 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
|||
cardInfo: CustomerInfo.CardInfo,
|
||||
customerId: String,
|
||||
): PaymentAccountStatusValue {
|
||||
val reissueOrder = reissueCardRepository.getReissueOrderInfo(
|
||||
userWalletId = userWalletId,
|
||||
cardId = productInstance.cardId,
|
||||
).getOrNull()
|
||||
|
||||
val isReissuing = reissueOrder != null &&
|
||||
reissueOrder.orderStatus != OrderStatus.CANCELED &&
|
||||
reissueOrder.orderStatus != OrderStatus.COMPLETED
|
||||
|
||||
val cardFrozenState = cardDetailsRepository.cardFrozenStateSync(productInstance.cardId)
|
||||
val cardId = productInstance.cardId
|
||||
val cardState = getCardState(cardId, userWalletId)
|
||||
val cardFrozenState = cardDetailsRepository.cardFrozenStateSync(cardId)
|
||||
val cryptoCurrency = tangemPayCurrencyFactory.create(userWalletId)
|
||||
return PaymentAccountStatusValue.Loaded(
|
||||
source = StatusSource.ACTUAL,
|
||||
|
|
@ -321,7 +318,7 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
|||
cryptoCurrency = cryptoCurrency,
|
||||
cards = listOf(
|
||||
TangemPayCard(
|
||||
id = productInstance.cardId,
|
||||
id = cardId,
|
||||
hasPinCode = cardInfo.isPinSet,
|
||||
displayName = productInstance.displayName,
|
||||
limit = TangemPayCardLimitData(
|
||||
|
|
@ -334,12 +331,35 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
|
|||
productInstance.frozenState
|
||||
},
|
||||
lastDigits = cardInfo.lastFourDigits,
|
||||
isReissuing = isReissuing,
|
||||
state = cardState,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getCardState(cardId: String, userWalletId: UserWalletId): TangemPayCardState {
|
||||
val closingOrderId = closeCardRepository.getCloseOrderId(userWalletId, cardId).getOrNull()
|
||||
val reissueOrderId = reissueCardRepository.getReissueOrderId(userWalletId, cardId).getOrNull()
|
||||
return if (closingOrderId != null) {
|
||||
val order = cardDetailsRepository.getOrderInfo(userWalletId, closingOrderId).getOrNull()
|
||||
if (order != null && order.orderStatus.isFinalStatus) {
|
||||
closeCardRepository.setCloseOrderId(cardId, null)
|
||||
TangemPayCardState.Active
|
||||
} else {
|
||||
TangemPayCardState.Closing
|
||||
}
|
||||
} else if (reissueOrderId != null) {
|
||||
val order = cardDetailsRepository.getOrderInfo(userWalletId, reissueOrderId).getOrNull()
|
||||
if (order != null && order.orderStatus.isFinalStatus) {
|
||||
TangemPayCardState.Active
|
||||
} else {
|
||||
TangemPayCardState.Reissuing
|
||||
}
|
||||
} else {
|
||||
TangemPayCardState.Active
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun VisaApiError.mapToPaymentAccountStatus(userWalletId: UserWalletId): PaymentAccountStatusValue {
|
||||
return when (this) {
|
||||
is VisaApiError.RefreshTokenExpired -> PaymentAccountStatusValue.Error.NotSynced
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package com.tangem.data.pay.repository
|
||||
|
||||
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.CloseCardRequest
|
||||
import com.tangem.datasource.local.visa.TangemPayCloseCardStore
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.model.TangemPayOrderInfo
|
||||
import com.tangem.domain.pay.repository.TangemPayCloseCardRepository
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultCloseCardRepository @Inject constructor(
|
||||
private val tangemPayApi: TangemPayApi,
|
||||
private val requestHelper: TangemPayRequestPerformer,
|
||||
private val tangemPayCloseCardStore: TangemPayCloseCardStore,
|
||||
) : TangemPayCloseCardRepository {
|
||||
|
||||
override suspend fun closeCard(
|
||||
userWalletId: UserWalletId,
|
||||
cardId: String,
|
||||
): Either<VisaApiError, TangemPayOrderInfo> = either {
|
||||
val response = requestHelper.performRequest(userWalletId) { authHeader ->
|
||||
tangemPayApi.closeCard(
|
||||
authHeader = authHeader,
|
||||
body = CloseCardRequest(cardId = cardId),
|
||||
)
|
||||
}.bind()
|
||||
TangemPayOrderInfo(
|
||||
orderId = response.result.orderId,
|
||||
orderStatus = OrderStatusConverter.convert(response.result.status),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun setCloseOrderId(cardId: String, orderId: String?): Either<UniversalError, Unit> =
|
||||
runSuspendCatching {
|
||||
tangemPayCloseCardStore.setCloseOrderId(cardId, orderId)
|
||||
}.fold(
|
||||
onSuccess = { Unit.right() },
|
||||
onFailure = { Either.Left(VisaApiError.Unspecified) },
|
||||
)
|
||||
|
||||
override suspend fun getCloseOrderId(userWalletId: UserWalletId, cardId: String): Either<UniversalError, String?> =
|
||||
either {
|
||||
runSuspendCatching { tangemPayCloseCardStore.getOrderId(cardId) }.getOrNull()
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ import com.tangem.datasource.local.visa.TangemPayReissueCardStore
|
|||
import com.tangem.domain.models.pay.TangemPayReissueCardFee
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.model.TangemPayOrderInfo
|
||||
import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository
|
||||
import com.tangem.domain.pay.repository.TangemPayReissueCardRepository
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
|
|
@ -21,7 +20,6 @@ internal class DefaultReissueCardRepository @Inject constructor(
|
|||
private val tangemPayApi: TangemPayApi,
|
||||
private val requestHelper: TangemPayRequestPerformer,
|
||||
private val tangemPayReissueCardStore: TangemPayReissueCardStore,
|
||||
private val cardDetailsRepository: TangemPayCardDetailsRepository,
|
||||
) : TangemPayReissueCardRepository {
|
||||
|
||||
override suspend fun getReissueCardFee(userWalletId: UserWalletId): Either<VisaApiError, TangemPayReissueCardFee> =
|
||||
|
|
@ -74,17 +72,11 @@ internal class DefaultReissueCardRepository @Inject constructor(
|
|||
onFailure = { Either.Left(VisaApiError.Unspecified) },
|
||||
)
|
||||
|
||||
override suspend fun getReissueOrderInfo(
|
||||
override suspend fun getReissueOrderId(
|
||||
userWalletId: UserWalletId,
|
||||
cardId: String,
|
||||
): Either<UniversalError, TangemPayOrderInfo?> = either {
|
||||
val orderId = runSuspendCatching { tangemPayReissueCardStore.getOrderId(cardId) }.getOrNull()
|
||||
|
||||
if (orderId == null) {
|
||||
return null.right()
|
||||
}
|
||||
|
||||
cardDetailsRepository.getOrderInfo(userWalletId, orderId).bind()
|
||||
): Either<UniversalError, String?> = either {
|
||||
runSuspendCatching { tangemPayReissueCardStore.getOrderId(cardId) }.getOrNull()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue