diff --git a/app/src/main/java/com/qonversion/android/app/HomeFragment.kt b/app/src/main/java/com/qonversion/android/app/HomeFragment.kt
index 373e45a4..8f71fa40 100644
--- a/app/src/main/java/com/qonversion/android/app/HomeFragment.kt
+++ b/app/src/main/java/com/qonversion/android/app/HomeFragment.kt
@@ -23,6 +23,7 @@ import com.qonversion.android.sdk.automations.dto.QActionResultType
import com.qonversion.android.sdk.automations.dto.QScreenPresentationConfig
import com.qonversion.android.sdk.automations.dto.QScreenPresentationStyle
import com.qonversion.android.sdk.dto.QPurchaseModel
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.entitlements.QEntitlement
import com.qonversion.android.sdk.dto.QonversionError
import com.qonversion.android.sdk.dto.products.QProduct
@@ -189,6 +190,7 @@ class HomeFragment : Fragment() {
showError(requireContext(), error, TAG)
}
})
+
}
private fun showLoading(isLoading: Boolean) {
diff --git a/build.gradle b/build.gradle
index 8168fcee..ebc71c84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
buildscript {
ext {
release = [
- versionName: "8.0.2",
+ versionName: "8.1.0",
versionCode: 1
]
}
diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml
index 53d16f42..4c50fef9 100644
--- a/config/detekt/baseline.xml
+++ b/config/detekt/baseline.xml
@@ -30,11 +30,10 @@
FinalNewline:com.qonversion.android.sdk.internal.storage.util.kt:1
FinalNewline:com.qonversion.android.sdk.utils.kt:1
LargeClass:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider
- LongParameterList:IBillingClientWrapper.kt$IBillingClientWrapper$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean, updatePurchaseInfo: UpdatePurchaseInfo?, onFailed: (error: BillingError) -> Unit )
+ LongParameterList:IBillingClientWrapper.kt$IBillingClientWrapper$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean? = true, updatePurchaseInfo: UpdatePurchaseInfo?, onFailed: (error: BillingError) -> Unit )
LongParameterList:ManagersModule.kt$ManagersModule$( appContext: Application, repository: QRepository, propertiesStorage: UserPropertiesStorage, incrementalDelayCalculator: IncrementalDelayCalculator, appStateProvider: AppStateProvider, logger: Logger )
LongParameterList:ManagersModule.kt$ManagersModule$( repository: QRepository, preferences: SharedPreferences, eventMapper: AutomationsEventMapper, appContext: Application, activityProvider: ActivityProvider, appStateProvider: AppStateProvider )
- LongParameterList:PurchaseModelInternalEnriched.kt$PurchaseModelInternalEnriched$( productId: String, val product: QProduct, offerId: String?, applyOffer: Boolean, oldProductId: String?, val oldProduct: QProduct?, updatePolicy: QPurchaseUpdatePolicy?, )
- LongParameterList:QonversionBillingService.kt$QonversionBillingService$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean, oldProduct: QProduct, updatePolicy: QPurchaseUpdatePolicy? )
+ LongParameterList:QonversionBillingService.kt$QonversionBillingService$( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean?, oldProduct: QProduct, updatePolicy: QPurchaseUpdatePolicy? )
LongParameterList:QonversionBillingService.kt$QonversionBillingService$( private val mainHandler: Handler, private val purchasesListener: PurchasesListener, private val logger: Logger, private val isAnalyticsMode: Boolean, private val billingClientHolder: BillingClientHolder, private val billingClientWrapper: BillingClientWrapper, private val legacyBillingClientWrapper: LegacyBillingClientWrapper )
LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, sharedPreferences: SharedPreferences, delayCalculator: IncrementalDelayCalculator )
LongParameterList:RepositoryModule.kt$RepositoryModule$( retrofit: Retrofit, environmentProvider: EnvironmentProvider, config: InternalConfig, logger: Logger, apiErrorMapper: ApiErrorMapper, sharedPreferences: SharedPreferences, delayCalculator: IncrementalDelayCalculator, rateLimiter: RateLimiter )
@@ -90,6 +89,8 @@
MaxLineLength:AutomationsEventMapperTest.kt$AutomationsEventMapperTest.GetEventFromRemoteMessage$"{\"name\": \"subscription_started\", \"happened\": $timeInSec}" to AutomationsEventType.SubscriptionStarted
MaxLineLength:AutomationsEventMapperTest.kt$AutomationsEventMapperTest.GetEventFromRemoteMessage$"{\"name\": \"subscription_upgraded\", \"happened\": $timeInSec}" to AutomationsEventType.SubscriptionUpgraded
MaxLineLength:AutomationsEventMapperTest.kt$AutomationsEventMapperTest.GetEventFromRemoteMessage$"{\"name\": \"trial_billing_retry_entered\", \"happened\": $timeInSec}" to AutomationsEventType.TrialBillingRetry
+ MaxLineLength:GooglePurchaseConverter.kt$GooglePurchaseConverter$override
+ MaxLineLength:LaunchResultCacheWrapperTest.kt$LaunchResultCacheWrapperTest$cacheWrapper = LaunchResultCacheWrapper(mockMoshi, mockPrefsCache, mockCacheConfigProvider, mockQFallbacksService)
MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$"lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"
MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$purchaseToken = "lgeigljfpmeoddkcebkcepjc.AO-J1Oy305qZj99jXTPEVBN8UZGoYAtjDLj4uTjRQvUFaG0vie-nr6VBlN0qnNDMU8eJR-sI7o3CwQyMOEHKl8eJsoQ86KSFzxKBR07PSpHLI_o7agXhNKY"
MaxLineLength:OutagerIntegrationTest.kt$OutagerIntegrationTest$val token = "dt70kovLQdKymNnhIY6I94:APA91bGfg6m108VFio2ZdgLR6U0B2PtqAn0hIPVU7M4jKklkMxqDUrjoThpX_K60M7CfH8IVZqtku31ei2hmjdJZDfm-bdAl7uxLDWFU8yVcA6-3wBMn3nsYmUrhYWom-qgGC7yIUYzR"
@@ -101,12 +102,18 @@
MaxLineLength:QAutomationsManager.kt$QAutomationsManager$"To override default animation, please, provide an activity context to AutomationsDelegate.contextForScreenIntent"
MaxLineLength:QAutomationsManager.kt$QAutomationsManager$getScreenTransactionAnimations(screenPresentationConfig.presentationStyle)
MaxLineLength:QEntitlementsUpdateListener.kt$QEntitlementsUpdateListener$*
+ MaxLineLength:QProduct.kt$QProduct$@Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOffer(offer).build()"))
+ MaxLineLength:QProduct.kt$QProduct$@Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOfferId(offerId).build()"))
+ MaxLineLength:QProduct.kt$QProduct$@Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOldProduct(TODO(\"pass old product here\")).build()"))
+ MaxLineLength:QProductCenterManager.kt$QProductCenterManager$val oldProduct: QProduct? = purchaseModel.options?.oldProduct ?: getProductForPurchase(purchaseModel.oldProductId, products)
MaxLineLength:QProductCenterManagerTest.kt$QProductCenterManagerTest${ Assert.assertEquals("Wrong installDate value", installDate.milliSecondsToSeconds(), installDateSlot.captured) }
MaxLineLength:QProductCenterManagerTest.kt$QProductCenterManagerTest${ Assert.assertEquals("Wrong purchaseToken value", purchaseToken, entityPurchaseSlot.captured.purchaseToken) }
MaxLineLength:QProductStoreDetails.kt$QProductStoreDetails$basePlanSubscriptionOfferDetails?.basePlan?.recurrenceMode == QProductPricingPhase.RecurrenceMode.NonRecurring
MaxLineLength:QRemoteConfigManager.kt$QRemoteConfigManager.<no name provided>$val remoteConfigs = baseRemoteConfigList.remoteConfigs.filter { contextKeys.contains(it.source.contextKey) }.toMutableList()
MaxLineLength:QUserPropertiesManagerTest.kt$QUserPropertiesManagerTest$fun
MaxLineLength:Qonversion.kt$Qonversion$*
+ MaxLineLength:Qonversion.kt$Qonversion$@Deprecated("Use the new purchase() method", replaceWith = ReplaceWith("purchase(context, TODO(\"pass product here\"), callback)"))
+ MaxLineLength:Qonversion.kt$Qonversion$@Deprecated("Use the new updatePurchase() method", replaceWith = ReplaceWith("updatePurchase(context, TODO(\"pass product here\"), TODO(\"pass purchase options here\"), callback)"))
MaxLineLength:QonversionBillingService.kt$QonversionBillingService$"updatePurchase() -> Purchase was found successfully for store product: ${purchaseHistoryRecord.productId}"
MaxLineLength:QonversionBillingService.kt$QonversionBillingService$logger.debug("queryPurchaseHistoryAsync() -> purchase history for $productType is retrieved ${record.getDescription()}")
MaxLineLength:QonversionConfig.kt$QonversionConfig.Builder$*
@@ -126,6 +133,8 @@
MaxLineLength:util.kt$Util.Companion$"\"offerings\":[{\"id\":\"main\",\"tag\":1,\"products\":[{\"id\":\"in_app\",\"store_id\":\"qonversion_inapp_consumable\",\"type\":2},{\"id\":\"main\",\"store_id\":\"qonversion_subs_weekly\",\"type\":0,\"duration\":0}]"
MaxLineLength:util.kt$Util.Companion$"\"permissions\":[{\"id\":\"standart\",\"associated_product\":\"in_app\",\"renew_state\":-1,\"started_timestamp\":1612880300,\"source\":\"playstore\",\"active\":1},{\"id\":\"Test Permission\",\"associated_product\":\"in_app\",\"renew_state\":-1,\"started_timestamp\":1612880300,\"source\":\"appstore\",\"active\":1}],\"user_products\":[{\"id\":\"in_app\",\"store_id\":\"qonversion_inapp_consumable\",\"type\":2}],"
MaxLineLength:utils.kt$"ProductId: ${this.productId}; PurchaseTime: ${this.purchaseTime.convertLongToTime()}; PurchaseToken: ${this.purchaseToken}"
+ MaximumLineLength:com.qonversion.android.sdk.Qonversion.kt:131
+ MaximumLineLength:com.qonversion.android.sdk.Qonversion.kt:146
MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:105
MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:106
MaximumLineLength:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:107
@@ -140,13 +149,17 @@
MaximumLineLength:com.qonversion.android.sdk.automations.internal.QAutomationsManager.kt:142
MaximumLineLength:com.qonversion.android.sdk.automations.mvp.ScreenPresenterTest.kt:159
MaximumLineLength:com.qonversion.android.sdk.dto.QonversionError.kt:46
+ MaximumLineLength:com.qonversion.android.sdk.dto.products.QProduct.kt:109
+ MaximumLineLength:com.qonversion.android.sdk.dto.products.QProduct.kt:120
+ MaximumLineLength:com.qonversion.android.sdk.dto.products.QProduct.kt:139
MaximumLineLength:com.qonversion.android.sdk.dto.products.QProductStoreDetails.kt:130
MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:213
MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:370
MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:429
MaximumLineLength:com.qonversion.android.sdk.internal.OutagerIntegrationTest.kt:90
- MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:147
- MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:148
+ MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManager.kt:332
+ MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:152
+ MaximumLineLength:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:153
MaximumLineLength:com.qonversion.android.sdk.internal.QRemoteConfigManager.kt:225
MaximumLineLength:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:175
MaximumLineLength:com.qonversion.android.sdk.internal.QonversionRepositoryIntegrationTest.kt:286
@@ -159,11 +172,13 @@
MaximumLineLength:com.qonversion.android.sdk.internal.billing.QonversionBillingService.kt:253
MaximumLineLength:com.qonversion.android.sdk.internal.billing.QonversionBillingService.kt:371
MaximumLineLength:com.qonversion.android.sdk.internal.billing.utils.kt:22
+ MaximumLineLength:com.qonversion.android.sdk.internal.converter.GooglePurchaseConverter.kt:17
MaximumLineLength:com.qonversion.android.sdk.internal.errors.kt:33
- MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:166
- MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:188
- MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:21
- MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:72
+ MaximumLineLength:com.qonversion.android.sdk.internal.storage.LaunchResultCacheWrapperTest.kt:29
+ MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:158
+ MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:167
+ MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:20
+ MaximumLineLength:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:67
MaximumLineLength:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:219
MaximumLineLength:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:220
MaximumLineLength:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:221
@@ -193,6 +208,7 @@
NoConsecutiveBlankLines:com.qonversion.android.sdk.automations.internal.QAutomationsManagerTest.kt:396
NoConsecutiveBlankLines:com.qonversion.android.sdk.internal.QAttributionManagerTest.kt:141
NoConsecutiveBlankLines:com.qonversion.android.sdk.internal.requests.ProviderDataRequestTest.kt:18
+ NoUnusedImports:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:4
NoUnusedImports:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:5
NoWildcardImports:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:12
NoWildcardImports:com.qonversion.android.sdk.automations.internal.AutomationsEventMapperTest.kt:6
@@ -209,8 +225,8 @@
NoWildcardImports:com.qonversion.android.sdk.internal.QHandledPurchasesCacheTest.kt:4
NoWildcardImports:com.qonversion.android.sdk.internal.QIdentityManagerTest.kt:7
NoWildcardImports:com.qonversion.android.sdk.internal.QIdentityManagerTest.kt:9
- NoWildcardImports:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:21
- NoWildcardImports:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:29
+ NoWildcardImports:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:23
+ NoWildcardImports:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:31
NoWildcardImports:com.qonversion.android.sdk.internal.QProductCenterManagerTest.kt:9
NoWildcardImports:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:18
NoWildcardImports:com.qonversion.android.sdk.internal.QUserPropertiesManagerTest.kt:19
@@ -218,13 +234,13 @@
NoWildcardImports:com.qonversion.android.sdk.internal.billing.QonversionBillingService.kt:5
NoWildcardImports:com.qonversion.android.sdk.internal.services.QUserInfoServiceTest.kt:11
NoWildcardImports:com.qonversion.android.sdk.internal.services.QUserInfoServiceTest.kt:5
- NoWildcardImports:com.qonversion.android.sdk.internal.storage.LaunchResultCacheWrapperTest.kt:7
+ NoWildcardImports:com.qonversion.android.sdk.internal.storage.LaunchResultCacheWrapperTest.kt:8
NoWildcardImports:com.qonversion.android.sdk.internal.storage.PurchasesCacheTest.kt:8
NoWildcardImports:com.qonversion.android.sdk.internal.storage.SharedPreferencesCacheTest.kt:5
NoWildcardImports:com.qonversion.android.sdk.internal.storage.util.kt:24
NoWildcardImports:com.qonversion.android.sdk.utils.kt:4
ReturnCount:AutomationsEventMapper.kt$AutomationsEventMapper$fun getEventFromRemoteMessage(messageData: Map<String, String>): AutomationsEvent?
- ReturnCount:BillingClientWrapper.kt$BillingClientWrapper$override fun makePurchase( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean, updatePurchaseInfo: UpdatePurchaseInfo?, onFailed: (error: BillingError) -> Unit )
+ ReturnCount:BillingClientWrapper.kt$BillingClientWrapper$override fun makePurchase( activity: Activity, product: QProduct, offerId: String?, applyOffer: Boolean?, updatePurchaseInfo: UpdatePurchaseInfo?, onFailed: (error: BillingError) -> Unit )
ReturnCount:ExceptionHandler.kt$ExceptionHandler$private fun isQonversionException(exception: Throwable): Boolean
ReturnCount:QExceptionManager.kt$QExceptionManager$private fun getContentOfCrashReport(filename: String): CrashRequest.ExceptionInfo?
ReturnCount:QProductCenterManager.kt$QProductCenterManager$@Synchronized private fun executeProductsBlocks(loadStoreProductsError: QonversionError? = null)
@@ -269,7 +285,6 @@
TooManyFunctions:Cache.kt$Cache
TooManyFunctions:DefaultRepository.kt$DefaultRepository : QRepository
TooManyFunctions:LaunchResultCacheWrapper.kt$LaunchResultCacheWrapper
- TooManyFunctions:LegacyBillingClientWrapper.kt$LegacyBillingClientWrapper : BillingClientWrapperBaseIBillingClientWrapper
TooManyFunctions:QAutomationsManager.kt$QAutomationsManager
TooManyFunctions:QProductCenterManager.kt$QProductCenterManager : PurchasesListenerUserStateProvider
TooManyFunctions:QRemoteConfigManager.kt$QRemoteConfigManager
diff --git a/fastlane/report.xml b/fastlane/report.xml
index 2d8c36f5..1814b4fe 100644
--- a/fastlane/report.xml
+++ b/fastlane/report.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/Qonversion.kt b/sdk/src/main/java/com/qonversion/android/sdk/Qonversion.kt
index 1d7ca44b..7389a7dd 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/Qonversion.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/Qonversion.kt
@@ -4,7 +4,9 @@ import android.app.Activity
import android.util.Log
import com.qonversion.android.sdk.dto.QAttributionProvider
import com.qonversion.android.sdk.dto.QPurchaseModel
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.QPurchaseUpdateModel
+import com.qonversion.android.sdk.dto.products.QProduct
import com.qonversion.android.sdk.dto.properties.QUserPropertyKey
import com.qonversion.android.sdk.internal.InternalConfig
import com.qonversion.android.sdk.internal.QonversionInternal
@@ -75,6 +77,50 @@ interface Qonversion {
*/
fun syncHistoricalData()
+ /**
+ * Make a purchase and validate it through server-to-server using Qonversion's Backend
+ * @param context current activity context
+ * @param product product for purchase
+ * @param options necessary information for purchase
+ * @param callback - callback that will be called when response is received
+ * @see [Making Purchases](https://documentation.qonversion.io/docs/making-purchases)
+ */
+ fun purchase(
+ context: Activity,
+ product: QProduct,
+ options: QPurchaseOptions,
+ callback: QonversionEntitlementsCallback
+ )
+
+ /**
+ * Make a purchase and validate it through server-to-server using Qonversion's Backend
+ * @param context current activity context
+ * @param product product for purchase
+ * @param callback - callback that will be called when response is received
+ * @see [Making Purchases](https://documentation.qonversion.io/docs/making-purchases)
+ */
+ fun purchase(
+ context: Activity,
+ product: QProduct,
+ callback: QonversionEntitlementsCallback
+ )
+
+ /**
+ * Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend
+ * @param context current activity context
+ * @param product product for purchase
+ * @param options necessary information for purchase
+ * @param callback - callback that will be called when response is received
+ * @see [Update policy](https://developer.android.com/google/play/billing/subscriptions#replacement-modes)
+ * @see [Making Purchases](https://documentation.qonversion.io/docs/making-purchases)
+ */
+ fun updatePurchase(
+ context: Activity,
+ product: QProduct,
+ options: QPurchaseOptions,
+ callback: QonversionEntitlementsCallback
+ )
+
/**
* Make a purchase and validate it through server-to-server using Qonversion's Backend
* @param context current activity context
@@ -82,7 +128,12 @@ interface Qonversion {
* @param callback - callback that will be called when response is received
* @see [Making Purchases](https://documentation.qonversion.io/docs/making-purchases)
*/
- fun purchase(context: Activity, purchaseModel: QPurchaseModel, callback: QonversionEntitlementsCallback)
+ @Deprecated("Use the new purchase() method", replaceWith = ReplaceWith("purchase(context, TODO(\"pass product here\"), callback)"))
+ fun purchase(
+ context: Activity,
+ purchaseModel: QPurchaseModel,
+ callback: QonversionEntitlementsCallback
+ )
/**
* Update (upgrade/downgrade) subscription and validate it through server-to-server using Qonversion's Backend
@@ -92,6 +143,7 @@ interface Qonversion {
* @see [Update policy](https://developer.android.com/google/play/billing/subscriptions#replacement-modes)
* @see [Making Purchases](https://documentation.qonversion.io/docs/making-purchases)
*/
+ @Deprecated("Use the new updatePurchase() method", replaceWith = ReplaceWith("updatePurchase(context, TODO(\"pass product here\"), TODO(\"pass purchase options here\"), callback)"))
fun updatePurchase(
context: Activity,
purchaseUpdateModel: QPurchaseUpdateModel,
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/dto/QPurchaseOptions.kt b/sdk/src/main/java/com/qonversion/android/sdk/dto/QPurchaseOptions.kt
new file mode 100644
index 00000000..efcfed96
--- /dev/null
+++ b/sdk/src/main/java/com/qonversion/android/sdk/dto/QPurchaseOptions.kt
@@ -0,0 +1,102 @@
+package com.qonversion.android.sdk.dto
+
+import com.qonversion.android.sdk.QonversionConfig.Builder
+import com.qonversion.android.sdk.dto.products.QProduct
+import com.qonversion.android.sdk.dto.products.QProductOfferDetails
+import com.qonversion.android.sdk.dto.products.QProductStoreDetails
+import com.squareup.moshi.JsonClass
+
+/**
+ * Purchase options that may be used to modify purchase process.
+ * To create an instance, use the nested [Builder] class.
+ */
+@JsonClass(generateAdapter = true)
+class QPurchaseOptions internal constructor (
+ internal val contextKeys: List? = null,
+ internal val offerId: String? = null,
+ internal val applyOffer: Boolean = true,
+ internal val oldProduct: QProduct? = null,
+ internal val updatePolicy: QPurchaseUpdatePolicy? = null
+) {
+ /**
+ * The builder of QPurchaseOptions instance.
+ *
+ * This class contains a variety of methods to customize the purchase behavior.
+ * You can call them sequentially and call [build] finally to get the [QPurchaseOptions] instance.
+ */
+ class Builder {
+ private var contextKeys: List? = null
+ private var offerId: String? = null
+ private var applyOffer: Boolean = true
+ private var oldProduct: QProduct? = null
+ private var updatePolicy: QPurchaseUpdatePolicy? = null
+
+ /**
+ * Set the context keys associated with a purchase.
+ *
+ * @param contextKeys context keys for the purchase.
+ * @return builder instance for chain calls.
+ */
+ fun setContextKeys(contextKeys: List): QPurchaseOptions.Builder = apply {
+ this.contextKeys = contextKeys
+ }
+
+ /**
+ * Set context keys associated with a purchase.
+ *
+ * @param oldProduct Qonversion product from which the upgrade/downgrade
+ * will be initialized.
+ * @return builder instance for chain calls.
+ */
+ fun setOldProduct(oldProduct: QProduct): QPurchaseOptions.Builder = apply {
+ this.oldProduct = oldProduct
+ }
+
+ /**
+ * Set the update policy for the purchase.
+ * If the [updatePolicy] is not provided, then default one
+ * will be selected - [QPurchaseUpdatePolicy.WithTimeProration].
+ * @param updatePolicy update policy for the purchase.
+ * @return builder instance for chain calls.
+ */
+ fun setUpdatePolicy(updatePolicy: QPurchaseUpdatePolicy): QPurchaseOptions.Builder = apply {
+ this.updatePolicy = updatePolicy
+ }
+
+ /**
+ * Set offer for the purchase.
+ * @param offer concrete offer which you'd like to purchase.
+ * @return builder instance for chain calls.
+ */
+ fun setOffer(offer: QProductOfferDetails): QPurchaseOptions.Builder = apply {
+ this.offerId = offer.offerId
+ }
+
+ /**
+ * Set the offer Id to the purchase.
+ * If [offerId] is not specified, then the default offer will be applied. To know how we choose
+ * the default offer, see [QProductStoreDetails.defaultSubscriptionOfferDetails].
+ * @param offerId concrete offer Id which you'd like to purchase.
+ * @return builder instance for chain calls.
+ */
+ fun setOfferId(offerId: String): QPurchaseOptions.Builder = apply {
+ this.offerId = offerId
+ }
+
+ /**
+ * Call this function to remove any intro/trial offer from the purchase (use only a bare base plan).
+ * @return builder instance for chain calls.
+ */
+ fun removeOffer(): QPurchaseOptions.Builder = apply {
+ this.applyOffer = false
+ }
+
+ /**
+ * Generate [QPurchaseOptions] instance with all the provided options.
+ * @return the complete [QPurchaseOptions] instance.
+ */
+ fun build(): QPurchaseOptions {
+ return QPurchaseOptions(contextKeys, offerId, applyOffer, oldProduct, updatePolicy)
+ }
+ }
+}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/dto/products/QProduct.kt b/sdk/src/main/java/com/qonversion/android/sdk/dto/products/QProduct.kt
index 6efa3e79..2f332e85 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/dto/products/QProduct.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/dto/products/QProduct.kt
@@ -106,6 +106,7 @@ data class QProduct(
* To know how we choose the default offer, see [QProductStoreDetails.defaultSubscriptionOfferDetails].
* @return purchase model to pass to the purchase method.
*/
+ @Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOfferId(offerId).build()"))
@JvmOverloads
fun toPurchaseModel(offerId: String? = null): QPurchaseModel {
return QPurchaseModel(qonversionID, offerId)
@@ -116,6 +117,7 @@ data class QProduct(
* @param offer concrete offer which you'd like to purchase.
* @return purchase model to pass to the purchase method.
*/
+ @Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOffer(offer).build()"))
fun toPurchaseModel(offer: QProductOfferDetails?): QPurchaseModel {
val model = toPurchaseModel(offer?.offerId)
// Remove offer for the case when provided offer details are for bare base plan.
@@ -134,6 +136,7 @@ data class QProduct(
* @param updatePolicy purchase update policy.
* @return purchase model to pass to the update purchase method.
*/
+ @Deprecated("Use new QPurchaseOptions object instead", replaceWith = ReplaceWith("QPurchaseOptions.Builder().setOldProduct(TODO(\"pass old product here\")).build()"))
@JvmOverloads
fun toPurchaseUpdateModel(
oldProductId: String,
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/QProductCenterManager.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/QProductCenterManager.kt
index 4bce9ad3..30b3f08f 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/QProductCenterManager.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/QProductCenterManager.kt
@@ -5,6 +5,7 @@ import android.app.Application
import android.content.pm.PackageManager
import android.os.Build
import com.android.billingclient.api.Purchase
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.entitlements.QEntitlement
import com.qonversion.android.sdk.listeners.QonversionEligibilityCallback
import com.qonversion.android.sdk.dto.QonversionError
@@ -94,6 +95,10 @@ internal class QProductCenterManager internal constructor(
private var converter: PurchaseConverter = GooglePurchaseConverter()
+ private val processingPurchaseOptions: MutableMap by lazy {
+ purchasesCache.loadProcessingPurchasesOptions().toMutableMap()
+ }
+
@Volatile
lateinit var billingService: BillingService
@Synchronized set
@@ -324,7 +329,7 @@ internal class QProductCenterManager internal constructor(
callback.onError(QonversionError(QonversionErrorCode.ProductNotFound))
return
}
- val oldProduct: QProduct? = getProductForPurchase(purchaseModel.oldProductId, products)
+ val oldProduct: QProduct? = purchaseModel.options?.oldProduct ?: getProductForPurchase(purchaseModel.oldProductId, products)
val purchaseModelEnriched = purchaseModel.enrich(product, oldProduct)
processPurchase(context, purchaseModelEnriched, callback)
}
@@ -349,9 +354,28 @@ internal class QProductCenterManager internal constructor(
}
purchasingCallbacks[purchaseModel.product.storeID] = callback
+
+ updatePurchaseOptions(purchaseModel.options, purchaseModel.product.storeID)
+
billingService.purchase(context, purchaseModel)
}
+ private fun updatePurchaseOptions(options: QPurchaseOptions?, storeProductId: String?) {
+ storeProductId?.let { productId ->
+ options?.let {
+ processingPurchaseOptions[productId] = it
+ } ?: run {
+ processingPurchaseOptions.remove(productId)
+ }
+
+ purchasesCache.saveProcessingPurchasesOptions(processingPurchaseOptions)
+ }
+ }
+
+ private fun removePurchaseOptions(productId: String?) {
+ updatePurchaseOptions(null, productId)
+ }
+
private fun getProductForPurchase(
productId: String?,
products: Map
@@ -651,7 +675,7 @@ internal class QProductCenterManager internal constructor(
processingPurchases = completedPurchases
- val purchasesInfo = converter.convertPurchases(completedPurchases)
+ val purchasesInfo = converter.convertPurchases(completedPurchases, processingPurchaseOptions)
val handledPurchasesCallback =
getWrappedPurchasesCallback(completedPurchases, callback)
@@ -673,6 +697,9 @@ internal class QProductCenterManager internal constructor(
return object : QonversionLaunchCallback {
override fun onSuccess(launchResult: QLaunchResult) {
handledPurchasesCache.saveHandledPurchases(trackingPurchases)
+ trackingPurchases.forEach {
+ removePurchaseOptions(it.productId)
+ }
outerCallback?.onSuccess(launchResult)
}
@@ -959,7 +986,8 @@ internal class QProductCenterManager internal constructor(
val product: QProduct? = launchResultCache.getActualProducts()?.values?.find {
it.storeID == purchase.productId
}
- val purchaseInfo = converter.convertPurchase(purchase)
+ val currentPurchaseOptions = processingPurchaseOptions[purchase.productId]
+ val purchaseInfo = converter.convertPurchase(purchase, currentPurchaseOptions)
repository.purchase(
installDate,
purchaseInfo,
@@ -970,6 +998,7 @@ internal class QProductCenterManager internal constructor(
val entitlements = launchResult.permissions.toEntitlementsMap()
+ removePurchaseOptions(product?.storeID)
purchaseCallback?.onSuccess(entitlements) ?: run {
internalConfig.entitlementsUpdateListener?.onEntitlementsUpdated(
entitlements
@@ -981,6 +1010,8 @@ internal class QProductCenterManager internal constructor(
override fun onError(error: QonversionError) {
storeFailedPurchaseIfNecessary(purchase, purchaseInfo, product)
+ removePurchaseOptions(product?.storeID)
+
if (shouldCalculatePermissionsLocally(error)) {
calculatePurchasePermissionsLocally(
purchase,
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
index 15be6732..f0b6b97d 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/QonversionInternal.kt
@@ -9,6 +9,7 @@ import com.qonversion.android.sdk.Qonversion
import com.qonversion.android.sdk.automations.internal.QAutomationsManager
import com.qonversion.android.sdk.dto.QAttributionProvider
import com.qonversion.android.sdk.dto.QPurchaseModel
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.QPurchaseUpdateModel
import com.qonversion.android.sdk.dto.entitlements.QEntitlement
import com.qonversion.android.sdk.dto.QRemoteConfig
@@ -170,6 +171,44 @@ internal class QonversionInternal(
)
}
+ override fun purchase(
+ context: Activity,
+ product: QProduct,
+ options: QPurchaseOptions,
+ callback: QonversionEntitlementsCallback
+ ) {
+ productCenterManager.purchaseProduct(
+ context,
+ PurchaseModelInternal(product, options),
+ mainEntitlementsCallback(callback)
+ )
+ }
+
+ override fun purchase(
+ context: Activity,
+ product: QProduct,
+ callback: QonversionEntitlementsCallback
+ ) {
+ productCenterManager.purchaseProduct(
+ context,
+ PurchaseModelInternal(product),
+ mainEntitlementsCallback(callback)
+ )
+ }
+
+ override fun updatePurchase(
+ context: Activity,
+ product: QProduct,
+ options: QPurchaseOptions,
+ callback: QonversionEntitlementsCallback
+ ) {
+ productCenterManager.purchaseProduct(
+ context,
+ PurchaseModelInternal(product, options),
+ mainEntitlementsCallback(callback)
+ )
+ }
+
override fun updatePurchase(
context: Activity,
purchaseUpdateModel: QPurchaseUpdateModel,
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/BillingClientWrapper.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/BillingClientWrapper.kt
index 14b58231..396e7888 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/BillingClientWrapper.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/BillingClientWrapper.kt
@@ -54,7 +54,7 @@ internal class BillingClientWrapper(
activity: Activity,
product: QProduct,
offerId: String?,
- applyOffer: Boolean,
+ applyOffer: Boolean?,
updatePurchaseInfo: UpdatePurchaseInfo?,
onFailed: (error: BillingError) -> Unit
) {
@@ -76,7 +76,7 @@ internal class BillingClientWrapper(
val offerDetails: QProductOfferDetails? = when {
storeDetails.isInApp -> null
- !applyOffer -> {
+ applyOffer == false -> {
storeDetails.basePlanSubscriptionOfferDetails ?: run {
fireError("Failed to find base plan offer for Qonversion product ${product.qonversionID}")
return
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/IBillingClientWrapper.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/IBillingClientWrapper.kt
index 4bae185f..e6be0ba6 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/IBillingClientWrapper.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/IBillingClientWrapper.kt
@@ -21,7 +21,7 @@ internal interface IBillingClientWrapper {
activity: Activity,
product: QProduct,
offerId: String?,
- applyOffer: Boolean,
+ applyOffer: Boolean? = true,
updatePurchaseInfo: UpdatePurchaseInfo?,
onFailed: (error: BillingError) -> Unit
)
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/LegacyBillingClientWrapper.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/LegacyBillingClientWrapper.kt
index a999ce57..8b061dc8 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/LegacyBillingClientWrapper.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/LegacyBillingClientWrapper.kt
@@ -46,7 +46,7 @@ internal class LegacyBillingClientWrapper(
activity: Activity,
product: QProduct,
offerId: String?, // ignored
- applyOffer: Boolean, // ignored
+ applyOffer: Boolean?, // ignored
updatePurchaseInfo: UpdatePurchaseInfo?,
onFailed: (error: BillingError) -> Unit
) {
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/QonversionBillingService.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/QonversionBillingService.kt
index 5d7c5a61..7a9a5655 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/QonversionBillingService.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/billing/QonversionBillingService.kt
@@ -103,16 +103,16 @@ internal class QonversionBillingService internal constructor(
updatePurchase(
activity,
purchaseModel.product,
- purchaseModel.offerId,
- purchaseModel.applyOffer,
+ purchaseModel.options?.offerId,
+ purchaseModel.options?.applyOffer,
purchaseModel.oldProduct,
purchaseModel.updatePolicy)
} else {
makePurchase(
activity,
purchaseModel.product,
- purchaseModel.offerId,
- purchaseModel.applyOffer
+ purchaseModel.options?.offerId,
+ purchaseModel.options?.applyOffer
)
}
}
@@ -232,7 +232,7 @@ internal class QonversionBillingService internal constructor(
activity: Activity,
product: QProduct,
offerId: String?,
- applyOffer: Boolean,
+ applyOffer: Boolean?,
oldProduct: QProduct,
updatePolicy: QPurchaseUpdatePolicy?
) {
@@ -274,7 +274,7 @@ internal class QonversionBillingService internal constructor(
activity: Activity,
product: QProduct,
offerId: String?,
- applyOffer: Boolean,
+ applyOffer: Boolean?,
updatePurchaseInfo: UpdatePurchaseInfo? = null
) {
executeOnMainThread { billingSetupError ->
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/GooglePurchaseConverter.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/GooglePurchaseConverter.kt
index fb48c63a..00454798 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/GooglePurchaseConverter.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/GooglePurchaseConverter.kt
@@ -1,5 +1,6 @@
package com.qonversion.android.sdk.internal.converter
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.internal.billing.productId
import com.qonversion.android.sdk.internal.milliSecondsToSeconds
import com.qonversion.android.sdk.internal.purchase.Purchase
@@ -7,18 +8,20 @@ import com.qonversion.android.sdk.internal.purchase.Purchase
internal class GooglePurchaseConverter : PurchaseConverter {
override fun convertPurchases(
- purchases: List
+ purchases: List,
+ options: Map?
): List {
- return purchases.map { convertPurchase(it) }
+ return purchases.map { convertPurchase(it, options?.get(it.productId)) }
}
- override fun convertPurchase(purchase: com.android.billingclient.api.Purchase): Purchase {
+ override fun convertPurchase(purchase: com.android.billingclient.api.Purchase, options: QPurchaseOptions?): Purchase {
return Purchase(
storeProductId = purchase.productId,
orderId = purchase.orderId ?: "",
originalOrderId = formatOriginalTransactionId(purchase.orderId ?: ""),
purchaseTime = purchase.purchaseTime.milliSecondsToSeconds(),
purchaseToken = purchase.purchaseToken,
+ contextKeys = options?.contextKeys
)
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/PurchaseConverter.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/PurchaseConverter.kt
index edf997a7..1dbf0154 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/PurchaseConverter.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/converter/PurchaseConverter.kt
@@ -1,9 +1,13 @@
package com.qonversion.android.sdk.internal.converter
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.internal.purchase.Purchase
internal interface PurchaseConverter {
- fun convertPurchase(purchase: com.android.billingclient.api.Purchase): Purchase
+ fun convertPurchase(purchase: com.android.billingclient.api.Purchase, options: QPurchaseOptions?): Purchase
- fun convertPurchases(purchases: List): List
+ fun convertPurchases(
+ purchases: List,
+ options: Map?
+ ): List
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/di/module/AppModule.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/di/module/AppModule.kt
index 8a6c8b15..e9b0ddd6 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/di/module/AppModule.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/di/module/AppModule.kt
@@ -62,7 +62,7 @@ internal class AppModule(
@ApplicationScope
@Provides
- fun providePurchasesCache(sharedPreferences: SharedPreferences): PurchasesCache {
+ fun providePurchasesCache(sharedPreferences: SharedPreferencesCache): PurchasesCache {
return PurchasesCache(sharedPreferences)
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/Inapp.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/Inapp.kt
index c483fa1b..66dc7aab 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/Inapp.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/Inapp.kt
@@ -15,5 +15,6 @@ internal data class PurchaseDetails(
@Json(name = "transaction_id") val transactionId: String,
@Json(name = "original_transaction_id") val originalTransactionId: String,
@Json(name = "product") val storeProductId: String,
- @Json(name = "product_id") val qProductId: String
+ @Json(name = "product_id") val qProductId: String,
+ @Json(name = "context_keys") val contextKeys: List?,
)
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternal.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternal.kt
index f098aa85..d4fa4c02 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternal.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternal.kt
@@ -1,34 +1,39 @@
package com.qonversion.android.sdk.internal.dto.purchase
import com.qonversion.android.sdk.dto.QPurchaseModel
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.QPurchaseUpdateModel
import com.qonversion.android.sdk.dto.QPurchaseUpdatePolicy
import com.qonversion.android.sdk.dto.products.QProduct
internal open class PurchaseModelInternal(
val productId: String,
- val offerId: String?,
- val applyOffer: Boolean,
val oldProductId: String?,
val updatePolicy: QPurchaseUpdatePolicy?,
+ val options: QPurchaseOptions?
) {
constructor(purchaseModel: QPurchaseModel) : this(
purchaseModel.productId,
- purchaseModel.offerId,
- purchaseModel.applyOffer,
null,
null,
+ QPurchaseOptions(offerId = purchaseModel.offerId, applyOffer = purchaseModel.applyOffer)
+ )
+
+ constructor(product: QProduct, options: QPurchaseOptions? = null) : this(
+ product.qonversionID,
+ options?.oldProduct?.qonversionID,
+ options?.updatePolicy,
+ options
)
constructor(purchaseModel: QPurchaseUpdateModel) : this(
purchaseModel.productId,
- purchaseModel.offerId,
- purchaseModel.applyOffer,
purchaseModel.oldProductId,
purchaseModel.updatePolicy,
+ QPurchaseOptions(offerId = purchaseModel.offerId, applyOffer = purchaseModel.applyOffer)
)
fun enrich(product: QProduct, oldProduct: QProduct?) = PurchaseModelInternalEnriched(
- productId, product, offerId, applyOffer, oldProductId, oldProduct, updatePolicy
+ productId, product, oldProduct, updatePolicy, options
)
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternalEnriched.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternalEnriched.kt
index 6218e874..f0ab2a67 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternalEnriched.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/dto/purchase/PurchaseModelInternalEnriched.kt
@@ -1,29 +1,25 @@
package com.qonversion.android.sdk.internal.dto.purchase
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.dto.QPurchaseUpdatePolicy
import com.qonversion.android.sdk.dto.products.QProduct
internal class PurchaseModelInternalEnriched(
productId: String,
val product: QProduct,
- offerId: String?,
- applyOffer: Boolean,
- oldProductId: String?,
val oldProduct: QProduct?,
updatePolicy: QPurchaseUpdatePolicy?,
-) : PurchaseModelInternal(productId, offerId, applyOffer, oldProductId, updatePolicy) {
+ options: QPurchaseOptions?
+) : PurchaseModelInternal(productId, oldProduct?.qonversionID, updatePolicy, options) {
constructor(
purchaseModel: PurchaseModelInternal,
- product: QProduct,
- oldProduct: QProduct?
+ product: QProduct
) : this(
purchaseModel.productId,
product,
- purchaseModel.offerId,
- purchaseModel.applyOffer,
- purchaseModel.oldProductId,
- oldProduct,
- purchaseModel.updatePolicy
+ purchaseModel.options?.oldProduct,
+ purchaseModel.updatePolicy,
+ purchaseModel.options
)
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/purchase/Purchase.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/purchase/Purchase.kt
index d5a7c468..46c252c4 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/purchase/Purchase.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/purchase/Purchase.kt
@@ -9,4 +9,5 @@ internal data class Purchase(
val originalOrderId: String,
val purchaseTime: Long,
val purchaseToken: String,
+ val contextKeys: List?,
)
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/repository/DefaultRepository.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/repository/DefaultRepository.kt
index 56ec9295..eda39d74 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/repository/DefaultRepository.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/repository/DefaultRepository.kt
@@ -598,7 +598,8 @@ internal class DefaultRepository internal constructor(
purchase.orderId,
purchase.originalOrderId,
purchase.storeProductId ?: "",
- qProductId ?: ""
+ qProductId ?: "",
+ purchase.contextKeys
)
}
diff --git a/sdk/src/main/java/com/qonversion/android/sdk/internal/storage/PurchasesCache.kt b/sdk/src/main/java/com/qonversion/android/sdk/internal/storage/PurchasesCache.kt
index e28342b2..450eb7d7 100644
--- a/sdk/src/main/java/com/qonversion/android/sdk/internal/storage/PurchasesCache.kt
+++ b/sdk/src/main/java/com/qonversion/android/sdk/internal/storage/PurchasesCache.kt
@@ -1,6 +1,6 @@
package com.qonversion.android.sdk.internal.storage
-import android.content.SharedPreferences
+import com.qonversion.android.sdk.dto.QPurchaseOptions
import com.qonversion.android.sdk.internal.purchase.Purchase
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
@@ -9,15 +9,22 @@ import java.io.IOException
import java.lang.reflect.Type
internal class PurchasesCache(
- private val preferences: SharedPreferences
+ private val preferences: SharedPreferencesCache
) {
private val moshi = Moshi.Builder().build()
private val collectionPurchaseType: Type = Types.newParameterizedType(
Set::class.java,
Purchase::class.java
)
- private val jsonAdapter: JsonAdapter> =
+ private val collectionPurchaseOptionsType: Type = Types.newParameterizedType(
+ Map::class.java,
+ String::class.java,
+ QPurchaseOptions::class.java
+ )
+ private val purchasesJsonAdapter: JsonAdapter> =
moshi.adapter(collectionPurchaseType)
+ private val purchasesOptionsJsonAdapter: JsonAdapter