-
Notifications
You must be signed in to change notification settings - Fork 3
feat(android): update for 2.8.0 #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -121,7 +121,7 @@ class PaywallOptions { | |
| }, | ||
| onBackPressed: { | ||
| type: "((PaywallInfo?) -> Boolean)?", | ||
| description: "Callback invoked when back button is pressed (requires `reroute_back_button` enabled in paywall settings). Return `true` to consume the back press, `false` to use SDK default behavior.", | ||
| description: "Callback invoked when back button is pressed (requires `reroute_back_button` enabled in paywall settings). Return `true` to consume the press. Return `false` to forward it to the paywall as `back_button_input`; the paywall navigates back one page when possible or closes through its standard manual-close path.", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an app still presents a paywall built on a runtime that predates Useful? React with 👍 / 👎. |
||
| default: "null", | ||
| }, | ||
| }} | ||
|
|
@@ -150,7 +150,8 @@ val paywallOptions = PaywallOptions().apply { | |
| timeoutAfter = null | ||
| onBackPressed = { paywallInfo -> | ||
| // Custom back button handling | ||
| // Return true to consume the back press, false to use SDK default | ||
| // Return true to consume the back press. Returning false forwards it to | ||
| // the paywall, which navigates back one page or closes itself. | ||
| false | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,31 +19,43 @@ 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 | ||
| } | ||
| ``` | ||
|
|
||
| ```java | ||
| // Java | ||
| public interface PurchaseController { | ||
| CompletableFuture<PurchaseResult> purchase( | ||
| Activity activity, | ||
| StoreProduct product | ||
| // Java uses the callback-based PurchaseControllerJava interface. | ||
| public interface PurchaseControllerJava { | ||
| void purchase( | ||
| ProductDetails productDetails, | ||
| String basePlanId, | ||
| String offerId, | ||
| kotlin.jvm.functions.Function1<? super PurchaseResult, kotlin.Unit> completion | ||
| ); | ||
|
|
||
| void restorePurchases( | ||
| kotlin.jvm.functions.Function2<? super RestorationResult, ? super Throwable, kotlin.Unit> completion | ||
| ); | ||
|
|
||
| CompletableFuture<RestorationResult> restorePurchases(); | ||
| } | ||
| ``` | ||
|
|
||
| <Info> | ||
| Starting in `2.8.0`, Kotlin's `PurchaseController.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. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When developers use this note to migrate a Google Play implementation, Useful? React with 👍 / 👎. |
||
| </Info> | ||
|
|
||
| `PurchaseControllerJava` remains a callback-based API that receives `ProductDetails`. It does not support custom store products. | ||
|
|
||
| ## 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: { | ||
|
|
@@ -56,11 +68,20 @@ public interface PurchaseController { | |
|
|
||
|
|
||
| ## Returns / State | ||
| - `purchase()` returns a `PurchaseResult` (`.Purchased`, `.Failed(Throwable)`, `.Cancelled`, or `.Pending`) | ||
| - `restorePurchases()` returns a `RestorationResult` (`.Restored` or `.Failed(Throwable?)`) | ||
| - `purchase()` returns a `PurchaseResult` (`.Purchased()`, `.Failed(errorMessage: String)`, `.Cancelled()`, or `.Pending()`) | ||
| - `restorePurchases()` returns a `RestorationResult` (`.Restored()` or `.Failed(Throwable?)`) | ||
|
|
||
| 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. | ||
|
|
||
| - Kotlin `PurchaseController` implementations can check `product.isCustomProduct` in `purchase()` to detect a custom product and fulfill it via their own payment flow. `PurchaseControllerJava` does not support custom store products. | ||
| - On a successful purchase, grant the entitlement yourself by calling `Superwall.instance.setSubscriptionStatus(...)` — the SDK does not do this automatically for custom products. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For a custom-backend purchase, 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). | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For fresh Unity Android builds,
content/docs/unity/quickstart/install.mdx:54-55still says the package pullssuperwall-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 👍 / 👎.