6.0.0-rc.1
Warning
v6 is currently in a release-candidate phase — use 6.0.0-rc.1, not 6.0.0. 6.0.0-rc.1 is the official build to integrate against for early integration and testing while v6 stabilizes. Use it to validate your migration and report any issues; the stable 6.0.0 will be announced once the RC cycle completes.
implementation("io.purchasely:core:6.0.0-rc.1")
implementation("io.purchasely:google-play:6.0.0-rc.1")
// implementation("io.purchasely:player:6.0.0-rc.1") // optionalPurchasely Android SDK 6.0.0-rc.1
The first release candidate of the v6 major version. v6 modernizes the presentation API, reworks the action interceptor, makes storeless and observer-first the defaults, and tightens initialization. This is a major release with breaking changes — read the full migration guide before upgrading.
✨ Highlights & New Features
- New
PLYPresentationAPI — a complete builder / preload / display lifecycle with an observablestate: StateFlow<PLYPresentationState>(Idle → Loading → Loaded → Displayed → Dismissed/Error). Preload early, display later, no extra network call. PLYPresentationSession— everydisplay(...)returns a session handle. Fire-and-forget from Java, orawait()it from a coroutine to suspend until dismissal and get aPLYPresentationOutcome(structured concurrency +try/catch).- Granular action interceptor —
interceptAction<PLYPresentationAction.Purchase> { … }replaces the monolithicsetPaywallActionsInterceptor. Type-safe parameters per action, no casting. - Kotlin DSL entrypoint —
Purchasely { context(...); apiKey(...); … }configures and starts in one block, with editor-time Lint checks (PurchaselyMissingContext,PurchaselyMissingApiKey,PurchaselyFullModeWithoutStores). - Storeless integration is now first-class — screens, analytics, campaigns, deeplinks, and user attributes all work with no store configured.
- Automatic deeplink interception — the SDK reads the foreground activity's intent and routes its own URIs. No
handleDeeplink()call required (opt out viaautomaticDeeplinkHandling). - Independent campaign gating — new
allowCampaignsflag decouples campaign display from deeplink handling. synchronize()completion callbacks —synchronize(onSuccess, onError)for Observer mode; the subscriptions cache is refreshed beforeonSuccessfires.- Structured transition dimensions —
PLYTransitionsupports px (dp) and percentage for drawer/popin height and popin width. - Logging — custom loggers now receive all messages regardless of
logLevel; newlogcatEnabledflag controls Logcat independently.
⚠️ Breaking Changes
Initialization & running mode
- Default running mode is now
Observer(wasFull). Add.runningMode(PLYRunningMode.Full)if you want Purchasely to handle/validate purchases. In Observer mode, presentations no longer auto-close after purchase/restore. PLYRunningMode.PaywallObserver→PLYRunningMode.Observer(rename).apiKeyis validated atstart()— null/blank leaves the SDK inert and firesPLYError.Configuration.- Init callback signature simplified —
start { error -> }(dropped the leadingBoolean). Java:Function2<Boolean,PLYError,Unit>→Function1<PLYError,Unit>.
Action interceptor
- Removed
setPaywallActionsInterceptor(),PLYPresentationInfo,PLYPaywallActionHandler/PLYCompletionHandler,PLYPaywallActionListener/PLYProcessActionListener. PLYPresentationActionis now a sealed class (was enum);PLYPresentationActionParametersremoved (params live on each subclass).processAction(false/true)→PLYInterceptResult.SUCCESS/NOT_HANDLED(+ newFAILED).- Kotlin reified
interceptAction<T>requires consumerjvmTarget = 11(or use theClass-based overload).
Presentation API
- All presentation types moved to
io.purchasely.ext.presentation.*(import-only change). PLYPresentationPropertiesremoved — configure via the builder/DSL.Purchasely.presentationView(...)removed →PLYPresentation { … }.preload { … }.PLYPresentation.id→screenId(alsotoMap()key"id"→"screenId").- Suspend
display()extension removed —Loaded.display()is now non-suspend. onClose→onCloseRequested;PLYPresentationClose→PLYPresentationCloseRequested.- Display callbacks now receive a single
PLYPresentationOutcome(carriespurchaseResult,plan,closeReason,error) instead of(result, plan)+ separate error. back()/close()are now onPLYPresentation(Loaded) only.PLYProductViewResultdeprecated →PLYPurchaseResult.
Removed surfaces
- Subscription list & cancellation survey UI fully removed —
subscriptionsFragment(), allPLYSubscription*/cancellation fragments & views, theply/subscriptions&ply/cancellation_surveydeeplinks, and 5 relatedPLYEventsubclasses. Build custom UI fromuserSubscriptions()/userSubscriptionsHistory(). - Purchase history —
purchaseHistory()andisPastSubscriber()removed →userSubscriptionsHistory(). PLYPlanintro*methods removed →offer*equivalents (direct rename).PLYPlanTagsINTRO_*/TRIAL_*removed →OFFER_*.
Behavioral changes
allowDeeplinknow defaults totrue(wasfalse). Set.allowDeeplink(false)to keep v5 deferred behavior. Preview deeplinks (?preview=1) always display immediately.- Storeless errors — purchase/restore now return
PLYError.NoStoreConfigured(wasPLYError.Unknown"No store found"). - User attribute mutators return
Deferred<Boolean>(setUserAttribute,clearUserAttribute,increment/decrementUserAttribute, etc.) — safe to ignore.
🛠 Build Requirements
- Minimum Gradle 9.3.0, Kotlin 2.2.x (K2), Java target 11.