From 928fe1c2687773db99ab52523ce3f7d020658348 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Mar 2026 17:15:56 +0000 Subject: [PATCH 1/2] feat(android): update for 2.7.4 Co-Authored-By: Claude Opus 4.5 --- content/docs/android/changelog.mdx | 14 ++++++++++++++ content/docs/android/index.mdx | 2 +- content/docs/android/quickstart/install.mdx | 2 +- content/docs/android/sdk-reference/index.mdx | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/content/docs/android/changelog.mdx b/content/docs/android/changelog.mdx index eccbc836..311ad97b 100644 --- a/content/docs/android/changelog.mdx +++ b/content/docs/android/changelog.mdx @@ -3,6 +3,20 @@ title: "Changelog" description: "Release notes for the Superwall Android SDK" --- +## 2.7.4 + +### Enhancements + +- Adds support for "Test Mode", which allows you to simulate in-app purchases without involving Google Play. Test Mode can be enabled through the Superwall dashboard by marking specific users as test store users, or activates automatically when a an application ID mismatch is detected or behavior is set to `ALWAYS`. When active, a configuration modal lets you select starting entitlements and override free trial availability. Purchases are simulated with a UI that lets users complete, abandon, or fail transactions, with all purchase events firing normally for end-to-end paywall testing. +- Improved logging in web entitlement and entitlement redeeming for easier debugging +- Adds active entitlements to subscription status change event +- Ensures purchases are always queried with connected clients and retried in background +- Adds `expirationDate`, `subscriptionGroupId` and `offerId` to `StoreTransactionType` + +### Fixes + +- Improve rounding to match editor's pricing consistently + ## 2.7.3 ### Enhancements diff --git a/content/docs/android/index.mdx b/content/docs/android/index.mdx index 12dfa5ec..3c23f791 100644 --- a/content/docs/android/index.mdx +++ b/content/docs/android/index.mdx @@ -42,4 +42,4 @@ If you have feedback on any of our docs, please leave a rating and message at th If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-android/issues). - + diff --git a/content/docs/android/quickstart/install.mdx b/content/docs/android/quickstart/install.mdx index 7a81dfdd..b02fb92b 100644 --- a/content/docs/android/quickstart/install.mdx +++ b/content/docs/android/quickstart/install.mdx @@ -20,7 +20,7 @@ can find the [latest release here](https://github.com/superwall/Superwall-Androi ```gradle build.gradle -implementation "com.superwall.sdk:superwall-android:2.7.3" +implementation "com.superwall.sdk:superwall-android:2.7.4" ``` ```kotlin build.gradle.kts diff --git a/content/docs/android/sdk-reference/index.mdx b/content/docs/android/sdk-reference/index.mdx index c98c80aa..0a37af33 100644 --- a/content/docs/android/sdk-reference/index.mdx +++ b/content/docs/android/sdk-reference/index.mdx @@ -15,4 +15,4 @@ If you have feedback on any of our docs, please leave a rating and message at th If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-android/issues). - + From d9da244920df60956788d41a2c6a11e40167fdb8 Mon Sep 17 00:00:00 2001 From: Duncan Crawbuck Date: Mon, 2 Mar 2026 16:07:16 -0800 Subject: [PATCH 2/2] fix(android): complete 2.7.4 version strings and SDK reference updates Update all install snippets (build.gradle.kts, libs.version.toml) to 2.7.4, add testModeBehavior to SuperwallOptions reference, expand SuperwallEvent signature with missing events, and remove version-specific changelog sections in favor of inline definitions. --- content/docs/android/quickstart/install.mdx | 4 +- .../android/sdk-reference/SuperwallEvent.mdx | 77 +++++++++---------- .../sdk-reference/SuperwallOptions.mdx | 7 ++ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/content/docs/android/quickstart/install.mdx b/content/docs/android/quickstart/install.mdx index b02fb92b..969519da 100644 --- a/content/docs/android/quickstart/install.mdx +++ b/content/docs/android/quickstart/install.mdx @@ -24,12 +24,12 @@ implementation "com.superwall.sdk:superwall-android:2.7.4" ``` ```kotlin build.gradle.kts -implementation("com.superwall.sdk:superwall-android:2.7.3") +implementation("com.superwall.sdk:superwall-android:2.7.4") ``` ```toml libs.version.toml [libraries] -superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.7.3" } +superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.7.4" } // And in your build.gradle.kts dependencies { diff --git a/content/docs/android/sdk-reference/SuperwallEvent.mdx b/content/docs/android/sdk-reference/SuperwallEvent.mdx index 8c6c6daf..3e4ff1f4 100644 --- a/content/docs/android/sdk-reference/SuperwallEvent.mdx +++ b/content/docs/android/sdk-reference/SuperwallEvent.mdx @@ -86,8 +86,45 @@ sealed class SuperwallEvent { object SubscriptionStatusDidChange : SuperwallEvent() + // Restore events + sealed class Restore : SuperwallEvent() { + object Start : Restore() + data class Fail(val error: String) : Restore() + object Complete : Restore() + } + + // Customer and permission events + data class CustomerInfoDidChange( + val from: CustomerInfo, + val to: CustomerInfo + ) : SuperwallEvent() + data class PermissionRequested( + val permissionName: String, + val paywallIdentifier: String + ) : SuperwallEvent() + data class PermissionGranted( + val permissionName: String, + val paywallIdentifier: String + ) : SuperwallEvent() + data class PermissionDenied( + val permissionName: String, + val paywallIdentifier: String + ) : SuperwallEvent() + + // Preloading events + data class PaywallPreloadStart(val paywallIdentifier: String) : SuperwallEvent() + data class PaywallPreloadComplete(val paywallCount: Int) : SuperwallEvent() + + // Test mode events + class TestModeModalOpen : SuperwallEvent() + class TestModeModalClose : SuperwallEvent() + // System events data class DeviceAttributes(val attributes: Map) : SuperwallEvent() + data class SurveyResponse(val survey: Survey, val selectedOption: SurveyOption, val customResponse: String?, val paywallInfo: PaywallInfo) : SuperwallEvent() + class SurveyClose : SuperwallEvent() + data class CustomPlacement(val name: String, val params: Map, val paywallInfo: PaywallInfo) : SuperwallEvent() + object Reset : SuperwallEvent() // And more... } @@ -115,43 +152,3 @@ This is a sealed class that represents different event types. Events are receive These events are received via [`SuperwallDelegate.handleSuperwallEvent(eventInfo)`](/android/sdk-reference/SuperwallDelegate) for forwarding to your analytics platform. -## Deprecations in 2.7.0 - -- `PaywallWebviewLoadTimeout` is deprecated. This event was causing confusion due to its naming and has been removed from internal tracking. It will no longer fire. - -## New events in 2.6.6+ - -- `CustomerInfoDidChange` fires whenever the SDK merges device, web, and external purchase controller data into a new [`CustomerInfo`](/android/quickstart/tracking-subscription-state#reading-detailed-purchase-history-2-6-6) snapshot. The event includes the previous and next objects so you can diff entitlements or transactions. -- `PermissionRequested`, `PermissionGranted`, and `PermissionDenied` correspond to the new **Request permission** action in the paywall editor. Each event carries the `permissionName` and `paywallIdentifier`. -- `PaywallPreloadStart` and `PaywallPreloadComplete` track when preloading kicks off and how many paywalls finished warming the cache. - -Example handler: - -```kotlin -override fun handleSuperwallEvent(eventInfo: SuperwallEventInfo) { - when (val event = eventInfo.event) { - is SuperwallEvent.CustomerInfoDidChange -> { - analytics.track("customer_info_updated", mapOf( - "old_products" to event.from.activeSubscriptionProductIds.joinToString(), - "new_products" to event.to.activeSubscriptionProductIds.joinToString() - )) - } - is SuperwallEvent.PermissionRequested -> { - analytics.track("permission_requested", mapOf( - "permission" to event.permissionName, - "paywall_id" to event.paywallIdentifier - )) - } - is SuperwallEvent.PermissionGranted -> { - featureFlags.unlock(event.permissionName) - } - is SuperwallEvent.PermissionDenied -> { - showPermissionHelpSheet(event.permissionName) - } - is SuperwallEvent.PaywallPreloadComplete -> { - Logger.i("Superwall", "Preloaded ${event.paywallCount} paywalls") - } - else -> Unit - } -} -``` diff --git a/content/docs/android/sdk-reference/SuperwallOptions.mdx b/content/docs/android/sdk-reference/SuperwallOptions.mdx index e1b49847..a4d01bde 100644 --- a/content/docs/android/sdk-reference/SuperwallOptions.mdx +++ b/content/docs/android/sdk-reference/SuperwallOptions.mdx @@ -31,6 +31,7 @@ class SuperwallOptions { var enableExperimentalDeviceVariables: Boolean = false var logging: Logging = Logging() var useMockReviews: Boolean = false + var testModeBehavior: TestModeBehavior = TestModeBehavior.AUTOMATIC } ``` @@ -47,6 +48,7 @@ public class SuperwallOptions { public boolean enableExperimentalDeviceVariables = false; public Logging logging = new Logging(); public boolean useMockReviews = false; + public TestModeBehavior testModeBehavior = TestModeBehavior.AUTOMATIC; } ``` @@ -106,6 +108,11 @@ public class SuperwallOptions { description: "Shows mock Google Play review dialogs for testing.", required: true, }, + testModeBehavior: { + type: "TestModeBehavior", + description: "Controls when test mode activates. `AUTOMATIC` enables test mode when an application ID mismatch is detected. `WHEN_ENABLED_FOR_USER` only activates when the user is marked as a test store user in the dashboard. `ALWAYS` forces test mode on. `NEVER` disables it entirely.", + default: "AUTOMATIC", + }, }} />