From e11e2d953d7d7d4b37a022af4930bba0df69756a Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 18 Jun 2026 13:50:25 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/datasource/api/pay/TangemPayApi.kt | 6 ++++-- .../DefaultTangemPayCardDetailsRepository.kt | 9 +++++++-- .../MockAwareTangemPayCardDetailsRepository.kt | 8 ++++++-- .../pay/repository/TangemPayCardDetailsRepository.kt | 2 +- .../components/TangemPayCardPageComponent.kt | 7 +++++-- .../components/TangemPayChangePinComponent.kt | 6 +++++- .../tangempay/model/TangemPayCardPageModel.kt | 7 ++++--- .../tangempay/model/TangemPayChangePinModel.kt | 11 +++++++---- .../navigation/TangemPayCardDetailsInnerRoute.kt | 2 +- 9 files changed, 40 insertions(+), 18 deletions(-) diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt index 2e2bd9d865..80fcf19f81 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/TangemPayApi.kt @@ -79,15 +79,17 @@ interface TangemPayApi { @Body body: CardDetailsRequest, ): ApiResponse - @GET("v1/customer/card/pin") + @GET("v1/customer/card/{card_id}/pin") suspend fun getPin( @Header("Authorization") authHeader: String, + @Path("card_id") cardId: String, @Header("X-Session-Id") sessionId: String, ): ApiResponse - @PUT("v1/customer/card/pin") + @PUT("v1/customer/card/{card_id}/pin") suspend fun setPin( @Header("Authorization") authHeader: String, + @Path("card_id") cardId: String, @Body body: SetPinRequest, ): ApiResponse diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt index a72a37db8e..18d0d10209 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultTangemPayCardDetailsRepository.kt @@ -123,7 +123,7 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor( val publicKeyBase64 = getPublicKeyBase64() val (secretKeyBytes, sessionId) = rainCryptoUtil.generateSecretKeyAndSessionId(publicKeyBase64) val response = requestHelper.performRequest(userWalletId = userWalletId) { authHeader -> - tangemPayApi.getPin(authHeader = authHeader, sessionId = sessionId) + tangemPayApi.getPin(authHeader = authHeader, cardId = cardId, sessionId = sessionId) }.getOrNull() val result = requireNotNull(response?.result) @@ -140,7 +140,11 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor( ) } - override suspend fun setPin(userWalletId: UserWalletId, pin: String): Either { + override suspend fun setPin( + userWalletId: UserWalletId, + cardId: String, + pin: String, + ): Either { return catch( block = { val publicKeyBase64 = getPublicKeyBase64() @@ -151,6 +155,7 @@ internal class DefaultTangemPayCardDetailsRepository @Inject constructor( val response = requestHelper.performRequest(userWalletId) { authHeader -> tangemPayApi.setPin( authHeader = authHeader, + cardId = cardId, body = SetPinRequest( sessionId = sessionId, pin = encryptedData.encryptedBase64, diff --git a/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareTangemPayCardDetailsRepository.kt b/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareTangemPayCardDetailsRepository.kt index b359525c20..30c237ddf2 100644 --- a/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareTangemPayCardDetailsRepository.kt +++ b/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareTangemPayCardDetailsRepository.kt @@ -53,9 +53,13 @@ internal class MockAwareTangemPayCardDetailsRepository @Inject constructor( return real.getPin(userWalletId, cardId) } - override suspend fun setPin(userWalletId: UserWalletId, pin: String): Either { + override suspend fun setPin( + userWalletId: UserWalletId, + cardId: String, + pin: String, + ): Either { if (isMockMode) return SetPinResult.SUCCESS.right() - return real.setPin(userWalletId, pin) + return real.setPin(userWalletId, cardId, pin) } override suspend fun isAddToWalletDone(userWalletId: UserWalletId): Either = diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/TangemPayCardDetailsRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/TangemPayCardDetailsRepository.kt index 95aa215164..3de0e60e91 100644 --- a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/TangemPayCardDetailsRepository.kt +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/TangemPayCardDetailsRepository.kt @@ -22,7 +22,7 @@ interface TangemPayCardDetailsRepository { suspend fun getPin(userWalletId: UserWalletId, cardId: String): Either - suspend fun setPin(userWalletId: UserWalletId, pin: String): Either + suspend fun setPin(userWalletId: UserWalletId, cardId: String, pin: String): Either suspend fun isAddToWalletDone(userWalletId: UserWalletId): Either diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt index 1dff479707..51137888da 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayCardPageComponent.kt @@ -70,9 +70,12 @@ internal class TangemPayCardPageComponent @AssistedInject constructor( params = params, tokenReceiveComponentFactory = tokenReceiveComponentFactory, ) - TangemPayCardDetailsInnerRoute.ChangePIN -> TangemPayChangePinComponent( + is TangemPayCardDetailsInnerRoute.ChangePIN -> TangemPayChangePinComponent( appComponentContext = childByContext(componentContext = componentContext, router = innerRouter), - params = TangemPayDetailsContainerComponent.Params(initialStatus = params.initialStatus), + params = TangemPayChangePinComponent.Params( + card = config.card, + userWalletId = params.initialStatus.userWalletId, + ), ) TangemPayCardDetailsInnerRoute.ChangePINSuccess -> TangemPayChangePinSuccessComponent( appComponentContext = childByContext( diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt index 220fb0ccd2..ee61b7cf9f 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/components/TangemPayChangePinComponent.kt @@ -9,13 +9,15 @@ import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect +import com.tangem.domain.models.pay.TangemPayCard +import com.tangem.domain.models.wallet.UserWalletId import com.tangem.features.tangempay.model.TangemPayChangePinModel import com.tangem.features.tangempay.ui.TangemPayChangePinScreen import com.tangem.features.tangempay.ui.TangemPayChangePinScreenV2 internal class TangemPayChangePinComponent( private val appComponentContext: AppComponentContext, - params: TangemPayDetailsContainerComponent.Params, + params: Params, ) : AppComponentContext by appComponentContext, ComposableContentComponent { private val model: TangemPayChangePinModel = getOrCreateModel(params) @@ -37,4 +39,6 @@ internal class TangemPayChangePinComponent( ) } } + + data class Params(val card: TangemPayCard, val userWalletId: UserWalletId) } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt index a0a20e4953..7b604eb42c 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayCardPageModel.kt @@ -379,10 +379,10 @@ internal class TangemPayCardPageModel @Inject constructor( } private fun onClickChangePIN(isPinSet: Boolean) { + val card = selectedCard() ?: return if (!isPinSet) { - router.push(TangemPayCardDetailsInnerRoute.ChangePIN) + router.push(TangemPayCardDetailsInnerRoute.ChangePIN(card)) } else { - val card = selectedCard() ?: return bottomSheetNavigation.activate( TangemPayCardNavigation.ViewPinCode( userWalletId = userWalletId, @@ -551,7 +551,8 @@ internal class TangemPayCardPageModel @Inject constructor( override fun onClickChangePin() { bottomSheetNavigation.dismiss() - router.push(TangemPayCardDetailsInnerRoute.ChangePIN) + val card = selectedCard() ?: return + router.push(TangemPayCardDetailsInnerRoute.ChangePIN(card)) } override fun onDismissViewPin() { diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt index f8d8643db7..8163372405 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/model/TangemPayChangePinModel.kt @@ -9,16 +9,16 @@ import com.tangem.core.decompose.navigation.Router import com.tangem.core.decompose.ui.UiMessageSender import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.ToastMessage +import com.tangem.domain.pay.flow.PaymentAccountStatusFetcher import com.tangem.domain.pay.model.SetPinResult import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import com.tangem.domain.tangempay.TangemPayAnalyticsEvents import com.tangem.features.tangempay.TangemPayFeatureToggles -import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent +import com.tangem.features.tangempay.components.TangemPayChangePinComponent import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.entity.TangemPayChangePinUM import com.tangem.features.tangempay.model.transformers.PinCodeChangeTransformer import com.tangem.features.tangempay.navigation.TangemPayCardDetailsInnerRoute -import com.tangem.features.tangempay.utils.userWalletId import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.logging.TangemLogger import com.tangem.utils.transformer.update @@ -39,9 +39,10 @@ internal class TangemPayChangePinModel @Inject constructor( private val cardDetailsRepository: TangemPayCardDetailsRepository, private val analytics: AnalyticsEventHandler, private val featureToggles: TangemPayFeatureToggles, + private val fetcher: PaymentAccountStatusFetcher, ) : Model() { - private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require() + private val params: TangemPayChangePinComponent.Params = paramsContainer.require() val uiState: StateFlow field = MutableStateFlow(getInitialState()) @@ -66,7 +67,8 @@ internal class TangemPayChangePinModel @Inject constructor( uiState.update { it.copy(submitButtonLoading = true) } val result = try { cardDetailsRepository.setPin( - userWalletId = params.initialStatus.userWalletId, + userWalletId = params.userWalletId, + cardId = params.card.id, pin = uiState.value.pinCode, ).getOrNull() } catch (e: Exception) { @@ -83,6 +85,7 @@ internal class TangemPayChangePinModel @Inject constructor( ) } SetPinResult.SUCCESS -> { + fetcher.invoke(params = PaymentAccountStatusFetcher.Params(userWalletId = params.userWalletId)) analytics.send(TangemPayAnalyticsEvents.ChangePinSuccessShown()) router.push(TangemPayCardDetailsInnerRoute.ChangePINSuccess) } diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/navigation/TangemPayCardDetailsInnerRoute.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/navigation/TangemPayCardDetailsInnerRoute.kt index 0f3d188cff..6aaba8da25 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/navigation/TangemPayCardDetailsInnerRoute.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/navigation/TangemPayCardDetailsInnerRoute.kt @@ -11,7 +11,7 @@ internal sealed class TangemPayCardDetailsInnerRoute : Route { data object Details : TangemPayCardDetailsInnerRoute() @Serializable - data object ChangePIN : TangemPayCardDetailsInnerRoute() + data class ChangePIN(val card: TangemPayCard) : TangemPayCardDetailsInnerRoute() @Serializable data object ChangePINSuccess : TangemPayCardDetailsInnerRoute()