Updated on 2026-08-14
This commit is contained in:
parent
0bd23be25f
commit
2c754243f5
16 changed files with 378 additions and 29 deletions
|
|
@ -2,6 +2,8 @@ package com.tangem.domain.pay.flow
|
|||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.core.flow.FlowFetcher
|
||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||
import com.tangem.domain.models.account.VirtualAccountOnramp
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface PaymentAccountStatusFetcher : FlowFetcher<PaymentAccountStatusFetcher.Params> {
|
||||
|
|
@ -10,5 +12,12 @@ interface PaymentAccountStatusFetcher : FlowFetcher<PaymentAccountStatusFetcher.
|
|||
return invoke(Params(userWalletId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimistically marks the cached VA on-ramp as [VirtualAccountOnramp.Processing] so the UI reflects a
|
||||
|
||||
* cached [PaymentAccountStatusValue.Loaded].
|
||||
*/
|
||||
suspend fun markVirtualAccountProcessing(userWalletId: UserWalletId)
|
||||
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
}
|
||||
|
|
@ -42,6 +42,8 @@ interface OnboardingRepository {
|
|||
|
||||
suspend fun storeVirtualAccountOrderId(userWalletId: UserWalletId, vaOrderId: String)
|
||||
|
||||
suspend fun clearVirtualAccountOrderId(userWalletId: UserWalletId)
|
||||
|
||||
suspend fun hasTangemPayInWallet(userWalletId: UserWalletId): Either<VisaApiError, Boolean>
|
||||
|
||||
suspend fun checkCustomerEligibility(): List<TangemPayEligibilityType>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.pay.usecase
|
|||
import arrow.core.Either
|
||||
import arrow.core.raise.either
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.model.OrderStatus
|
||||
import com.tangem.domain.pay.model.TangemPayOrderInfo
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
|
|
@ -22,6 +23,7 @@ import java.util.UUID
|
|||
class CreateVirtualAccountOrderUseCase(
|
||||
private val onboardingRepository: OnboardingRepository,
|
||||
private val pollingUseCase: StartTangemPayOrderPollingUseCase,
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher,
|
||||
private val appCoroutineScope: AppCoroutineScope,
|
||||
) {
|
||||
suspend operator fun invoke(
|
||||
|
|
@ -36,6 +38,9 @@ class CreateVirtualAccountOrderUseCase(
|
|||
idempotencyKey = UUID.randomUUID().toString(),
|
||||
).bind()
|
||||
onboardingRepository.storeVirtualAccountOrderId(userWalletId = userWalletId, vaOrderId = vaOrderId)
|
||||
// Optimistically flip the cached on-ramp to Processing so the UI shows "Preparing" immediately
|
||||
// (no wait for the poll/refetch to confirm).
|
||||
paymentAccountStatusFetcher.markVirtualAccountProcessing(userWalletId)
|
||||
appCoroutineScope.launch {
|
||||
pollingUseCase.invoke(
|
||||
order = TangemPayOrderInfo(orderId = vaOrderId, orderStatus = OrderStatus.NEW),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import arrow.core.left
|
|||
import arrow.core.right
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher
|
||||
import com.tangem.domain.pay.repository.OnboardingRepository
|
||||
import com.tangem.domain.visa.error.VisaApiError
|
||||
import com.tangem.test.core.TestAppCoroutineScope
|
||||
|
|
@ -17,9 +18,12 @@ internal class CreateVirtualAccountOrderUseCaseTest {
|
|||
|
||||
private val onboardingRepository: OnboardingRepository = mockk(relaxUnitFun = true)
|
||||
private val pollingUseCase: StartTangemPayOrderPollingUseCase = mockk(relaxed = true)
|
||||
private val paymentAccountStatusFetcher: PaymentAccountStatusFetcher = mockk(relaxUnitFun = true)
|
||||
|
||||
private val useCase = CreateVirtualAccountOrderUseCase(
|
||||
onboardingRepository = onboardingRepository,
|
||||
pollingUseCase = pollingUseCase,
|
||||
paymentAccountStatusFetcher = paymentAccountStatusFetcher,
|
||||
appCoroutineScope = TestAppCoroutineScope(),
|
||||
)
|
||||
|
||||
|
|
@ -36,6 +40,7 @@ internal class CreateVirtualAccountOrderUseCaseTest {
|
|||
coVerify(exactly = 0) { onboardingRepository.createVirtualAccountOrder(any(), any(), any()) }
|
||||
coVerify(exactly = 0) { onboardingRepository.storeVirtualAccountOrderId(any(), any()) }
|
||||
coVerify(exactly = 0) { pollingUseCase.invoke(any(), any()) }
|
||||
coVerify(exactly = 0) { paymentAccountStatusFetcher.markVirtualAccountProcessing(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -50,6 +55,7 @@ internal class CreateVirtualAccountOrderUseCaseTest {
|
|||
assertThat(result.isRight()).isTrue()
|
||||
coVerify(exactly = 1) { onboardingRepository.storeVirtualAccountOrderId(userWalletId, "new-id") }
|
||||
coVerify(exactly = 1) { pollingUseCase.invoke(any(), userWalletId) }
|
||||
coVerify(exactly = 1) { paymentAccountStatusFetcher.markVirtualAccountProcessing(userWalletId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -64,5 +70,6 @@ internal class CreateVirtualAccountOrderUseCaseTest {
|
|||
assertThat(result.leftOrNull()).isEqualTo(VisaApiError.Unspecified)
|
||||
coVerify(exactly = 0) { onboardingRepository.storeVirtualAccountOrderId(any(), any()) }
|
||||
coVerify(exactly = 0) { pollingUseCase.invoke(any(), any()) }
|
||||
coVerify(exactly = 0) { paymentAccountStatusFetcher.markVirtualAccountProcessing(any()) }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue