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..969519da 100644
--- a/content/docs/android/quickstart/install.mdx
+++ b/content/docs/android/quickstart/install.mdx
@@ -20,16 +20,16 @@ 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
-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",
+ },
}}
/>
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).
-
+