Migration guide
Migrating to 8.0.0
Overview
This release is built with the Swift 6 compiler and strict concurrency checking. The public API is unchanged — no classes or methods have been renamed or removed — so for most merchants this is a toolchain upgrade, not a code rewrite.
Requirements (mandatory)
These apply to every integration, regardless of the language your app is written in:
- Xcode 26.6 or later: The SDK is built with the Swift 6.3.3 compiler; older Xcode versions cannot import the framework.
- iOS 15.0 deployment target or higher: Earlier iOS versions are no longer supported.
Do I need to change any code?
Find your project's language below. The requirements above still apply in all three cases — this table covers source changes only.
| Your project | Source-code changes required? | What to do (if anything) |
|---|---|---|
| Objective-C | No | Nothing. The public interface is unchanged and Objective-C is unaffected by Swift's new concurrency annotations. Ship as usual after the toolchain upgrade. |
| Swift, using the Swift 5 language mode | No | Nothing required. Your code keeps compiling — the SDK's stricter concurrency annotations surface as optional warnings you can address whenever convenient. |
| Swift, using the Swift 6 language mode | No breaking changes; one optional cleanup. | Existing integration code continues to compile. You may remove any manual DispatchQueue.main.async that existed only to make SDK callbacks safe — see “Main-thread delivery” below. |
Regardless of language: if your integration uses one of the three callbacks listed under “Callbacks still delivered off the main thread”, you must keep a manual main-queue hop before updating UI. This was already required before this release; it has not changed.
Main-thread callback delivery
The behavioural change in this release: SDK completion handlers and delegate callbacks now arrive on the main thread. You can update UI directly inside them.
Callbacks delivered on the main thread
- OPPCheckoutProvider — presentCheckout… completion and cancel handlers.
- OPPCheckoutProviderDelegate — continueSubmitting:completion:, continueSubmitting:andAddOnDetails:completion:, and the Apple Pay shipping-method / shipping-contact / authorization handlers.
- OPPPaymentProvider — network responses for submitTransaction, sendTransaction, registerTransaction, requestCheckoutInfoWithCheckoutID, requestBinInfoWithCheckoutID, requestLogoURLsForPaymentBrands, requestIdealBanksWithCheckoutID, requestCheckoutDataWithCheckoutID, requestApplesTokenIdWithCheckoutID, and getVisaInstallmentPlans.
- Merchant-facing brand processors — OPPAffirmProcessor, OPPCashAppPayProcessor, OPPBraintreeProcessor, OPPPazeProcessor, OPPPayToProcessor, OPPAfterpayUtil, OPPKlarnaPaymentViewWrapper.
Example — Swift, before and after:
// Before — manual hop was required
provider.submitTransaction(transaction) { transaction, error in
DispatchQueue.main.async {
self.updateUI(with: transaction, error: error)
}
}
// After — the callback already runs on the main thread
provider.submitTransaction(transaction) { transaction, error in
self.updateUI(with: transaction, error: error) // safe
}
Under the hood: In the public headers you will notice the completion blocks on OPPPaymentProvider, OPPCheckoutProvider, OPPCheckoutProviderDelegate, OPPAffirmProcessor, and OPPCashAppPayProcessor now carry the NS_SWIFT_NONSENDABLE annotation. This is expected: Swift imports such blocks as non-Sendable, so a closure you pass from a @MainActor type (a SwiftUI view model or a view controller) inherits @MainActor isolation — which matches the main-thread delivery described above. Objective-C ignores the annotation, so Objective-C integrations are not affected.
Callbacks still delivered off the main thread
Three callbacks are exceptions. If you use any of them and touch UI or @MainActor state inside the block, add a hop to the main queue yourself. This was already the case before this release.
| Callback | Delivery thread |
|---|---|
| OPPPaymentProvider.securityWarningsWithCompletionHandler: | A background queue — the 3-D Secure service initialises on a global concurrent queue. |
| Any OPPPaymentProvider completion when the request cannot be serialised (e.g. an invalid URL or parameters) | The caller's thread — the early-return error path fires before the network hop. |
| OPPPaymentProvider threeDSEventListener — onThreeDSChallengeRequiredWithCompletion: | The thread the 3-D Secure SDK triggers the challenge on; a background thread on the app-to-web fallback path. |
Methods you must call on the main thread
One public method now requires the main thread: OPPPazeProcessor.startPaze (custom-UI Paze) is annotated @MainActor because it presents a web-authentication screen. Call it from the main thread — correctly-written UI code already does. The primary entry points, OPPPaymentProvider and OPPCheckoutProvider, are not @MainActor and can be called from any thread.
Testing
Before shipping to production, run the following against your staging environment:
- Full checkout with your staging credentials.
- Every payment method your app offers, end-to-end.
- 3-D Secure challenge flow and Apple Pay, if enabled.
- Confirm success / cancel / error UI still updates correctly from SDK callbacks.
- Your existing UI / automation regression suite.
Migrating to 8.0.0
Overview
Migrating to 8.0.0 involves updating your project to align with the latest Android platform requirements and development tooling. This release introduces support for Android API Level 36 (Android 16), upgrades the Kotlin and Gradle ecosystem, refreshes all major dependencies to their latest stable versions, and includes an internal update to the onNewIntent() method signature.
These changes improve platform compatibility, build performance, security, and long-term maintainability while ensuring readiness for future Android releases.
What's Changing?
- Kotlin updated to 2.2.0.
- Android Gradle Plugin (AGP) updated to 8.13.0.
- Gradle updated to 8.14.5.
compileSdkVersionandtargetSdkVersionupdated to Android API Level 36 (Android 16).- All dependencies updated to their latest stable versions.
- Internal update to the
onNewIntent()method signature.
Benefits
- Android 16 Support: Full compatibility with the latest Android devices and operating system features.
- Better Performance and Stability: Improved Kotlin version and updated dependency stack.
- Improved Build Experience: Faster and more reliable builds using the latest Gradle and Android Gradle Plugin versions.
- Security and Maintenance: Latest dependency updates, bug fixes, and security patches.
- Future Readiness: Aligned with upcoming Android platform requirements and best practices.
Steps
To ensure a smooth transition to the updated library, we recommend the following steps:
1. Update your development environment
- Upgrade Android Studio to Narwhal (2025.1.1) or later.
- Update your Gradle distribution to gradle-8.14.5.
- Ensure your JDK is set to Java 17 (required for AGP 8.13.0).
2. Update your project configuration
- Set
sourceCompatibilityandtargetCompatibilitytoJavaVersion.VERSION_17. - Set
compileSdkVersionandtargetSdkVersionto 36. - Set
kotlinOptions { jvmTarget = "17" }.
Example configuration:
android {
compileSdkVersion 36
defaultConfig {
targetSdkVersion 36
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
Android Gradle Plugin
Update Android Gradle Plugin (AGP), in project-level build.gradle file, update the android build gradle dependency to:
dependencies {
classpath "com.android.tools.build:gradle:8.13.0"
}
In the gradle-wrapper.properties file, update the distributionUrl to:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip
In your project-level build.gradle file, if you are using Kotlin, update the Kotlin version to 2.2.0
buildscript {
ext.kotlin_version = "2.2.0"
}
3. Upgrade edge-to-edge design principles for Android 16
Applications targeting Android API Level 36 should adhere to edge-to-edge design principles. This helps ensure a modern user experience and proper use of the available screen space on newer Android devices.
Please refer to the official Android documentation for implementation details:
https://developer.android.com/develop/ui/views/layout/edge-to-edge?utm_source=android-studio-app&utm_medium=app target="_blank"> Edge-to-Edge Design Guidelines
4. Handle onNewIntent() signature change (if applicable)
The SDK now uses AppCompat versions that require a non-null Intent parameter in the onNewIntent() callback.
This change only affects applications that explicitly override the onNewIntent() method. Most integrations will not require any code changes.
If your application overrides onNewIntent() in any Activity, update the method signature as shown below.
If you are using Java
Before
@Override
protected void onNewIntent(@Nullable Intent intent) {
super.onNewIntent(intent);
}
After (required)
@Override
protected void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
}
If you are using Kotlin
Before
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
}
After
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
}
5. Update dependencies
Update all Android, AndroidX, testing, and third-party dependencies to their latest stable versions to ensure compatibility with Android API Level 36 and the updated SDK stack.
Testing
Test your application with the updated library in a staging environment to identify any compatibility issues early.
Testing should include:
- Staging Environment: Test your application with the updated configuration in a staging environment before production deployment.
- Device Coverage: Test on multiple devices ranging from the minimum Android API level supported by your application up to Android API Level 36.
- Functional Testing: Verify that all application features, payment flows, and checkout scenarios work as expected.
- Performance Testing: Assess application startup performance, payment processing, and overall responsiveness with the updated SDK.
- Regression Testing: Ensure that existing functionality continues to work correctly after the migration.
Summary
Migrating to 8.0.0 ensures compatibility with Android 16, introduces the latest Kotlin and build tooling updates, improves overall stability and performance, and keeps your application aligned with modern Android development practices.
We recommend completing all migration and validation activities in a staging environment before deploying the updated SDK to production.
Migrating to 7.0.0
Migrating to 7.0.0 consist of two stages
- Migration Guide from JDK 11 to JDK 17
- Migration Guide from Android API Level 33 to API Level 35
1. Migration Guide from JDK 11 to JDK 17
Overview
Migrating from JDK 11 to JDK 17 involves updating your project to leverage the latest features, performance improvements, and security enhancements provided by Java 17. This guide will walk you through the necessary steps to ensure a smooth transition.
Steps
- Download JDK 17
First, download JDK 17 from Android Studio settings:
- Go to
File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle. - In the
Gradle JDKdrop-down, selectDownload JDKand choose JDK 17.
- Go to
- Update Project Configuration
Modify your build configuration to specify Java 17 as the target version. This involves updating the
build.gradlefile in your project.android { compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { jvmTarget = "17" } }In your project-level
build.gradlefile, if you are using Kotlin, update the Kotlin version to 1.8.21 (or the latest available)buildscript { ext.kotlin_version = "1.8.21" }Update Android Gradle Plugin (AGP), in project-level
build.gradlefile, update the android build gradle dependency to:dependencies { classpath "com.android.tools.build:gradle:8.8.2" }In the gradle-wrapper.properties file, update the
distributionUrlto:distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip - Update Dependencies
Ensure all dependencies are compatible with Java 17. Check for updates or replacements for any libraries that may not support Java 17.
- Testing
Thoroughly test your application to identify and resolve any issues that may arise from the migration. Use automated tests to ensure compatibility and stability.
- Build and Deployment
Update your build tools and CI/CD pipelines to use Java 17. Deploy the updated application to a staging environment for further testing before production rollout.
Benefits
- Improved performance and security.
- Access to new language features.
- Enhanced stability and efficiency.
2. Migration Guide from Android API Level 33 to API Level 35
Overview
Migrating from Android API Level 33 to API Level 35 involves updating your project to target the latest Android platform, ensuring compatibility with new features and optimizations.
Note: If you are targeting your application to Android API 35, it is mandatory to upgrade to Java 17. Google recommends using Java 17 as the minimum JDK version for targeting Android API 35. For more details, you can refer to the official documentation here.
Steps
- Update Project Configuration
Modify your
build.gradlefile to setcompileSdkVersionandtargetSdkVersionto 35:android { namespace("com.example.appname") // you need to add your package name here compileSdkVersion 35 defaultConfig { targetSdkVersion 35 } } - Update Dependencies
Update all
androidandandroidTestdependencies to their latest stable versions. Update the Kotlin version to 1.8.21 (or the latest available). - Edge-to-Edge Design Principles
Implement edge-to-edge design principles to fully utilize the screen area. Refer to the Edge-to-Edge Design Guidelines for detailed instructions.
- Testing
Test your application with the updated configurations in a staging environment to ensure compatibility and identify any potential issues early.
Testing should include:
- Staging Environment: Test your application with the updated configurations in a staging environment to ensure compatibility and identify any potential issues early.
- Device Coverage: Test on multiple devices ranging from the minimum API level supported by your application to API level 35. This ensures that your application works seamlessly across different Android versions and devices.
- Functional Testing: Verify that all functionalities of your application work as expected with the new configurations.
- Performance Testing: Assess the performance improvements brought by the new Android API level.
- Regression Testing: Ensure that existing features continue to work correctly after the migration.
Migrating to 6.x.x
Minimal supported iOS version has been changed to iOS 12.
API Deprecations
| Deprecated in 5.x.x | Use instead in 6.x.x | |
|---|---|---|
| OPPCheckoutInfo | ||
@property (nonatomic, copy) NSArray |
Not used anymore. | |
@property (nonatomic, assign) OPPThreeDS2Flow threeDS2Flow |
Not used anymore. | |
@property (nonatomic, getter=isBrowserParamsRequired) BOOL browserParamsRequired |
Not used anymore. | |
Increased the minimal required API level
In order to support the new features and payment methods the minimal API level required for Mobile SDK has been changed to 24.
Please make sure your application uses minSdkVersion 24 or above.
Handling asynchronous payments with Ready-to-Use UI
To simplify the Ready-to-Use UI integration the CheckoutActivity will handle the redirect to the shopper result URL. For this reason the shopper result URL has been removed from the CheckoutSettings. As a result setting the intent filter for the shopper result URL and handling the redirect in onNewIntent callback are not required anymore.
API Deprecations
| Deprecated in 5.x.x | Use instead in 6.x.x | |
|---|---|---|
| CheckoutThreeDS2Flow | Not used anymore. | |
| CheckoutInfo | ||
String[] getThreeDS2Brands() |
Not used anymore. | |
CheckoutThreeDS2Flow getThreeDS2Flow() |
Not used anymore. | |
boolean isBrowserParamsRequired() |
Not used anymore. | |
Migrating to 5.x.x
Simplified 3D Secure 2.x integration
Since Mobile SDK 5.0.0 the external initialization of 3DS service was removed. Now it is fully managed by Mobile SDK. Please check 3D Secure 2 page for more details. Check your integration for OPPThreeDSService leftovers and remove if any.
Use the threeDSConfig property of the OPPCheckoutSettings instance to assign OPPThreeDSConfig.
OPPThreeDSConfig *config = [[OPPThreeDSConfig alloc] init];
checkoutSettings.threeDSConfig = config;
let config = OPPThreeDSConfig()
checkoutSettings.threeDSConfig = config
Core API Deprecations
| Deprecated in 4.x.x | Use instead in 5.x.x | |
|---|---|---|
| OPPPaymentProvider | ||
+paymentProviderWithMode:andDomain: |
Not used anymore. |
|
@property OPPProviderDomain domain |
Not used anymore. |
|
-requestPaymentBrandsForBin:checkoutID:completionHandler: |
-requestBinInfoWithCheckoutID:bin:completionHandler: |
|
Required dependencies
Because Mobile SDK distributed as .aar file it doesn't include transitive dependencies.
Your application build.gradle must define them.
implementation "androidx.appcompat:appcompat:1.4.2"
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation "androidx.browser:browser:1.4.0"
implementation "androidx.fragment:fragment-ktx:1.4.1"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.webkit:webkit:1.6.0"
implementation "com.google.android.material:material:1.6.1"
implementation "com.google.code.gson:gson:2.8.9"
Make sure viewBinding feature is enabled.
buildFeatures {
viewBinding true
}
Simplified 3D Secure 2.x integration
Since Mobile SDK 5.0.0 the external initialization of 3DS service was removed. Now it is fully managed by Mobile SDK. Please check 3D Secure 2 page for more details.
Using Activity Result API
The Mobile SDK started to use Activity Result API for Ready-to-Use UI. The method to create the intent was removed from CheckoutSettings, use CheckoutActivityResultContract instead. Please check Present Checkout UI for more details.
API Deprecations
| Deprecated in 4.x.x | Use instead in 5.x.x | |
|---|---|---|
| CheckoutSettings | ||
Intent createCheckoutActivityIntent(Context context) |
CheckoutActivityResultContract |
|
CheckoutSettings setProviderDomain(Connect.ProviderDomain providerDomain) |
Not used anymore. | |
Intent createCheckoutActivityIntent(Context context, ComponentName componentName) |
CheckoutActivityResultContract |
|
| PaymentButtonFragment | ||
void submitTransaction(CheckoutSettings checkoutSettings, ComponentName componentName) |
Set componentName in the CheckoutSettings before submitting transaction. |
|
| CardPaymentParams | ||
boolean isNumberValid(String cardNumber) |
boolean isNumberValid(String cardNumber, boolean luhnCheck) |
|
boolean checkLuhn(String cardNumber) |
boolean isNumberValid(String cardNumber, boolean luhnCheck) |
|
| OppPaymentProvider | ||
OppPaymentProvider(Context context, Connect.ProviderMode providerMode, Connect.ProviderDomain providerDomain) |
Not used anymore. | |
void requestPaymentBrandsForBin(String bin, String checkoutId, ITransactionListener listener) |
void requestBinInfo(String checkoutId, String bin, BinInfoListener listener |
|
void sendThreeDS2AuthParams(String authParams, Transaction transaction, ThreeDS2AuthResponseListener listener) |
The authentication parameters will be sent automatically. | |
Naming changes
com.oppwa.mobile.connect.threeds.OppThreeDSConfig->com.oppwa.mobile.connect.provider.threeds.v2.model.ThreeDSConfigcom.oppwa.mobile.connect.threeds.constant.ChallengeUiType->com.oppwa.mobile.connect.provider.threeds.v2.model.ChallengeUiType
Migrating to 4.x.x
One framework instead of two
Mobile 3DS SDK wrapper OPPWAMobile_ThreeDS.xcframework is deprecated now - all 3DS functionality is build into Mobile SDK OPPWAMobile.xcframework. So before moving forward:
- Remove
OPPWAMobile_ThreeDS.xcframeworkfrom your project. - Review your project settings - General and Build Phases tabs for ThreeDS wrapper leftovers.
Import mandatory library
As 3DS SDK now is a part of Mobile SDK you have to import the following framework to the project:
ipworks3ds_sdk.xcframework // certified 3DS SDK
There are two versions of the ipworks3ds_sdk.xcframework included: one to be used for development and one for production. The production version includes more strict security measures that would not allow for common development processes to occur, including running with attached debuggers or using simulators/emulators. The deployment version includes _deploy in the filename.
- Drap and drop
ipworks3ds_sdk.xcframeworkto the "Frameworks" folder of your project.
Make sure "Copy items if needed" is checked. - Embed the frameworks
- Go to the app target’s General configuration page.
- Add the frameworks target to the Frameworks, Libraries, and Embedded Content section by clicking the Add icon.
- Review your Build Phases:
ipworks3ds_sdk.xcframeworkis added to the "Link Binary With Libraries".
One framework instead of two
Mobile 3DS SDK wrapper oppwa.mobile.threeds.aar is deprecated now - all 3DS functionality is build into Mobile SDK oppwa.mobile.aar. So before moving forward remove oppwa.mobile.threeds.aar from your project.
Import mandatory library
As 3DS SDK now is a part of Mobile SDK you have to import the following framework to the project:
ipworks3ds_sdk.aar // certified 3DS SDK
Drag and drop ipworks3ds_sdk.aar (use ipworks3ds_sdk_deploy.aar for production) to the "libs" folder of the module where you plan to integrate Mobile SDK.
There are two versions of the ipworks3ds_sdk included: one to be used for development and one for production. The production version includes more strict security measures that would not allow for common development processes to occur, including running with attached debuggers or using simulators/emulators. The deployment version includes _deploy in the filename.
Easy Custom UI 3D Secure 2.x integration
The highlight of Mobile SDK 4.x is an easy Your Own UI 3D Secure 2.x integration. You don't need to send authentication parameters, display processing view and handle authentication response anymore - all these steps integrated into Submit Transaction call. Check MSDK + Your Custom UI page for more details.
Checkout API Deprecations
| Deprecated in 3.x.x | Use instead in 4.x.x | |
|---|---|---|
| OPPCheckoutSettings | ||
@property BOOL showDetectedBrands |
@property OPPCheckoutBrandDetectionAppearanceStyle brandDetectionAppearanceStyle |
|
| Deprecated in 3.x.x | Use instead in 4.x.x | |
|---|---|---|
| CheckoutSettings | ||
boolean isDetectedBrandsShown() |
CheckoutBrandDetectionAppearanceStyle getBrandDetectionAppearanceStyle() |
|
CheckoutSettings setShowDetectedBrands(boolean isDetectedBrandsShown) |
CheckoutSettings setBrandDetectionAppearanceStyle(CheckoutBrandDetectionAppearanceStyle brandDetectionAppearanceStyle) |
|
PaymentDataRequest getGooglePayPaymentDataRequest() |
String getGooglePayPaymentDataRequestJson() |
|
CheckoutSettings setGooglePayPaymentDataRequest(PaymentDataRequest paymentDataRequest) |
CheckoutSettings setGooglePayPaymentDataRequestJson(String googlePayPaymentDataRequestJson) |
|
Core API Deprecations
| Deprecated in 3.x.x | Use instead in 4.x.x | |
|---|---|---|
| OPPTransaction | ||
@property NSString *alipaySignedOrderInfo |
@property NSDictionary |
|
| OPPThreeDSService | ||
public func createTransaction(paymentBrand:) |
public func createTransaction(paymentBrand:protocolVersion:) |
|
| OPPThreeDSSchemeConfig | ||
public var protocolVersion |
Set protocol version during creation of the transaction OPPThreeDSService.createTransaction(paymentBrand:protocolVersion:) |
|
| Deprecated in 3.x.x | Use instead in 4.x.x | |
|---|---|---|
| ConnectService | Not used anymore. Use OppPaymentProvider directly. | |
| IProviderBinder | Not used anymore. | |
| PaymentProviderNotInitializedException | Not used anymore. | |
| Transaction | ||
String BANCONTACT_SECURE_TRANSACTION_ID_KEY |
String BANCONTACT_LINK_APP_SCHEME_URL_KEY |
|
| GooglePayPaymentParams | ||
GooglePayPaymentParams(String checkoutId, String paymentToken) |
GooglePayPaymentParams(String checkoutId, String paymentToken, String cardBrand) |
|
| OppThreeDSService | ||
OppThreeDSTransaction createTransaction(String paymentBrand) |
OppThreeDSTransaction createTransaction(String paymentBrand, String protocolVersion) |
|
| SchemeConfig | ||
String DEFAULT_PROTOCOL_VERSION |
Not used anymore. | |
void setProtocolVersion(String protocolVersion) |
The protocol version should be passed to the createTransaction(String paymentBrand, String protocolVersion) method of the OppThreeDSService instead. | |
String getProtocolVersion() |
Not used anymore. | |