Search code examples
androidin-app-purchasein-app-billingin-app-subscriptionandroid-inapp-purchase

InApp Purcahse Issue : Why its showing Unresolved Reference: setType for BillingFlowParams?


Using billing library in android and to buy subscription instead of in-app products (consumable-non consumable), added .setType(SkuType.SUBS) to BillingFlowParams as below :

val billingFlowParams = BillingFlowParams
                                    .newBuilder()
                                    .setType(SkuType.SUBS)
                                    .setSkuDetails(skuDetailsList!![i])
                                    .build()

But, .setType(SkuType.SUBS) shows me Unresolved Reference: setType

What might be the issue ? How can I launch Purchase flow for the In-App Subscription?


Solution

  • try BillingClient.SkuType.SUBS
    You can launch purchase flow like below

    billingClient.launchBillingFlow(this, billingFlowParams).getResponseCode();
    

    if we go more thoroughly,
    -BTW It's in java

    first, you have to implement PurchasesUpdatedListener, AcknowledgePurchaseResponseListener in your class and override onPurchasesUpdated and onAcknowledgePurchaseResponse methods.
    then initialize the billing client

    private void initBilling() {
            billingClient = BillingClient.newBuilder(this)
                    .enablePendingPurchases()
                    .setListener(this)
                    .build();
            billingClient.startConnection(new BillingClientStateListener() {
    
                @Override
                public void onBillingSetupFinished(BillingResult billingResult) {
                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        Purchase.PurchasesResult purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
                        billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.SUBS, (billingResult1, purchaseHistoryRecordList) -> {
                            Log.i("SKURESLUT", purchaseHistoryRecordList.toString());
                        });
                    }
                }
    
                @Override
                public void onBillingServiceDisconnected() {
    
                }
            });
        }
    

    then you can pass the desired package id to the following method and start the billingFlow,

    private void getBillingPackage(String id) {
            List<String> productIdsList = new ArrayList<>();
            productIdsList.add(id);
            SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
            params.setSkusList(productIdsList).setType(BillingClient.SkuType.SUBS);
            billingClient.querySkuDetailsAsync(params.build(),
                    (result, skuDetailsList) -> {
                        if (!skuDetailsList.isEmpty()) {
                            mSkuDetails.addAll(skuDetailsList);
                            BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                                    .setSkuDetails(skuDetailsList.get(0))
                                    .build();
                            int responseCode = billingClient.launchBillingFlow(this, billingFlowParams).getResponseCode();
                        } else {
                            Toast.makeText(this, "Requested package not available", Toast.LENGTH_LONG).show();
                        }
                        Log.e("SKURESLUT", result.toString());
                    });
        }
    

    then in onPurchaseUpdated Method will invoke when billing flow is completed or canceled. You can acknowledge the purchase here

    @Override
        public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                    && purchases != null) {
                for (Purchase purchase : purchases) {
                    Log.e("Purchase:", purchase.toString());
                    if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
                        currentPurchase = purchase;
                        if (!purchase.isAcknowledged()) {
                            AcknowledgePurchaseParams acknowledgePurchaseParams =
                                    AcknowledgePurchaseParams.newBuilder()
                                            .setPurchaseToken(purchase.getPurchaseToken())
                                            .build();
                            billingClient.acknowledgePurchase(acknowledgePurchaseParams, this);
                        }
                    }
                }
            } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
                Toast.makeText(this, "Purchase Cancelled", Toast.LENGTH_LONG).show();
            } else {
                // Handle any other error codes.
            }
        }
    

    Then you can get AcknowledgePurchase like below

    @Override
        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                //Purchase Acknowledged and verified
            } else {
                Toast.makeText(this, "Purchase Failed", Toast.LENGTH_LONG).show();
            }
            Log.e("Acknowledged Purchase:", billingResult.toString());
    
        }