Updated on 2026-08-14

This commit is contained in:
Tangem 2026-08-04 02:56:26 -07:00
parent 50a384f13d
commit 457e8870a4
7 changed files with 165 additions and 10 deletions

View file

@ -604,13 +604,25 @@ internal class DefaultPaymentAccountStatusFetcher @Inject constructor(
private suspend fun buildIssuingCards(userWalletId: UserWalletId): List<TangemPayCard> {
val orderIds = issueCardRepository.getIssueOrderIds(userWalletId)
return orderIds.mapNotNull { orderId ->
val order = cardDetailsRepository.getOrderInfo(userWalletId, orderId).getOrNull()
if (order != null && order.orderStatus.isTerminal) {
issueCardRepository.removeIssueOrderId(userWalletId, orderId)
null
} else {
issuingPlaceholderCard(orderId)
}
cardDetailsRepository.getOrderInfo(userWalletId, orderId).fold(
ifLeft = { error ->
if (error == VisaApiError.OrderNotFound) {
logger.i("buildIssuingCards $userWalletId: dropping missing order $orderId")
issueCardRepository.removeIssueOrderId(userWalletId, orderId)
null
} else {
issuingPlaceholderCard(orderId)
}
},
ifRight = { order ->
if (order.orderStatus.isTerminal) {
issueCardRepository.removeIssueOrderId(userWalletId, orderId)
null
} else {
issuingPlaceholderCard(orderId)
}
},
)
}
}

View file

@ -308,6 +308,8 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor(
): Either<UniversalError, TangemPayOrderInfo> = either {
val order = requestHelper.performRequest(userWalletId) { authHeader ->
tangemPayApi.getOrder(authHeader, orderId)
}.mapLeft { error ->
if (error is VisaApiError.NotFound) VisaApiError.OrderNotFound else error
}.bind()
val result = order.result ?: raise(VisaApiError.Unspecified)

View file

@ -769,5 +769,29 @@ internal class DefaultPaymentAccountStatusFetcherTest {
assertThat(loaded.cards).hasSize(1)
assertThat(loaded.cards.single().state).isEqualTo(TangemPayCardState.Issuing)
}
@Test
fun `GIVEN local issue order missing on backend WHEN invoke THEN placeholder dropped and order forgotten`() =
runTest {
// GIVEN
val customerInfo = buildCustomerInfo()
stubHappyPath(customerInfo)
every { tangemPayFeatureToggles.isTiersPlusPlanEnabled } returns true
every { virtualAccountFeatureToggles.isVaMvp0Enabled } returns false
coEvery { issueCardRepository.getIssueOrderIds(userWalletId) } returns listOf("order_gone")
coEvery {
cardDetailsRepository.getOrderInfo(userWalletId, "order_gone")
} returns VisaApiError.OrderNotFound.left()
coEvery { issueCardRepository.removeIssueOrderId(userWalletId, "order_gone") } just Runs
val storedStatuses = captureStoredStatuses()
// WHEN
fetcher.invoke(params)
// THEN
val loaded = storedStatuses.lastLoaded()
assertThat(loaded.cards.map { it.state }).doesNotContain(TangemPayCardState.Issuing)
coVerify(exactly = 1) { issueCardRepository.removeIssueOrderId(userWalletId, "order_gone") }
}
}
}