From fd0add4aa502d3523c76533550fbe234c2ef0197 Mon Sep 17 00:00:00 2001 From: youssefali424 Date: Mon, 25 Jul 2022 01:02:18 +0200 Subject: [PATCH 1/3] migrate billing to 5.0.0 --- android/build.gradle | 4 +- .../AndroidInappPurchasePlugin.kt | 91 +++++++++++-------- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 16ffe6cf..e9649b92 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -44,8 +44,8 @@ android { } dependencies { - implementation 'com.android.billingclient:billing-ktx:4.1.0' + implementation 'com.android.billingclient:billing-ktx:5.0.0' implementation files('jars/in-app-purchasing-2.0.76.jar') - implementation 'androidx.annotation:annotation:1.3.0' + implementation 'androidx.annotation:annotation:1.4.0' } diff --git a/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt b/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt index 1fdb7293..8c423d57 100644 --- a/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt +++ b/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt @@ -206,7 +206,8 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, ) { try { val array = ArrayList() - billingClient!!.queryPurchasesAsync(BillingClient.SkuType.INAPP) + val params = QueryPurchasesParams.newBuilder().apply { setProductType(BillingClient.ProductType.INAPP) }.build() + billingClient!!.queryPurchasesAsync(params) { billingResult, skuDetailsList -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { if (skuDetailsList.size == 0) { @@ -252,9 +253,10 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, call: MethodCall, safeChannel: MethodResultWrapper ) { - val type = if(call.argument("type") == "subs") BillingClient.SkuType.SUBS else BillingClient.SkuType.INAPP + val type = if(call.argument("type") == "subs") BillingClient.ProductType.SUBS else BillingClient.ProductType.INAPP + val params = QueryPurchasesParams.newBuilder().apply { setProductType(type) }.build() val items = JSONArray() - billingClient!!.queryPurchasesAsync(type) { billingResult, skuDetailsList -> + billingClient!!.queryPurchasesAsync(params) { billingResult, skuDetailsList -> if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) { for (purchase in skuDetailsList) { val item = JSONObject() @@ -355,10 +357,11 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, call: MethodCall, safeChannel: MethodResultWrapper ) { - val type = if(call.argument("type") == "subs") BillingClient.SkuType.SUBS else BillingClient.SkuType.INAPP + val type = if(call.argument("type") == "subs") BillingClient.ProductType.SUBS else BillingClient.ProductType.INAPP + val params = QueryPurchaseHistoryParams.newBuilder().apply { setProductType(type) }.build() billingClient!!.queryPurchaseHistoryAsync( - type, + params, PurchaseHistoryResponseListener { billingResult, purchaseHistoryRecordList -> if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) { val errorData = BillingError.getErrorFromResponseData(billingResult.responseCode) @@ -391,21 +394,21 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, call: MethodCall, safeChannel: MethodResultWrapper ) { - val skuArr = call.argument>("skus")!! - val skuList = ArrayList() + val skuArr : ArrayList = call.argument>("skus")!! + val skuList = ArrayList() for (i in skuArr.indices) { - skuList.add(skuArr[i]) + skuList.add(QueryProductDetailsParams.Product.newBuilder().setProductId(skuArr[i]).setProductType(skuType).build()) } - billingClient!!.querySkuDetailsAsync( - SkuDetailsParams.newBuilder().setSkusList(skuList).setType(skuType).build() + billingClient!!.queryProductDetailsAsync( + QueryProductDetailsParams.newBuilder().setProductList(skuList).build() ) { billingResult, skuDetailsList -> if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) { val errorData = BillingError.getErrorFromResponseData(billingResult.responseCode) safeChannel.error(call.method, errorData.code, errorData.message) - return@querySkuDetailsAsync + return@queryProductDetailsAsync } - for (sku in skuDetailsList!!) { + for (sku in skuDetailsList) { if (!skus.contains(sku)) { skus.add(sku) } @@ -414,32 +417,43 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, val items = JSONArray() for (skuDetails in skuDetailsList) { val item = JSONObject() - item.put("productId", skuDetails.sku) - item.put("price", (skuDetails.priceAmountMicros / 1000000f).toString()) - item.put("currency", skuDetails.priceCurrencyCode) - item.put("type", skuDetails.type) - item.put("localizedPrice", skuDetails.price) + item.put("productId", skuDetails.productId) + item.put("price", ((skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros ?: 0) / 1000000f).toString()) + item.put("currency", skuDetails.oneTimePurchaseOfferDetails?.priceCurrencyCode) + item.put("type", skuDetails.productType) + item.put("localizedPrice", skuDetails.oneTimePurchaseOfferDetails?.formattedPrice) item.put("title", skuDetails.title) item.put("description", skuDetails.description) - item.put("introductoryPrice", skuDetails.introductoryPrice) - item.put("subscriptionPeriodAndroid", skuDetails.subscriptionPeriod) - item.put("freeTrialPeriodAndroid", skuDetails.freeTrialPeriod) - item.put("introductoryPriceCyclesAndroid", skuDetails.introductoryPriceCycles) - item.put("introductoryPricePeriodAndroid", skuDetails.introductoryPricePeriod) + val subs = JSONArray() + if(skuDetails.subscriptionOfferDetails!=null) { + for (it in skuDetails.subscriptionOfferDetails!!) { + for (pricing in it.pricingPhases.pricingPhaseList) { + val subItem = JSONObject() + subItem.put("introductoryPrice", pricing.formattedPrice) + subItem.put("subscriptionPeriodAndroid", pricing.billingPeriod.) +// item.put("freeTrialPeriodAndroid", pricing.getRecurrenceMode()) + subItem.put("introductoryPriceCyclesAndroid", pricing.billingCycleCount) +// item.put("introductoryPricePeriodAndroid", pricing.p) + subs.put(subItem) + } + + } + } // new - item.put("iconUrl", skuDetails.iconUrl) - item.put("originalJson", skuDetails.originalJson) - item.put("originalPrice", (skuDetails.priceAmountMicros / 1000000f).toDouble()) +// item.put("iconUrl", skuDetails.) +// item.put("originalJson", skuDetails.zzb) + item.put("subscriptionOfferDetails", subs) + item.put("originalPrice", ((skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros ?: 0) / 1000000f).toDouble()) items.put(item) } safeChannel.success(items.toString()) - return@querySkuDetailsAsync + return@queryProductDetailsAsync } catch (je: JSONException) { je.printStackTrace() safeChannel.error(TAG, BillingError.E_BILLING_RESPONSE_JSON_PARSE_ERROR, je.message) } catch (fe: FlutterException) { safeChannel.error(call.method, fe.message, fe.localizedMessage) - return@querySkuDetailsAsync + return@queryProductDetailsAsync } } } @@ -448,16 +462,16 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, call: MethodCall, safeChannel: MethodResultWrapper ) { - val type = if(call.argument("type") == "subs") BillingClient.SkuType.SUBS else BillingClient.SkuType.INAPP + val type = if(call.argument("type") == "subs") BillingClient.ProductType.SUBS else BillingClient.ProductType.INAPP val obfuscatedAccountId = call.argument("obfuscatedAccountId") val obfuscatedProfileId = call.argument("obfuscatedProfileId") val sku = call.argument("sku") val prorationMode = call.argument("prorationMode")!! val purchaseToken = call.argument("purchaseToken") val builder = newBuilder() - var selectedSku: SkuDetails? = null + var selectedSku: ProductDetails? = null for (skuDetail in skus) { - if (skuDetail.sku == sku) { + if (skuDetail.productId == sku) { selectedSku = skuDetail break } @@ -468,11 +482,14 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, safeChannel.error(TAG, "buyItemByType", debugMessage) return } - builder.setSkuDetails(selectedSku) + + var arr = ArrayList() + arr.add(ProductDetailsParams.newBuilder().apply { setProductDetails(selectedSku) }.build()) + builder.setProductDetailsParamsList(arr) val params = SubscriptionUpdateParams.newBuilder() if (purchaseToken != null) { - params.setOldSkuPurchaseToken(purchaseToken) + params.setOldPurchaseToken(purchaseToken) } if (obfuscatedAccountId != null) { builder.setObfuscatedAccountId(obfuscatedAccountId) @@ -484,8 +501,8 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, when (prorationMode) { -1 -> {} //ignore ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE -> { - params.setReplaceSkusProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) - if (type != BillingClient.SkuType.SUBS) { + params.setReplaceProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) + if (type != BillingClient.ProductType.SUBS) { safeChannel.error( TAG, "buyItemByType", @@ -498,8 +515,8 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, ProrationMode.DEFERRED, ProrationMode.IMMEDIATE_WITH_TIME_PRORATION, ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE -> - params.setReplaceSkusProrationMode(prorationMode) - else -> params.setReplaceSkusProrationMode(ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY) + params.setReplaceProrationMode(prorationMode) + else -> params.setReplaceProrationMode(ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY) } if (purchaseToken != null) { @@ -574,6 +591,6 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, companion object { private const val TAG = "InappPurchasePlugin" private const val PLAY_STORE_URL = "https://play.google.com/store/account/subscriptions" - private var skus: ArrayList = arrayListOf() + private var skus: ArrayList = arrayListOf() } } \ No newline at end of file From 01ba6988c1bc54d8bf3227c341311014b1915721 Mon Sep 17 00:00:00 2001 From: youssefali424 Date: Mon, 25 Jul 2022 01:12:30 +0200 Subject: [PATCH 2/3] fix kotlin error --- .../flutterinapppurchase/AndroidInappPurchasePlugin.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt b/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt index 8c423d57..7e16210d 100644 --- a/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt +++ b/android/src/main/kotlin/com/dooboolab/flutterinapppurchase/AndroidInappPurchasePlugin.kt @@ -430,7 +430,7 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, for (pricing in it.pricingPhases.pricingPhaseList) { val subItem = JSONObject() subItem.put("introductoryPrice", pricing.formattedPrice) - subItem.put("subscriptionPeriodAndroid", pricing.billingPeriod.) + subItem.put("subscriptionPeriodAndroid", pricing.billingPeriod) // item.put("freeTrialPeriodAndroid", pricing.getRecurrenceMode()) subItem.put("introductoryPriceCyclesAndroid", pricing.billingCycleCount) // item.put("introductoryPricePeriodAndroid", pricing.p) @@ -439,9 +439,6 @@ class AndroidInappPurchasePlugin internal constructor() : MethodCallHandler, } } - // new -// item.put("iconUrl", skuDetails.) -// item.put("originalJson", skuDetails.zzb) item.put("subscriptionOfferDetails", subs) item.put("originalPrice", ((skuDetails.oneTimePurchaseOfferDetails?.priceAmountMicros ?: 0) / 1000000f).toDouble()) items.put(item) From 8a56287b360ffc30437d1e4d359bffada0fbf20e Mon Sep 17 00:00:00 2001 From: youssefali424 Date: Mon, 25 Jul 2022 01:55:51 +0200 Subject: [PATCH 3/3] migrate billing to 5.0.0 --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index e9649b92..1dd60892 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -44,7 +44,7 @@ android { } dependencies { - implementation 'com.android.billingclient:billing-ktx:5.0.0' + implementation 'com.android.billingclient:billing:5.0.0' implementation files('jars/in-app-purchasing-2.0.76.jar') implementation 'androidx.annotation:annotation:1.4.0' }