Enhancements
⚠️ Updates Google Play Billing Library from 8.0.0 to 9.1.0. See the Play Billing Library 9 migration guide 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 — checkproduct.isCustomProductto fulfill them via your own payment flow, and grant their entitlements withSuperwall.instance.setSubscriptionStatus(...)on success. Requires configuring the SDK with aPurchaseController. - Adds a unified
PurchaseController.purchase(activity, product: StoreProduct, basePlanId, offerId)method that handles both Google Play and custom store products. For Play products, the underlyingProductDetailsare available viaproduct.rawStoreProduct. - Custom purchases produce full transaction analytics (
transaction_start/transaction_complete,subscriptionStart/freeTrialStart) with an SDK-generated transaction identifier exposed asStoreProduct.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_inputmessage 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. Whenreroute_back_buttonis enabled in Paywall settings, thePaywallOptions.onBackPressedapp callback keeps first refusal before the press is forwarded. Paywalls built on runtimes that predateback_button_inputwill 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 removesSkuDetailsentirely, so this method can no longer exist. UsesetProductDetailsParamsList(...)withProductDetailsinstead. -
Removes the unused internal
com.superwall.sdk.billing.SWProduct, which wrapped the now-removedSkuDetails. -
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-argenablePendingPurchases()), it will no longer compile once it picks up Billing 9 through this SDK. Migrate those call sites to theProductDetailsAPIs before upgrading; the migration guide 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 theandroid { }block:configurations.all { resolutionStrategy.force("com.android.billingclient:billing:8.3.0") }Or in Groovy (
build.gradle):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 forcom.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.QueryPurchaseHistoryParamsProGuard 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 theStoreProduct-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.