From 9492d27f119c4d38e9397ac78f08a0c03d3b8ec6 Mon Sep 17 00:00:00 2001 From: Pouya Heydari Date: Fri, 19 Jun 2026 13:09:05 +0200 Subject: [PATCH] Update SDK to version 7.1.0 * With support for target SDK 36 * With support for Android Gradle Plugin 9.x * Integrate Activity Result API for Login, CardReaderPage and Checkout --- CHANGELOG.md | 9 +++++ app/build.gradle.kts | 39 +++++++++--------- .../app/data/mapper/OfflineSessionMapper.kt | 2 +- .../repository/ReaderSdkRepositoryImpl.kt | 7 ++-- .../main/java/com/sumup/app/di/KoinModules.kt | 7 ++-- .../sumup/app/presentation/MainActivity.kt | 40 ++++++++----------- .../sumup/app/presentation/MainViewModel.kt | 2 - build.gradle.kts | 5 +-- gradle/wrapper/gradle-wrapper.properties | 4 +- 9 files changed, 56 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3b766a..a7b9672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog For more information, see the [README](https://github.com/sumup/Android-MerchantSDK/blob/master/README.md) + +## Version 7.1.0 +* [ADDED] Support for target SDK 36. +* [ADDED] Support for Android Gradle Plugin 9.x. +* [ADDED] SumUpLoginContract, SumUpCardReaderPageContract, and SumUpCheckoutContract to support Activity Result API integrations. Existing onActivityResult-based integrations remain unchanged. Please refer to the documentation for more information. +* [IMPROVEMENT] Reduced SDK size by approximately 8 MB. +* [IMPROVEMENT] In offline sessions, totalApprovedAmount now includes tip amounts. +* **Important:** SDK v7.1.0 introduces internal changes that are not backward compatible. After upgrading and running the application with v7.1.0, downgrading to an earlier SDK version is not supported. + ## Version 7.0.0 * [ADDED] `successScreenTimeout` in the payment builder to configure the duration of the success screen. * [ADDED] `getSavedCardReaderDetails()` to retrieve details of the saved card reader (serial number, type, and battery percentage). diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b8042cb..d5c84a5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,19 +1,18 @@ plugins { id("com.android.application") - id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.compose") } android { namespace = "com.sumup.app" - compileSdk = 35 + compileSdk = 36 defaultConfig { applicationId = "com.sumup.sdksampleapp" minSdk = 26 - targetSdk = 35 + targetSdk = 36 versionCode = 1 - versionName = "7.0.0" + versionName = "7.1.0" } packaging { @@ -29,15 +28,11 @@ android { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } - - kotlinOptions { - jvmTarget = "17" - } - buildTypes { debug { // All ProGuard rules required by the SumUp SDK are packaged with the library isMinifyEnabled = true + isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } } @@ -47,26 +42,30 @@ android { } } +kotlin { + jvmToolchain(17) +} + dependencies { - implementation(platform("androidx.compose:compose-bom:2025.04.01")) - implementation("androidx.core:core-ktx:1.15.0") - implementation("androidx.activity:activity-compose:1.9.3") + implementation(platform("androidx.compose:compose-bom:2026.05.01")) + implementation("androidx.core:core-ktx:1.18.0") + implementation("androidx.activity:activity-compose:1.13.0") implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") implementation("androidx.compose.material:material-icons-extended") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") - implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.7") - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.10.0") + implementation("androidx.lifecycle:lifecycle-runtime-compose:2.10.0") + implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0") - implementation("androidx.navigation:navigation-compose:2.8.5") + implementation("androidx.navigation:navigation-compose:2.9.8") - implementation("io.insert-koin:koin-android:3.5.6") - implementation("io.insert-koin:koin-androidx-compose:3.5.6") + implementation("io.insert-koin:koin-android:4.2.2") + implementation("io.insert-koin:koin-androidx-compose:4.2.2") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.11.0") - implementation("com.sumup:merchant-sdk:7.0.0") + implementation("com.sumup:merchant-sdk:7.1.0") implementation("com.google.android.gms:play-services-location:21.3.0") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") diff --git a/app/src/main/java/com/sumup/app/data/mapper/OfflineSessionMapper.kt b/app/src/main/java/com/sumup/app/data/mapper/OfflineSessionMapper.kt index e28b883..07f640e 100644 --- a/app/src/main/java/com/sumup/app/data/mapper/OfflineSessionMapper.kt +++ b/app/src/main/java/com/sumup/app/data/mapper/OfflineSessionMapper.kt @@ -1,7 +1,7 @@ package com.sumup.app.data.mapper import com.sumup.app.domain.model.OfflineSession -import com.sumup.merchant.reader.offline.OfflineSessionState +import com.sumup.contract.offline.OfflineSessionState internal class OfflineSessionMapper { diff --git a/app/src/main/java/com/sumup/app/data/repository/ReaderSdkRepositoryImpl.kt b/app/src/main/java/com/sumup/app/data/repository/ReaderSdkRepositoryImpl.kt index 0253334..3f1d57f 100644 --- a/app/src/main/java/com/sumup/app/data/repository/ReaderSdkRepositoryImpl.kt +++ b/app/src/main/java/com/sumup/app/data/repository/ReaderSdkRepositoryImpl.kt @@ -9,9 +9,9 @@ import com.sumup.app.domain.model.MerchantInfo import com.sumup.app.domain.model.OfflineSdkError import com.sumup.app.domain.model.OfflineSession import com.sumup.app.domain.repository.ReaderSdkRepository +import com.sumup.contract.offline.OfflineSessionState +import com.sumup.contract.offline.OfflineUploadFailureReasons import com.sumup.merchant.reader.api.SumUpAPI -import com.sumup.merchant.reader.offline.OfflineSessionState -import com.sumup.merchant.reader.offline.OfflineUploadFailureReasons import com.sumup.merchant.reader.offline.callbacks.OfflineSessionCallback import com.sumup.merchant.reader.offline.callbacks.SecurityPatchUpdateCallback import com.sumup.merchant.reader.offline.callbacks.UploadOfflineTransactionsStatusListener @@ -29,6 +29,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException +import kotlin.time.Duration.Companion.milliseconds internal class ReaderSdkRepositoryImpl( private val dispatcherProvider: CoroutinesDispatcherProvider, @@ -59,7 +60,7 @@ internal class ReaderSdkRepositoryImpl( override fun connectedReaderFlow(intervalMs: Long): Flow = flow { emit(snapshotConnectedReader()) while (true) { - delay(intervalMs) + delay(intervalMs.milliseconds) emit(snapshotConnectedReader()) } } diff --git a/app/src/main/java/com/sumup/app/di/KoinModules.kt b/app/src/main/java/com/sumup/app/di/KoinModules.kt index 0902986..d4a461a 100644 --- a/app/src/main/java/com/sumup/app/di/KoinModules.kt +++ b/app/src/main/java/com/sumup/app/di/KoinModules.kt @@ -1,7 +1,5 @@ package com.sumup.app.di -import com.sumup.app.util.CoroutinesDispatcherProvider -import com.sumup.app.util.DefaultCoroutinesDispatcherProvider import com.sumup.app.data.mapper.ConnectedReaderMapper import com.sumup.app.data.mapper.MerchantInfoMapper import com.sumup.app.data.mapper.OfflineSessionMapper @@ -12,7 +10,9 @@ import com.sumup.app.domain.usecase.CreateLoginRequestUseCase import com.sumup.app.domain.usecase.ParsePaymentResultUseCase import com.sumup.app.domain.usecase.ParseSdkStatusUseCase import com.sumup.app.presentation.MainViewModel -import org.koin.androidx.viewmodel.dsl.viewModel +import com.sumup.app.util.CoroutinesDispatcherProvider +import com.sumup.app.util.DefaultCoroutinesDispatcherProvider +import org.koin.core.module.dsl.viewModel import org.koin.dsl.module internal val appModule = module { @@ -42,7 +42,6 @@ internal val appModule = module { parseSdkStatusUseCase = get(), parsePaymentResultUseCase = get(), readerSdkRepository = get(), - dispatcherProvider = get(), ) } } diff --git a/app/src/main/java/com/sumup/app/presentation/MainActivity.kt b/app/src/main/java/com/sumup/app/presentation/MainActivity.kt index 8a568d6..324d3e0 100644 --- a/app/src/main/java/com/sumup/app/presentation/MainActivity.kt +++ b/app/src/main/java/com/sumup/app/presentation/MainActivity.kt @@ -27,12 +27,24 @@ import com.sumup.app.presentation.screen.CheckoutScreen import com.sumup.app.presentation.screen.SettingsScreen import com.sumup.app.presentation.screen.WelcomeScreen import com.sumup.app.presentation.theme.AppTheme -import com.sumup.merchant.reader.api.SumUpAPI +import com.sumup.merchant.reader.api.SumUpCardReaderPageContract +import com.sumup.merchant.reader.api.SumUpCheckoutContract +import com.sumup.merchant.reader.api.SumUpLoginContract import org.koin.androidx.viewmodel.ext.android.viewModel class MainActivity : ComponentActivity() { private val viewModel: MainViewModel by viewModel() + private val loginLauncher = registerForActivityResult(SumUpLoginContract()) { result -> + viewModel.onLoginResult(result.data?.extras) + } + private val cardReaderPageLauncher = registerForActivityResult(SumUpCardReaderPageContract()) { result -> + viewModel.onCardReaderPageResult(result.data?.extras) + } + private val checkoutLauncher = registerForActivityResult(SumUpCheckoutContract()) { result -> + viewModel.onPaymentResult(result.data?.extras) + } + override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) @@ -46,17 +58,6 @@ class MainActivity : ComponentActivity() { } } - @Deprecated("Required by SumUp SDK which uses startActivityForResult") - @Suppress("DEPRECATION") - override fun onActivityResult(requestCode: Int, resultCode: Int, data: android.content.Intent?) { - super.onActivityResult(requestCode, resultCode, data) - when (requestCode) { - REQUEST_CODE_LOGIN -> viewModel.onLoginResult(data?.extras) - REQUEST_CODE_CARD_READER_PAGE -> viewModel.onCardReaderPageResult(data?.extras) - REQUEST_CODE_PAYMENT -> viewModel.onPaymentResult(data?.extras) - } - } - override fun onResume() { super.onResume() @@ -65,20 +66,11 @@ class MainActivity : ComponentActivity() { private fun handleSdkAction(actionRequest: SdkActionRequest) { when (actionRequest) { - is SdkActionRequest.OpenLogin -> - SumUpAPI.openLoginActivity(this, actionRequest.login, REQUEST_CODE_LOGIN) - is SdkActionRequest.StartCheckout -> - SumUpAPI.checkout(this, actionRequest.payment, REQUEST_CODE_PAYMENT) - SdkActionRequest.OpenCardReaderPage -> - SumUpAPI.openCardReaderPage(this, REQUEST_CODE_CARD_READER_PAGE) + is SdkActionRequest.OpenLogin -> loginLauncher.launch(actionRequest.login) + is SdkActionRequest.StartCheckout -> checkoutLauncher.launch(actionRequest.payment) + SdkActionRequest.OpenCardReaderPage -> cardReaderPageLauncher.launch(null) } } - - private companion object { - private const val REQUEST_CODE_LOGIN = 101 - private const val REQUEST_CODE_PAYMENT = 102 - private const val REQUEST_CODE_CARD_READER_PAGE = 103 - } } @Composable diff --git a/app/src/main/java/com/sumup/app/presentation/MainViewModel.kt b/app/src/main/java/com/sumup/app/presentation/MainViewModel.kt index 53083ff..c467a92 100644 --- a/app/src/main/java/com/sumup/app/presentation/MainViewModel.kt +++ b/app/src/main/java/com/sumup/app/presentation/MainViewModel.kt @@ -12,7 +12,6 @@ import com.sumup.app.domain.usecase.ParseSdkStatusUseCase import com.sumup.app.presentation.model.SdkActionRequest import com.sumup.app.presentation.model.UiEvent import com.sumup.app.presentation.model.UiState -import com.sumup.app.util.CoroutinesDispatcherProvider import com.sumup.app.util.handleFailure import com.sumup.app.util.safelySuspend import com.sumup.merchant.reader.api.SumUpAPI @@ -35,7 +34,6 @@ internal class MainViewModel( private val parseSdkStatusUseCase: ParseSdkStatusUseCase, private val parsePaymentResultUseCase: ParsePaymentResultUseCase, private val readerSdkRepository: ReaderSdkRepository, - private val dispatcherProvider: CoroutinesDispatcherProvider, ) : ViewModel() { private val _uiState = MutableStateFlow(UiState()) diff --git a/build.gradle.kts b/build.gradle.kts index 3260c66..e30ca7a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,9 +6,8 @@ buildscript { google() } dependencies { - classpath("com.android.tools.build:gradle:8.9.1") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.1.20") - classpath("org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.1.20") + classpath("com.android.tools.build:gradle:9.2.1") + classpath("org.jetbrains.kotlin:compose-compiler-gradle-plugin:2.4.0") } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1f67664..4dbaa9c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Sep 02 09:19:11 CEST 2020 +#Mon Jun 15 14:36:11 CEST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip