From 5ca696d677f51acb3f3acbeadd8602cb79cb8776 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 13 Jul 2026 13:19:30 +0500 Subject: [PATCH] Updated on 2026-08-14 --- .../configs/feature_toggles_config.json | 4 + .../tangem/datasource/api/pay/TangemPayApi.kt | 3 + .../response/CashbackSummaryResponse.kt | 29 ++++ .../tangem/data/pay/di/TangemPayDataModule.kt | 5 + .../repository/DefaultCashbackRepository.kt | 22 +++ .../data/pay/util/CashbackSummaryConverter.kt | 44 ++++++ .../data/pay/di/TangemPayDataMockedModule.kt | 6 + .../repository/MockAwareCashbackRepository.kt | 52 +++++++ .../pay/di/TangemPayDataProductionModule.kt | 6 + .../pay/util/CashbackSummaryConverterTest.kt | 139 ++++++++++++++++++ .../domain/pay/model/CashbackDisplayMode.kt | 23 +++ .../domain/pay/model/CashbackProgramStatus.kt | 32 ++++ .../domain/pay/model/CashbackSummary.kt | 27 ++++ .../pay/repository/CashbackRepository.kt | 15 ++ .../pay/usecase/GetCashbackSummaryUseCase.kt | 20 +++ .../tangempay/TangemPayFeatureToggles.kt | 1 + .../DefaultTangemPayFeatureToggles.kt | 3 + 17 files changed, 431 insertions(+) create mode 100644 core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CashbackSummaryResponse.kt create mode 100644 data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCashbackRepository.kt create mode 100644 data/visa/src/main/kotlin/com/tangem/data/pay/util/CashbackSummaryConverter.kt create mode 100644 data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareCashbackRepository.kt create mode 100644 data/visa/src/test/kotlin/com/tangem/data/pay/util/CashbackSummaryConverterTest.kt create mode 100644 domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackDisplayMode.kt create mode 100644 domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackProgramStatus.kt create mode 100644 domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackSummary.kt create mode 100644 domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CashbackRepository.kt create mode 100644 domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetCashbackSummaryUseCase.kt diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index aa5cf5e68b..ddaa0bab10 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -178,5 +178,9 @@ { "name": "AND_16080_TRON_DEX_SWAP_ENABLED", "version": "undefined" + }, + { + "name": "TWI_1192_TANGEM_PAY_CASHBACK_ENABLED", + "version": "undefined" } ] 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 dcac795aca..de50b2d81a 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 @@ -187,4 +187,7 @@ interface TangemPayApi { @Body body: UpdateCardRequest, @Path("card_id") cardId: String, ): ApiResponse + + @GET("v1/customer/cashback/summary") + suspend fun getCashbackSummary(@Header("Authorization") authHeader: String): ApiResponse } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CashbackSummaryResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CashbackSummaryResponse.kt new file mode 100644 index 0000000000..381711b83b --- /dev/null +++ b/core/datasource/src/main/java/com/tangem/datasource/api/pay/models/response/CashbackSummaryResponse.kt @@ -0,0 +1,29 @@ +package com.tangem.datasource.api.pay.models.response + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import java.math.BigDecimal + +/** + * Response from `GET /v1/customer/cashback/summary`. + * + * When [cashbackProgramStatus] is not `enabled`, the amount/period fields may be omitted. + */ +@JsonClass(generateAdapter = true) +data class CashbackSummaryResponse( + @Json(name = "cashback_program_status") val cashbackProgramStatus: String, + @Json(name = "cashback_display_mode") val cashbackDisplayMode: String?, + @Json(name = "period") val period: Period?, + @Json(name = "confirmed_amount") val confirmedAmount: BigDecimal?, + @Json(name = "pending_amount") val pendingAmount: BigDecimal?, + @Json(name = "currency") val currency: String?, +) { + + @JsonClass(generateAdapter = true) + data class Period( + @Json(name = "year") val year: Int, + @Json(name = "month") val month: Int, + @Json(name = "payout_start_date") val payoutStartDate: String?, + @Json(name = "payout_end_date") val payoutEndDate: String?, + ) +} \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt index acecee8de6..552ed0e6f3 100644 --- a/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/di/TangemPayDataModule.kt @@ -301,6 +301,11 @@ internal interface TangemPayDataModule { return GetCustomerOffersUseCase(customerOffersRepository) } + @Provides + fun provideGetCashbackSummaryUseCase(cashbackRepository: CashbackRepository): GetCashbackSummaryUseCase { + return GetCashbackSummaryUseCase(cashbackRepository) + } + @Provides fun provideCheckOrderConflictUseCase( customerOrderRepository: CustomerOrderRepository, diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCashbackRepository.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCashbackRepository.kt new file mode 100644 index 0000000000..b8e1a2ebf8 --- /dev/null +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/repository/DefaultCashbackRepository.kt @@ -0,0 +1,22 @@ +package com.tangem.data.pay.repository + +import arrow.core.Either +import com.tangem.data.pay.util.CashbackSummaryConverter +import com.tangem.datasource.api.pay.TangemPayApi +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.pay.repository.CashbackRepository +import com.tangem.domain.visa.error.VisaApiError +import javax.inject.Inject + +internal class DefaultCashbackRepository @Inject constructor( + private val tangemPayApi: TangemPayApi, + private val requestHelper: TangemPayRequestPerformer, +) : CashbackRepository { + + override suspend fun getCashbackSummary(userWalletId: UserWalletId): Either { + return requestHelper.performRequest(userWalletId) { authHeader -> + tangemPayApi.getCashbackSummary(authHeader = authHeader) + }.map(CashbackSummaryConverter::convert) + } +} \ No newline at end of file diff --git a/data/visa/src/main/kotlin/com/tangem/data/pay/util/CashbackSummaryConverter.kt b/data/visa/src/main/kotlin/com/tangem/data/pay/util/CashbackSummaryConverter.kt new file mode 100644 index 0000000000..f626b5cb70 --- /dev/null +++ b/data/visa/src/main/kotlin/com/tangem/data/pay/util/CashbackSummaryConverter.kt @@ -0,0 +1,44 @@ +package com.tangem.data.pay.util + +import com.tangem.datasource.api.pay.models.response.CashbackSummaryResponse +import com.tangem.domain.pay.model.CashbackDisplayMode +import com.tangem.domain.pay.model.CashbackProgramStatus +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.pay.model.TangemPayCashback +import com.tangem.utils.converter.Converter +import org.joda.time.DateTime +import java.math.BigDecimal + +/** Maps [CashbackSummaryResponse] (BFF) to the domain [CashbackSummary]. */ +internal object CashbackSummaryConverter : Converter { + + override fun convert(value: CashbackSummaryResponse): CashbackSummary { + return when (CashbackProgramStatus.fromString(value.cashbackProgramStatus)) { + CashbackProgramStatus.ENABLED -> toEnabled(value) + CashbackProgramStatus.DEACTIVATED -> CashbackSummary.Deactivated + CashbackProgramStatus.DISABLED -> CashbackSummary.Disabled + CashbackProgramStatus.UNKNOWN -> CashbackSummary.Unknown + } + } + + private fun toEnabled(value: CashbackSummaryResponse): CashbackSummary { + val period = value.period ?: return CashbackSummary.Unknown + val payoutStart = period.payoutStartDate?.let(DateTime::parse) ?: return CashbackSummary.Unknown + val payoutEnd = period.payoutEndDate?.let(DateTime::parse) ?: return CashbackSummary.Unknown + + return CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.fromString(value.cashbackDisplayMode), + cashback = TangemPayCashback( + confirmedAmount = value.confirmedAmount ?: BigDecimal.ZERO, + currency = value.currency.orEmpty(), + period = TangemPayCashback.Period( + year = period.year, + month = period.month, + payoutStart = payoutStart, + payoutEnd = payoutEnd, + ), + ), + pendingAmount = value.pendingAmount ?: BigDecimal.ZERO, + ) + } +} \ No newline at end of file diff --git a/data/visa/src/mocked/kotlin/com/tangem/data/pay/di/TangemPayDataMockedModule.kt b/data/visa/src/mocked/kotlin/com/tangem/data/pay/di/TangemPayDataMockedModule.kt index 16f3f0b9db..4328268a04 100644 --- a/data/visa/src/mocked/kotlin/com/tangem/data/pay/di/TangemPayDataMockedModule.kt +++ b/data/visa/src/mocked/kotlin/com/tangem/data/pay/di/TangemPayDataMockedModule.kt @@ -1,7 +1,9 @@ package com.tangem.data.pay.di +import com.tangem.data.pay.repository.MockAwareCashbackRepository import com.tangem.data.pay.repository.MockAwareOnboardingRepository import com.tangem.data.pay.repository.MockAwareTangemPayCardDetailsRepository +import com.tangem.domain.pay.repository.CashbackRepository import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import dagger.Binds @@ -21,4 +23,8 @@ internal interface TangemPayDataMockedModule { @Binds @Singleton fun bindCardDetailsRepository(repository: MockAwareTangemPayCardDetailsRepository): TangemPayCardDetailsRepository + + @Binds + @Singleton + fun bindCashbackRepository(repository: MockAwareCashbackRepository): CashbackRepository } \ No newline at end of file diff --git a/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareCashbackRepository.kt b/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareCashbackRepository.kt new file mode 100644 index 0000000000..208c11fe9b --- /dev/null +++ b/data/visa/src/mocked/kotlin/com/tangem/data/pay/repository/MockAwareCashbackRepository.kt @@ -0,0 +1,52 @@ +package com.tangem.data.pay.repository + +import arrow.core.Either +import arrow.core.right +import com.tangem.datasource.api.common.config.ApiConfig +import com.tangem.datasource.api.common.config.ApiEnvironment +import com.tangem.datasource.api.common.config.managers.ApiConfigsManager +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.model.CashbackDisplayMode +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.pay.model.TangemPayCashback +import com.tangem.domain.pay.repository.CashbackRepository +import com.tangem.domain.visa.error.VisaApiError +import org.joda.time.DateTime +import java.math.BigDecimal +import javax.inject.Inject +import javax.inject.Singleton + +/** In MOCK env returns a canned cashback summary; otherwise delegates to [DefaultCashbackRepository]. */ +@Singleton +internal class MockAwareCashbackRepository @Inject constructor( + private val real: DefaultCashbackRepository, + private val apiConfigsManager: ApiConfigsManager, +) : CashbackRepository { + + private val isMockMode: Boolean + get() = apiConfigsManager + .getEnvironmentConfig(ApiConfig.ID.TangemPay) + .environment == ApiEnvironment.MOCK + + override suspend fun getCashbackSummary(userWalletId: UserWalletId): Either { + if (isMockMode) return MOCK_SUMMARY.right() + return real.getCashbackSummary(userWalletId) + } + + private companion object { + val MOCK_SUMMARY = CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.FULL, + cashback = TangemPayCashback( + confirmedAmount = BigDecimal("22.54"), + currency = "USD", + period = TangemPayCashback.Period( + year = 2026, + month = 6, + payoutStart = DateTime.parse("2026-07-02"), + payoutEnd = DateTime.parse("2026-07-05"), + ), + ), + pendingAmount = BigDecimal("13.65"), + ) + } +} \ No newline at end of file diff --git a/data/visa/src/prodDi/kotlin/com/tangem/data/pay/di/TangemPayDataProductionModule.kt b/data/visa/src/prodDi/kotlin/com/tangem/data/pay/di/TangemPayDataProductionModule.kt index 02c95e98be..48d56376a8 100644 --- a/data/visa/src/prodDi/kotlin/com/tangem/data/pay/di/TangemPayDataProductionModule.kt +++ b/data/visa/src/prodDi/kotlin/com/tangem/data/pay/di/TangemPayDataProductionModule.kt @@ -1,7 +1,9 @@ package com.tangem.data.pay.di +import com.tangem.data.pay.repository.DefaultCashbackRepository import com.tangem.data.pay.repository.DefaultOnboardingRepository import com.tangem.data.pay.repository.DefaultTangemPayCardDetailsRepository +import com.tangem.domain.pay.repository.CashbackRepository import com.tangem.domain.pay.repository.OnboardingRepository import com.tangem.domain.pay.repository.TangemPayCardDetailsRepository import dagger.Binds @@ -21,4 +23,8 @@ internal interface TangemPayDataProductionModule { @Binds @Singleton fun bindCardDetailsRepository(repository: DefaultTangemPayCardDetailsRepository): TangemPayCardDetailsRepository + + @Binds + @Singleton + fun bindCashbackRepository(repository: DefaultCashbackRepository): CashbackRepository } \ No newline at end of file diff --git a/data/visa/src/test/kotlin/com/tangem/data/pay/util/CashbackSummaryConverterTest.kt b/data/visa/src/test/kotlin/com/tangem/data/pay/util/CashbackSummaryConverterTest.kt new file mode 100644 index 0000000000..086e619ed3 --- /dev/null +++ b/data/visa/src/test/kotlin/com/tangem/data/pay/util/CashbackSummaryConverterTest.kt @@ -0,0 +1,139 @@ +package com.tangem.data.pay.util + +import com.google.common.truth.Truth.assertThat +import com.tangem.datasource.api.pay.models.response.CashbackSummaryResponse +import com.tangem.domain.pay.model.CashbackDisplayMode +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.pay.model.TangemPayCashback +import org.joda.time.DateTime +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.MethodSource +import java.math.BigDecimal + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +internal class CashbackSummaryConverterTest { + + @ParameterizedTest + @MethodSource("provideTestModels") + fun convert(model: ConvertModel) { + // Act + val actual = CashbackSummaryConverter.convert(model.response) + + // Assert + assertThat(actual).isEqualTo(model.expected) + } + + @Suppress("LongMethod") + private fun provideTestModels() = listOf( + ConvertModel( + name = "enabled + full -> Enabled(FULL)", + response = createResponse(status = "enabled", displayMode = "full"), + expected = CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.FULL, + cashback = expectedCashback(), + pendingAmount = BigDecimal("13.65"), + ), + ), + ConvertModel( + name = "enabled + alt_block -> Enabled(ALT_BLOCK)", + response = createResponse(status = "enabled", displayMode = "alt_block"), + expected = CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.ALT_BLOCK, + cashback = expectedCashback(), + pendingAmount = BigDecimal("13.65"), + ), + ), + ConvertModel( + name = "enabled + missing display mode -> Enabled(FULL)", + response = createResponse(status = "enabled", displayMode = null), + expected = CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.FULL, + cashback = expectedCashback(), + pendingAmount = BigDecimal("13.65"), + ), + ), + ConvertModel( + name = "enabled + zero amounts -> Enabled with zeros", + response = createResponse( + status = "enabled", + displayMode = "full", + confirmedAmount = null, + pendingAmount = null, + ), + expected = CashbackSummary.Enabled( + displayMode = CashbackDisplayMode.FULL, + cashback = expectedCashback(confirmedAmount = BigDecimal.ZERO), + pendingAmount = BigDecimal.ZERO, + ), + ), + ConvertModel( + name = "enabled but missing period -> Unknown", + response = createResponse(status = "enabled", period = null), + expected = CashbackSummary.Unknown, + ), + ConvertModel( + name = "deactivated -> Deactivated", + response = createResponse(status = "deactivated"), + expected = CashbackSummary.Deactivated, + ), + ConvertModel( + name = "disabled -> Disabled", + response = createResponse(status = "disabled"), + expected = CashbackSummary.Disabled, + ), + ConvertModel( + name = "unavailable -> Disabled", + response = createResponse(status = "unavailable"), + expected = CashbackSummary.Disabled, + ), + ConvertModel( + name = "unrecognized status -> Unknown", + response = createResponse(status = "something_new"), + expected = CashbackSummary.Unknown, + ), + ) + + internal data class ConvertModel( + val name: String, + val response: CashbackSummaryResponse, + val expected: CashbackSummary, + ) { + override fun toString(): String = name + } + + private companion object { + + fun createResponse( + status: String = "enabled", + displayMode: String? = "full", + period: CashbackSummaryResponse.Period? = CashbackSummaryResponse.Period( + year = 2026, + month = 6, + payoutStartDate = "2026-07-02", + payoutEndDate = "2026-07-05", + ), + confirmedAmount: BigDecimal? = BigDecimal("22.54"), + pendingAmount: BigDecimal? = BigDecimal("13.65"), + currency: String? = "USD", + ) = CashbackSummaryResponse( + cashbackProgramStatus = status, + cashbackDisplayMode = displayMode, + period = period, + confirmedAmount = confirmedAmount, + pendingAmount = pendingAmount, + currency = currency, + ) + + fun expectedCashback(confirmedAmount: BigDecimal = BigDecimal("22.54")) = TangemPayCashback( + confirmedAmount = confirmedAmount, + currency = "USD", + period = TangemPayCashback.Period( + year = 2026, + month = 6, + payoutStart = DateTime.parse("2026-07-02"), + payoutEnd = DateTime.parse("2026-07-05"), + ), + ) + } +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackDisplayMode.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackDisplayMode.kt new file mode 100644 index 0000000000..7d3651c4bc --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackDisplayMode.kt @@ -0,0 +1,23 @@ +package com.tangem.domain.pay.model + +/** + * Cashback block layout variant, from `cashback_display_mode`. Present only when the program is enabled. + * + * Absent or unrecognized values fall back to [FULL] (see summary display-mode logic). + */ +enum class CashbackDisplayMode { + + /** Standard cashback block. */ + FULL, + + /** Alternative EU/EEA block. */ + ALT_BLOCK, + ; + + companion object { + fun fromString(value: String?): CashbackDisplayMode = when (value?.lowercase()) { + "alt_block" -> ALT_BLOCK + else -> FULL + } + } +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackProgramStatus.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackProgramStatus.kt new file mode 100644 index 0000000000..d198e083b5 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackProgramStatus.kt @@ -0,0 +1,32 @@ +package com.tangem.domain.pay.model + +/** + * Cashback program availability for the customer, from `cashback_program_status` + * in `GET /v1/customer/cashback/summary`. + * + * Unknown wire values resolve to [UNKNOWN]. + */ +enum class CashbackProgramStatus { + + /** Cashback is active. */ + ENABLED, + + /** Customer blocked due to fraud behavior; client shows the "Cashback deactivated" banner. */ + DEACTIVATED, + + /** Cashback not available for this cohort/region; client silently hides all cashback UI. */ + DISABLED, + + /** Unrecognized status. */ + UNKNOWN, + ; + + companion object { + fun fromString(value: String?): CashbackProgramStatus = when (value?.lowercase()) { + "enabled" -> ENABLED + "deactivated" -> DEACTIVATED + "disabled", "unavailable" -> DISABLED + else -> UNKNOWN + } + } +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackSummary.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackSummary.kt new file mode 100644 index 0000000000..463d6985a5 --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/model/CashbackSummary.kt @@ -0,0 +1,27 @@ +package com.tangem.domain.pay.model + +import java.math.BigDecimal + +/** + * Customer cashback summary from `GET /v1/customer/cashback/summary`. + * + * Drives the cashback widget on the Payment account screen and the Cashback screen header. + */ +sealed interface CashbackSummary { + + /** Cashback is active for the customer. */ + data class Enabled( + val displayMode: CashbackDisplayMode, + val cashback: TangemPayCashback, + val pendingAmount: BigDecimal, + ) : CashbackSummary + + /** Customer blocked due to fraud; client shows the "Cashback deactivated" banner. */ + data object Deactivated : CashbackSummary + + /** Cashback not available for this cohort/region; client hides all cashback UI. */ + data object Disabled : CashbackSummary + + /** Unrecognized program status; treated as no cashback UI. */ + data object Unknown : CashbackSummary +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CashbackRepository.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CashbackRepository.kt new file mode 100644 index 0000000000..293cc5a2ff --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/repository/CashbackRepository.kt @@ -0,0 +1,15 @@ +package com.tangem.domain.pay.repository + +import arrow.core.Either +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.visa.error.VisaApiError + +/** + * Repository for the cashback endpoints (`GET /v1/customer/cashback/...`). + */ +interface CashbackRepository { + + /** Loads the cashback summary for the customer of [userWalletId]. */ + suspend fun getCashbackSummary(userWalletId: UserWalletId): Either +} \ No newline at end of file diff --git a/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetCashbackSummaryUseCase.kt b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetCashbackSummaryUseCase.kt new file mode 100644 index 0000000000..34a63a240d --- /dev/null +++ b/domain/visa/src/main/kotlin/com/tangem/domain/pay/usecase/GetCashbackSummaryUseCase.kt @@ -0,0 +1,20 @@ +package com.tangem.domain.pay.usecase + +import arrow.core.Either +import com.tangem.domain.models.wallet.UserWalletId +import com.tangem.domain.pay.model.CashbackSummary +import com.tangem.domain.pay.repository.CashbackRepository +import com.tangem.domain.visa.error.VisaApiError + +/** + * Loads the cashback summary from `GET /v1/customer/cashback/summary`. + * + * Used by the Payment account cashback widget and the Cashback screen header. + */ +class GetCashbackSummaryUseCase( + private val cashbackRepository: CashbackRepository, +) { + suspend operator fun invoke(userWalletId: UserWalletId): Either { + return cashbackRepository.getCashbackSummary(userWalletId) + } +} \ No newline at end of file diff --git a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt index 8e09e1ac9d..edba3aca26 100644 --- a/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt +++ b/features/tangempay/details/api/src/main/kotlin/com/tangem/features/tangempay/TangemPayFeatureToggles.kt @@ -6,4 +6,5 @@ interface TangemPayFeatureToggles { val isRemoveAccountEnabled: Boolean val isMultipleCardsEnabled: Boolean val isTiersPlusPlanEnabled: Boolean + val isCashbackEnabled: Boolean } \ No newline at end of file diff --git a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt index 958b410264..a921969c70 100644 --- a/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt +++ b/features/tangempay/details/impl/src/main/kotlin/com/tangem/features/tangempay/DefaultTangemPayFeatureToggles.kt @@ -21,4 +21,7 @@ internal class DefaultTangemPayFeatureToggles( override val isTiersPlusPlanEnabled: Boolean get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.AND_16041_VISA_TIERS_PLUS_PLAN) + + override val isCashbackEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled(FeatureToggles.TWI_1192_TANGEM_PAY_CASHBACK_ENABLED) } \ No newline at end of file