Updated on 2026-08-14
This commit is contained in:
parent
64efc8af01
commit
e11e2d953d
9 changed files with 40 additions and 18 deletions
|
|
@ -79,15 +79,17 @@ interface TangemPayApi {
|
|||
@Body body: CardDetailsRequest,
|
||||
): ApiResponse<CardDetailsResponse>
|
||||
|
||||
@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<GetPinResponse>
|
||||
|
||||
@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<SetPinResponse>
|
||||
|
||||
|
|
|
|||
|
|
@ -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<UniversalError, SetPinResult> {
|
||||
override suspend fun setPin(
|
||||
userWalletId: UserWalletId,
|
||||
cardId: String,
|
||||
pin: String,
|
||||
): Either<UniversalError, SetPinResult> {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -53,9 +53,13 @@ internal class MockAwareTangemPayCardDetailsRepository @Inject constructor(
|
|||
return real.getPin(userWalletId, cardId)
|
||||
}
|
||||
|
||||
override suspend fun setPin(userWalletId: UserWalletId, pin: String): Either<UniversalError, SetPinResult> {
|
||||
override suspend fun setPin(
|
||||
userWalletId: UserWalletId,
|
||||
cardId: String,
|
||||
pin: String,
|
||||
): Either<UniversalError, SetPinResult> {
|
||||
if (isMockMode) return SetPinResult.SUCCESS.right()
|
||||
return real.setPin(userWalletId, pin)
|
||||
return real.setPin(userWalletId, cardId, pin)
|
||||
}
|
||||
|
||||
override suspend fun isAddToWalletDone(userWalletId: UserWalletId): Either<UniversalError, Boolean> =
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ interface TangemPayCardDetailsRepository {
|
|||
|
||||
suspend fun getPin(userWalletId: UserWalletId, cardId: String): Either<UniversalError, String?>
|
||||
|
||||
suspend fun setPin(userWalletId: UserWalletId, pin: String): Either<UniversalError, SetPinResult>
|
||||
suspend fun setPin(userWalletId: UserWalletId, cardId: String, pin: String): Either<UniversalError, SetPinResult>
|
||||
|
||||
suspend fun isAddToWalletDone(userWalletId: UserWalletId): Either<UniversalError, Boolean>
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<TangemPayChangePinUM>
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue