Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-20 01:37:34 -07:00
parent 2070f1d21c
commit 8ca7bc0ca7
15 changed files with 132 additions and 53 deletions

View file

@ -2,12 +2,14 @@ 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.utils.coroutines.AppCoroutineScope
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isLocked
import com.tangem.domain.models.wallet.isMultiCurrency
import com.tangem.domain.pay.TangemPayEligibilityManager
import com.tangem.domain.pay.model.TangemPayEntryPoint
import com.tangem.domain.pay.repository.OnboardingRepository
import com.tangem.hot.sdk.model.HotWalletId
import kotlinx.coroutines.*
@ -22,7 +24,7 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor(
private val onboardingRepository: OnboardingRepository,
) : TangemPayEligibilityManager {
private var cachedEligibleWallets: List<UserWalletData>? = null
private var cachedEligibleWallets: Map<TangemPayEntryPoint?, List<UserWalletData>> = emptyMap()
private var eligibleWalletsDeferred: Deferred<List<UserWalletData>>? = null
private val loadMutex = Mutex()
@ -30,43 +32,46 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor(
resetDataWhenWalletsUpdate()
}
override suspend fun getEligibleWallets(shouldExcludePaeraCustomers: Boolean): List<UserWallet> {
return getUserWalletsData().mapNotNull {
override suspend fun getEligibleWallets(
shouldExcludePaeraCustomers: Boolean,
entryPoint: TangemPayEntryPoint?,
): List<UserWallet> {
return getUserWalletsData(entryPoint = entryPoint).mapNotNull {
if (!it.isPaeraCustomer || !shouldExcludePaeraCustomers) it.userWallet else null
}
}
override suspend fun getPossibleWalletsIds(shouldExcludePaeraCustomers: Boolean): List<UserWalletId> {
return getPossibleWalletsForTangemPay().addPaeraCustomersData().mapNotNull {
return getPossibleWalletsForTangemPay(entryPoint = null).addPaeraCustomersData().mapNotNull {
if (!it.isPaeraCustomer || !shouldExcludePaeraCustomers) it.userWallet.walletId else null
}
}
override suspend fun getTangemPayAvailability(): Boolean {
return onboardingRepository.checkCustomerEligibility()
override suspend fun getTangemPayAvailability(entryPoint: TangemPayEntryPoint): Boolean {
val eligibility = onboardingRepository.getCustomerEligibility().ifEmpty {
onboardingRepository.checkCustomerEligibility()
}
val type = entryPoint.toEligibilityType()
return eligibility.any { it == type }
.also { isEligible -> if (!isEligible) reset() }
}
override suspend fun isPaeraCustomerForAnyWallet(): Boolean {
return getUserWalletsData().any { it.isPaeraCustomer }
override suspend fun isPaeraCustomerForAnyWallet(entryPoint: TangemPayEntryPoint): Boolean {
return getUserWalletsData(entryPoint = entryPoint).any { it.isPaeraCustomer }
}
private suspend fun getUserWalletsData(): List<UserWalletData> {
cachedEligibleWallets?.let { return it }
private suspend fun getUserWalletsData(entryPoint: TangemPayEntryPoint?): List<UserWalletData> {
cachedEligibleWallets[entryPoint]?.let { return it }
return loadMutex.withLock {
cachedEligibleWallets?.let { return it }
cachedEligibleWallets[entryPoint]?.let { return it }
eligibleWalletsDeferred?.let { return it.await() }
coroutineScope {
val deferred = async {
if (!checkTangemPayEligibility()) {
emptyList()
} else {
getPossibleWalletsForTangemPay()
.addPaeraCustomersData()
.also { cachedEligibleWallets = it }
}
getPossibleWalletsForTangemPay(entryPoint = entryPoint)
.addPaeraCustomersData()
.also { cachedEligibleWallets += mapOf(entryPoint to it) }
}
eligibleWalletsDeferred = deferred
try {
@ -78,8 +83,8 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor(
}
}
private suspend fun getPossibleWalletsForTangemPay(): List<UserWallet> {
if (!checkTangemPayEligibility()) {
private suspend fun getPossibleWalletsForTangemPay(entryPoint: TangemPayEntryPoint?): List<UserWallet> {
if (!checkTangemPayEligibility(entryPoint = entryPoint)) {
return emptyList()
}
@ -122,13 +127,25 @@ internal class DefaultTangemPayEligibilityManager @Inject constructor(
}
override fun reset() {
cachedEligibleWallets = null
cachedEligibleWallets = emptyMap()
eligibleWalletsDeferred?.cancel()
eligibleWalletsDeferred = null
}
private suspend fun checkTangemPayEligibility(): Boolean {
return onboardingRepository.getCustomerEligibility() || onboardingRepository.checkCustomerEligibility()
private suspend fun checkTangemPayEligibility(entryPoint: TangemPayEntryPoint?): Boolean {
val eligibility = onboardingRepository.getCustomerEligibility().ifEmpty {
onboardingRepository.checkCustomerEligibility()
}
return if (entryPoint == null) {
eligibility.isNotEmpty()
} else {
eligibility.any { it == entryPoint.toEligibilityType() }
}
}
private fun TangemPayEntryPoint.toEligibilityType(): TangemPayEligibilityType = when (this) {
TangemPayEntryPoint.BANNER -> TangemPayEligibilityType.BANNER
TangemPayEntryPoint.DETAILS -> TangemPayEligibilityType.DETAILS
}
private data class UserWalletData(

View file

@ -11,6 +11,7 @@ import com.tangem.datasource.api.pay.models.response.CustomerMeResponse
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.kyc.KycStatus
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
@ -207,19 +208,20 @@ internal class DefaultOnboardingRepository @Inject constructor(
}
}
override suspend fun checkCustomerEligibility(): Boolean {
override suspend fun checkCustomerEligibility(): List<TangemPayEligibilityType> {
val response = requestHelper.performWithStaticToken {
tangemPayApi.checkCustomerEligibility()
tangemPayApi.getEligibilityChannels()
}.getOrNull()
val isAvailable = response?.result?.isTangemPayAvailable == true
tangemPayStorage.storeTangemPayEligibility(eligibility = isAvailable)
val channels = response?.result?.channels
val eligibility = channels.orEmpty().toSet()
tangemPayStorage.storeTangemPayEligibility(eligibility = eligibility)
return isAvailable
return eligibility.map(TangemPayEligibilityType::fromString)
}
override suspend fun getCustomerEligibility(): Boolean {
return tangemPayStorage.getTangemPayEligibility()
override suspend fun getCustomerEligibility(): List<TangemPayEligibilityType> {
return tangemPayStorage.getTangemPayEligibility().map(TangemPayEligibilityType::fromString)
}
override suspend fun getHideMainOnboardingBanner(userWalletId: UserWalletId): Boolean {