Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions content/docs/android/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,52 @@ title: "Changelog"
description: "Release notes for the Superwall Android SDK"
---

## 2.8.0

## Enhancements
- ⚠️ Updates Google Play Billing Library from 8.0.0 to 9.1.0. See the [Play Billing Library 9 migration guide](https://developer.android.com/google/play/billing/migrate-gpblv9) for the full list of changes. ⚠️
- Adds support for custom store products. Products configured on a custom store in the Superwall dashboard (e.g. Stripe or your own payment backend) can now be attached to paywalls: their metadata (price, subscription period, trial) is fetched from the Superwall API instead of Google Play and templated into the paywall like any other product. Purchases are routed through your `PurchaseController`, bypassing Google Play Billing entirely — check `product.isCustomProduct` to fulfill them via your own payment flow, and grant their entitlements with `Superwall.instance.setSubscriptionStatus(...)` on success. Requires configuring the SDK with a `PurchaseController`.
- Adds a unified `PurchaseController.purchase(activity, product: StoreProduct, basePlanId, offerId)` method that handles both Google Play and custom store products. For Play products, the underlying `ProductDetails` are available via `product.rawStoreProduct`.
- Custom purchases produce full transaction analytics (`transaction_start`/`transaction_complete`, `subscriptionStart`/`freeTrialStart`) with an SDK-generated transaction identifier exposed as `StoreProduct.customTransactionId`, and free-trial eligibility for custom products is derived from the customer's entitlement history.
- Adds `ApiStoreProduct`, a product backed by Superwall API data, used for custom store products.

## Breaking Changes
- System back presses are now forwarded into the paywall as a `back_button_input` message instead of dismissing it directly: multi-page flows navigate back one page, and paywalls with nowhere to go back (root page, single page) close themselves through the standard manual-close path (`Declined`/`ManualClose`) — so single-page paywalls dismiss the same as before, from the app's perspective. When `reroute_back_button` is enabled in Paywall settings, the `PaywallOptions.onBackPressed` app callback keeps first refusal before the press is forwarded. Paywalls built on runtimes that predate `back_button_input` will ignore the press; this means that previously existing Multi-page paywalls, if republished, will now navigate back inside the paywall once republished.
- Removes the deprecated `SuperwallBillingFlowParams.Builder.setSkuDetails(SkuDetails)`. Billing Library 9 removes `SkuDetails` entirely, so this method can no longer exist. Use `setProductDetailsParamsList(...)` with `ProductDetails` instead.
- Removes the unused internal `com.superwall.sdk.billing.SWProduct`, which wrapped the now-removed `SkuDetails`.
- Internal purchase-history queries now resolve current purchases via `QueryPurchasesParams` — Billing Library 9 removes the purchase-history APIs (`queryPurchaseHistoryAsync`, `QueryPurchaseHistoryParams`).
- **Impact:** if your app still calls the removed Billing Library APIs (`SkuDetails`, `SkuDetailsParams`, `querySkuDetailsAsync`, `queryPurchaseHistoryAsync`, `BillingClient.SkuType`, or the no-arg `enablePendingPurchases()`), it will no longer compile once it picks up Billing 9 through this SDK. Migrate those call sites to the `ProductDetails` APIs before upgrading; the [migration guide](https://developer.android.com/google/play/billing/migrate-gpblv9) has a mapping of every removed API to its replacement.
- **Please test your billing and purchasing flows before shipping this upgrade.** Because the Billing Library is resolved to a single version across your app, upgrading Superwall also upgrades Billing for everything else that depends on it. If you use Google Play Billing directly, or another subscription provider such as RevenueCat, Adapty or Purchasely, make sure that provider's SDK supports Billing 9 and run through purchase, restore and subscription-status flows end to end.
- **If you use other subscription management libraries (RC, Purchasely, Adapty) and they do not support Play Billing 9:** you can pin the Billing Client version to 8 in the following way.

Add this to your app module's `build.gradle.kts`, outside the `android { }` block:

```kotlin
configurations.all {
resolutionStrategy.force("com.android.billingclient:billing:8.3.0")
}
```

Or in Groovy (`build.gradle`):

```groovy
configurations.all {
resolutionStrategy.force 'com.android.billingclient:billing:8.3.0'
}
```

You can confirm which version you end up with via `./gradlew :app:dependencies --configuration releaseRuntimeClasspath` — look for `com.android.billingclient:billing:9.1.0 -> 8.3.0`. Billing 8 still satisfies Google's August 31, 2026 requirement, so this is a safe interim state, and no Superwall functionality is lost: the SDK works on both 8.x and 9.x.

Note that a `-dontwarn com.android.billingclient.api.QueryPurchaseHistoryParams` ProGuard rule is **not** a fix. It silences the R8 error and lets the build through, but then throws at runtime.

## ⚠️ Minimum SDK version raised to 23

Google Play Billing Library 9 requires Android 6.0 (API 23), so the SDK's `minSdk` is now **23** (previously 21). If your app's `minSdk` is below 23, you'll need to raise it to pick up this release — devices on Android 5.x will no longer receive app updates that include this SDK version.

## Deprecations

- Deprecates `PurchaseController.purchase(activity, productDetails, basePlanId, offerId)` in favor of the `StoreProduct`-based method above. Existing implementations keep working unchanged — the new method's default implementation routes Google Play purchases to the deprecated one — but purchasing custom store products requires implementing the new method.

## 2.7.23

## Fixes
Expand Down
2 changes: 1 addition & 1 deletion content/docs/android/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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).

<SdkLatestVersion version="2.7.23" repoUrl="https://github.com/superwall/Superwall-Android" />
<SdkLatestVersion version="2.8.0" repoUrl="https://github.com/superwall/Superwall-Android" />
10 changes: 7 additions & 3 deletions content/docs/android/quickstart/install.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ can find the [latest release here](https://github.com/superwall/Superwall-Androi
<CodeGroup>

```gradle build.gradle
implementation "com.superwall.sdk:superwall-android:2.7.23"
implementation "com.superwall.sdk:superwall-android:2.8.0"
```

```kotlin build.gradle.kts
implementation("com.superwall.sdk:superwall-android:2.7.23")
implementation("com.superwall.sdk:superwall-android:2.8.0")
```

```toml libs.version.toml
[libraries]
superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.7.23" }
superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.8.0" }

// And in your build.gradle.kts
dependencies {
Expand All @@ -39,6 +39,10 @@ dependencies {

</CodeGroup>

<Warning>
Starting with `2.8.0`, the SDK requires **`minSdk` 23** (previously 21) because it upgrades the underlying Google Play Billing Library to 9.1.0. If your app's `minSdk` is below 23, raise it before upgrading. Because Billing is resolved to a single version across your app, this also upgrades Billing for any other library that depends on it (RevenueCat, Adapty, Purchasely, etc.) — confirm those providers support Billing 9 before shipping. See the [changelog](/android/changelog) for the full breaking-changes list and a workaround if you need to pin Billing to version 8.
</Warning>
Comment on lines +42 to +44

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the Unity Android dependency guidance

For fresh Unity Android builds, content/docs/unity/quickstart/install.mdx:54-55 still says the package pulls superwall-android:2.+ alongside Billing 8.0.0. That dynamic SDK selector now resolves 2.8.0, whose transitive Billing 9.1.0 dependency wins Gradle conflict resolution, so Unity users actually receive the same Billing upgrade described here while their installation page continues to promise Billing 8 and omits the compatibility warning. Update the Unity dependency list and add the relevant Billing 9 migration guidance there as part of this release sync.

Useful? React with 👍 / 👎.


Make sure to run **Sync Now** to force Android Studio to update.

<Frame>![](/images/installation/gradle-sync-now.png) </Frame>
Expand Down
25 changes: 21 additions & 4 deletions content/docs/android/sdk-reference/PurchaseController.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ Use this interface only if you want complete control over purchase handling, suc
interface PurchaseController {
suspend fun purchase(
activity: Activity,
product: StoreProduct
product: StoreProduct,
basePlanId: String?,
offerId: String?
): PurchaseResult

suspend fun restorePurchases(): RestorationResult
Expand All @@ -31,19 +33,25 @@ interface PurchaseController {
public interface PurchaseController {
CompletableFuture<PurchaseResult> purchase(
Activity activity,
StoreProduct product
StoreProduct product,
String basePlanId,
String offerId
);

CompletableFuture<RestorationResult> restorePurchases();
}
```

<Info>
Starting in `2.8.0`, `purchase()` receives a `StoreProduct` (instead of the Billing Library's `ProductDetails`), which also supports [custom store products](#custom-store-products). For Google Play products, the underlying `ProductDetails` is available via `product.rawStoreProduct`. The default implementation of this method routes Google Play products to the older `purchase(activity, productDetails, basePlanId, offerId)` overload, so existing implementations of that overload keep working unchanged. That older overload is now deprecated; implement the `StoreProduct`-based method above going forward, and implement it directly if you need to support custom store products.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the implementation guides for the new overload

When developers follow the linked implementation guidance, both content/shared/advanced-configuration.mdx:190-195 and the Android section of content/shared/using-revenuecat.mdx:266-271 still implement the deprecated ProductDetails overload. That remains usable for Play products, but, as this callout explains, it cannot receive custom store products, so users following these examples cannot implement the newly documented custom-product flow. Update the shared Android samples to override the StoreProduct method and handle or explicitly reject the custom-product branch.

Useful? React with 👍 / 👎.

</Info>

## Parameters
<TypeTable
type={{
purchase: {
type: "activity: Activity, product: StoreProduct",
description: "Called when user initiates purchasing. Implement your purchase logic here. Activity is needed for Google Play Billing. Returns `PurchaseResult`.",
type: "activity: Activity, product: StoreProduct, basePlanId: String?, offerId: String?",
description: "Called when user initiates purchasing. Implement your purchase logic here. Activity is needed for Google Play Billing. `basePlanId` and `offerId` are optional identifiers for the base plan/offer being purchased. Returns `PurchaseResult`.",
required: true,
},
restorePurchases: {
Expand All @@ -61,6 +69,15 @@ public interface PurchaseController {

When using a PurchaseController, you must also manage [`subscriptionStatus`](/android/sdk-reference/subscriptionStatus) yourself.

## Custom store products

Products configured on a custom store in the Superwall dashboard (e.g. Stripe or your own payment backend) can be attached to paywalls. Their metadata (price, subscription period, trial) is fetched from the Superwall API instead of Google Play, and purchases for them are routed through your `PurchaseController`, bypassing Google Play Billing entirely.

- Check `product.isCustomProduct` in `purchase()` to detect a custom product and fulfill it via your own payment flow.
- On a successful purchase, grant the entitlement yourself by calling `Superwall.instance.setSubscriptionStatus(...)` — the SDK does not do this automatically for custom products.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Separate entitlement fulfillment from status synchronization

For a custom-backend purchase, setSubscriptionStatus(...) only reports the entitlements that the app's purchase system has already granted; it does not fulfill or persist the purchase itself. The existing API reference at content/docs/android/sdk-reference/advanced/setSubscriptionStatus.mdx:10-15 explicitly describes this as keeping Superwall synchronized with the purchase system, but this new instruction—and the equivalent wording in the new changelog entry—tells developers to grant the entitlement by calling it. A developer following that literally can mark the current client active without provisioning the user's account in their backend. Instruct users to grant access in their own billing/backend system first, then call setSubscriptionStatus(...) to mirror the resulting entitlement state into Superwall.

Useful? React with 👍 / 👎.

- `StoreProduct.customTransactionId` is an SDK-generated identifier you can use as the original transaction identifier in your own analytics.
- Requires configuring the SDK with a `PurchaseController`.

## Usage

For implementation examples and detailed guidance, see [Using RevenueCat](/android/guides/using-revenuecat).
2 changes: 1 addition & 1 deletion content/docs/android/sdk-reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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).

<SdkLatestVersion version="2.7.23" repoUrl="https://github.com/superwall/Superwall-Android" />
<SdkLatestVersion version="2.8.0" repoUrl="https://github.com/superwall/Superwall-Android" />
Loading