diff --git a/store/build.gradle b/store/build.gradle index b45388507..994b8b2ca 100644 --- a/store/build.gradle +++ b/store/build.gradle @@ -96,7 +96,7 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.6.2' // Purchases - implementation 'com.android.billingclient:billing:6.1.0' + implementation 'com.android.billingclient:billing:8.0.0' // Dagger kapt "com.google.dagger:dagger-compiler:$dagger_version" diff --git a/store/src/main/java/net/ivpn/client/billing/BillingListener.java b/store/src/main/java/net/ivpn/client/billing/BillingListener.java index f9e48c817..d1f7ad82d 100644 --- a/store/src/main/java/net/ivpn/client/billing/BillingListener.java +++ b/store/src/main/java/net/ivpn/client/billing/BillingListener.java @@ -23,10 +23,9 @@ */ -import com.android.billingclient.api.ProductDetails; -import net.ivpn.client.billing.BillingManagerWrapper.PurchaseState; +import com.android.billingclient.api.QueryProductDetailsResult; -import java.util.List; +import net.ivpn.client.billing.BillingManagerWrapper.PurchaseState; public interface BillingListener { @@ -34,7 +33,7 @@ public interface BillingListener { void onPurchaseStateChanged(PurchaseState state); - void onCheckingProductDetailsSuccess(List productDetailsList); + void onCheckingProductDetailsSuccess(QueryProductDetailsResult productDetailsList); void onPurchaseError(int errorStatus, String errorMessage); diff --git a/store/src/main/java/net/ivpn/client/billing/BillingManager.java b/store/src/main/java/net/ivpn/client/billing/BillingManager.java index dca7ac968..139cecbfb 100644 --- a/store/src/main/java/net/ivpn/client/billing/BillingManager.java +++ b/store/src/main/java/net/ivpn/client/billing/BillingManager.java @@ -34,11 +34,13 @@ import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeParams; import com.android.billingclient.api.ConsumeResponseListener; +import com.android.billingclient.api.PendingPurchasesParams; import com.android.billingclient.api.ProductDetails; import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.Purchase; import com.android.billingclient.api.PurchasesUpdatedListener; import com.android.billingclient.api.QueryProductDetailsParams; +import com.android.billingclient.api.QueryPurchasesParams; import net.ivpn.client.StoreIVPNApplication; import net.ivpn.client.dagger.BillingScope; @@ -69,8 +71,8 @@ public class BillingManager implements PurchasesUpdatedListener { BillingManager() { LOGGER.info("Creating Billing client."); billingClient = BillingClient.newBuilder(StoreIVPNApplication.instance) - .enablePendingPurchases() .setListener(this) + .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .build(); } @@ -118,7 +120,9 @@ public void onBillingServiceDisconnected() { private void queryPurchases() { Runnable queryToExecute = () -> { long time = System.currentTimeMillis(); - billingClient.queryPurchasesAsync(BillingClient.SkuType.INAPP, (billingResult, purchases) -> { + billingClient.queryPurchasesAsync(QueryPurchasesParams.newBuilder() + .setProductType(BillingClient.ProductType.INAPP) + .build(), (billingResult, purchases) -> { LOGGER.info("Querying products elapsed time: " + (System.currentTimeMillis() - time) + "ms"); LOGGER.info("Querying products result code: " diff --git a/store/src/main/java/net/ivpn/client/billing/BillingViewModel.java b/store/src/main/java/net/ivpn/client/billing/BillingViewModel.java index 51aef6d14..93275b905 100644 --- a/store/src/main/java/net/ivpn/client/billing/BillingViewModel.java +++ b/store/src/main/java/net/ivpn/client/billing/BillingViewModel.java @@ -25,7 +25,7 @@ import androidx.databinding.ObservableBoolean; import androidx.databinding.ObservableField; -import com.android.billingclient.api.ProductDetails; +import com.android.billingclient.api.QueryProductDetailsResult; import net.ivpn.client.StoreIVPNApplication; import net.ivpn.core.R; @@ -33,8 +33,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - import javax.inject.Inject; public class BillingViewModel implements BillingListener { @@ -113,7 +111,7 @@ public void onPurchaseStateChanged(BillingManagerWrapper.PurchaseState state) { } @Override - public void onCheckingProductDetailsSuccess(List productDetailsList) { + public void onCheckingProductDetailsSuccess(QueryProductDetailsResult productDetailsList) { // Nothing to do here } diff --git a/store/src/main/java/net/ivpn/client/signup/SignUpViewModel.kt b/store/src/main/java/net/ivpn/client/signup/SignUpViewModel.kt index ea8c3c272..e7cf30daa 100644 --- a/store/src/main/java/net/ivpn/client/signup/SignUpViewModel.kt +++ b/store/src/main/java/net/ivpn/client/signup/SignUpViewModel.kt @@ -30,6 +30,7 @@ import androidx.navigation.NavController import com.android.billingclient.api.BillingClient import com.android.billingclient.api.ProductDetails import com.android.billingclient.api.QueryProductDetailsParams.Product +import com.android.billingclient.api.QueryProductDetailsResult import net.ivpn.client.R import net.ivpn.client.billing.BillingListener import net.ivpn.client.billing.BillingManagerWrapper @@ -279,29 +280,35 @@ class SignUpViewModel @Inject constructor( } } - override fun onCheckingProductDetailsSuccess(productDetailsList: List) { + override fun onCheckingProductDetailsSuccess(productDetails: QueryProductDetailsResult?) { LOGGER.info("productDetailsList") dataLoading.set(false) - productDetailsList.let { details -> + productDetails?.productDetailsList.let { details -> selectedPlan.get()?.let { plan -> - for (productDetails in details) { - LOGGER.info("Check ${productDetails.productId}") - when (productDetails.productId) { - plan.skuPath + Period.ONE_WEEK.skuPath -> { - oneWeek.set(productDetails) - } - plan.skuPath + Period.ONE_MONTH.skuPath -> { - oneMonth.set(productDetails) - } - plan.skuPath + Period.ONE_YEAR.skuPath -> { - oneYear.set(productDetails) - } - plan.skuPath + Period.TWO_YEARS.skuPath -> { - twoYear.set(productDetails) - } - plan.skuPath + Period.THREE_YEARS.skuPath -> { - threeYear.set(productDetails) + if (details != null) { + for (productDetails in details) { + LOGGER.info("Check ${productDetails.productId}") + when (productDetails.productId) { + plan.skuPath + Period.ONE_WEEK.skuPath -> { + oneWeek.set(productDetails) + } + + plan.skuPath + Period.ONE_MONTH.skuPath -> { + oneMonth.set(productDetails) + } + + plan.skuPath + Period.ONE_YEAR.skuPath -> { + oneYear.set(productDetails) + } + + plan.skuPath + Period.TWO_YEARS.skuPath -> { + twoYear.set(productDetails) + } + + plan.skuPath + Period.THREE_YEARS.skuPath -> { + threeYear.set(productDetails) + } } } } @@ -313,25 +320,32 @@ class SignUpViewModel @Inject constructor( selectPeriod(Period.ONE_YEAR) } - for (productDetails in details) { - when (productDetails.productId) { - Plan.STANDARD.skuPath + Period.ONE_WEEK.skuPath -> { - standardWeek.set(getPricePerPeriodString(productDetails, "Week")) - } - Plan.STANDARD.skuPath + Period.ONE_MONTH.skuPath -> { - standardMonth.set(getPricePerPeriodString(productDetails, "Month")) - } - Plan.STANDARD.skuPath + Period.ONE_YEAR.skuPath -> { - standardYear.set(getPricePerPeriodString(productDetails, "Year")) - } - Plan.PRO.skuPath + Period.ONE_WEEK.skuPath -> { - proWeek.set(getPricePerPeriodString(productDetails, "Week")) - } - Plan.PRO.skuPath + Period.ONE_MONTH.skuPath -> { - proMonth.set(getPricePerPeriodString(productDetails, "Month")) - } - Plan.PRO.skuPath + Period.ONE_YEAR.skuPath -> { - proYear.set(getPricePerPeriodString(productDetails, "Year")) + if (details != null) { + for (productDetails in details) { + when (productDetails.productId) { + Plan.STANDARD.skuPath + Period.ONE_WEEK.skuPath -> { + standardWeek.set(getPricePerPeriodString(productDetails, "Week")) + } + + Plan.STANDARD.skuPath + Period.ONE_MONTH.skuPath -> { + standardMonth.set(getPricePerPeriodString(productDetails, "Month")) + } + + Plan.STANDARD.skuPath + Period.ONE_YEAR.skuPath -> { + standardYear.set(getPricePerPeriodString(productDetails, "Year")) + } + + Plan.PRO.skuPath + Period.ONE_WEEK.skuPath -> { + proWeek.set(getPricePerPeriodString(productDetails, "Week")) + } + + Plan.PRO.skuPath + Period.ONE_MONTH.skuPath -> { + proMonth.set(getPricePerPeriodString(productDetails, "Month")) + } + + Plan.PRO.skuPath + Period.ONE_YEAR.skuPath -> { + proYear.set(getPricePerPeriodString(productDetails, "Year")) + } } } }