⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Conversation

@ianrumac
Copy link
Collaborator

@ianrumac ianrumac commented Feb 2, 2026

Changes in this pull request

2.7.0

Enhancements

  • Enables paywall post-purchase action execution instead of dismissing
  • Adds retrieving of paywall state to paywall info

Fixes

  • Fixes wrong redemption type being displayed due to integration attributes

Deprecations

  • Deprecated paywallWebviewLoad_timeout - this event was causing confusion due to it's naming, leading to it being deprecated

Fixes

  • Fixes late initialization authorization issue for Stripe checkouts

Checklist

  • All unit tests pass.
  • All UI tests pass.
  • Demo project builds and runs.
  • I added/updated tests or detailed why my change isn't tested.
  • I added an entry to the CHANGELOG.md for any breaking changes, enhancements, or bug fixes.
  • I have run ktlint in the main directory and fixed any issues.
  • I have updated the SDK documentation as well as the online docs.
  • I have reviewed the contributing guide

Greptile Overview

Greptile Summary

This release implements version 2.7.0 with significant enhancements to product selection, purchase flow control, and paywall state management. The changes introduce better support for Google Play Billing's one-time purchase options and provide more control over post-purchase paywall behavior.

Key Changes:

  • Introduced BasePlanType and refactored OfferType sealed classes to support sw-auto, sw-none, and specific ID selection for both base plans and offers
  • Refactored RawStoreProduct with new SelectedOfferDetails sealed class to unify handling of subscription offers and one-time purchase options
  • Added shouldDismiss parameter throughout purchase flow to enable post-purchase actions instead of automatic dismissal
  • Implemented paywall state capture via getState() method that retrieves state from webview before dismissal
  • Fixed product identifier attributes to correctly use fullIdentifier (includes base plan and offer) instead of just productIdentifier
  • Deprecated paywallWebviewLoad_timeout event to reduce confusion
  • Added automatic consumption of in-app purchases after restoration

Architecture Impact:
The product selection logic has been significantly refactored to handle the complexity of Google Play Billing's one-time purchase options (introduced in newer API versions), which can have multiple purchase options with different discount offers. The new sealed class approach provides type safety and clearer logic flow compared to the previous nullable string-based approach.

Confidence Score: 4/5

  • Safe to merge with minor style fix needed for CHANGELOG formatting
  • The changes are well-structured with comprehensive test coverage for the new product ID parsing logic. The refactoring uses type-safe sealed classes which reduces error potential. However, the product selection logic in RawStoreProduct is complex with multiple conditional branches that would benefit from additional integration testing to ensure all edge cases are covered
  • Pay close attention to superwall/src/main/java/com/superwall/sdk/store/abstractions/product/RawStoreProduct.kt due to complex conditional logic in getSelectedOfferDetails()

Important Files Changed

Filename Overview
superwall/src/main/java/com/superwall/sdk/store/abstractions/product/RawStoreProduct.kt Refactored product selection logic to support one-time purchase options with sealed class SelectedOfferDetails; added BasePlanType handling and sw-none offer support
superwall/src/main/java/com/superwall/sdk/billing/DecomposedProductIds.kt Added BasePlanType sealed class to replace raw string handling; added sw-none offer type support for explicitly selecting no offer
superwall/src/main/java/com/superwall/sdk/store/abstractions/product/StoreProduct.kt Added BasePlanType and refactored OfferType with None option; both sealed classes have factory methods and helper properties
superwall/src/main/java/com/superwall/sdk/paywall/view/webview/messaging/PaywallMessageHandler.kt Added shouldDismiss parameter to purchase flow; added getState() method to retrieve paywall state from webview; added TransactionComplete event handling
superwall/src/main/java/com/superwall/sdk/store/AutomaticPurchaseController.kt Updated to use BasePlanType and OfferType; improved offer token handling for one-time purchases with purchase options; added automatic consumption of in-app purchases
superwall/src/main/java/com/superwall/sdk/store/abstractions/product/StoreProductType.kt Fixed identifier attribute to use fullIdentifier instead of productIdentifier; added separate productIdentifier attribute

Sequence Diagram

sequenceDiagram
    participant User
    participant PaywallView
    participant PaywallMessageHandler
    participant WebView
    participant TransactionManager
    participant AutomaticPurchaseController
    participant BillingClient

    Note over User,BillingClient: Purchase Flow with shouldDismiss Parameter

    User->>PaywallView: Click Purchase Button
    PaywallView->>WebView: User initiates purchase
    WebView->>PaywallMessageHandler: PaywallMessage.Purchase(productId, shouldDismiss)
    PaywallMessageHandler->>PaywallMessageHandler: purchaseProduct(productId, shouldDismiss)
    PaywallMessageHandler->>PaywallView: PaywallWebEvent.InitiatePurchase(productId, shouldDismiss)
    
    PaywallView->>TransactionManager: purchase(product, shouldDismiss)
    TransactionManager->>AutomaticPurchaseController: purchase(productId)
    
    Note over AutomaticPurchaseController,BillingClient: Product Selection Logic
    AutomaticPurchaseController->>AutomaticPurchaseController: Parse DecomposedProductIds
    AutomaticPurchaseController->>AutomaticPurchaseController: Create RawStoreProduct(basePlanType, offerType)
    AutomaticPurchaseController->>AutomaticPurchaseController: Get selectedOffer (Subscription/OneTime)
    AutomaticPurchaseController->>AutomaticPurchaseController: Extract offerToken if needed
    
    AutomaticPurchaseController->>BillingClient: launchBillingFlow(offerToken)
    BillingClient-->>AutomaticPurchaseController: Purchase result
    AutomaticPurchaseController-->>TransactionManager: PurchaseResult
    
    alt Purchase Successful
        TransactionManager->>PaywallMessageHandler: TransactionComplete event
        alt shouldDismiss == true
            TransactionManager->>PaywallView: Dismiss paywall
        else shouldDismiss == false
            Note over PaywallView: Paywall remains open for post-purchase actions
        end
    end

    Note over PaywallView,WebView: Paywall State Capture on Dismiss

    User->>PaywallView: Close/Dismiss Paywall
    PaywallView->>PaywallMessageHandler: getState()
    PaywallMessageHandler->>WebView: Evaluate "window.app.getAllState()"
    WebView-->>PaywallMessageHandler: State JSON
    PaywallMessageHandler->>PaywallMessageHandler: Parse and convert state
    PaywallMessageHandler-->>PaywallView: Map<String, Any>
    PaywallView->>PaywallView: SetPaywallState(state)
    PaywallView->>PaywallView: Dismiss with state captured
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

6 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Add custom callbacks message and interface
@ianrumac ianrumac merged commit 74148f3 into main Feb 3, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant