2

How to .setSkuDetails(skuDetails) in java while calling

BillingFlowParams flowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();
int responseCode = billingClient.launchBillingFlow(flowParams);

I searched whole google but did not find any proper and complete implementation, please someone help me with this by providing full process with all necessary functions, because I found only library1.0 examples or Kotlin or incomplete,I want java

please help me in this

Marsad
  • 859
  • 1
  • 14
  • 35
kunal
  • 133
  • 1
  • 1
  • 9
  • Here is it: https://stackoverflow.com/questions/60870706/implementing-in-app-purchase-with-updated-library-in-android – Marsad Apr 10 '20 at 04:16

1 Answers1

2

Here is the full implementation.

For further reference, refer to the documentation: https://developer.android.com/google/play/billing/billing_library_overview

String ITEM_SKU_diamond_500 = "diamond_500";
BillingClient billingClient;
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener;
String premiumUpgradePrice = "";

1: A billing client has to be created using BillingClient.Builder.

billingClient = BillingClient.newBuilder(this)
                .enablePendingPurchases()
                .setListener(this).build();

2: After creating a billingClient start the billingClient connection


        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                    List<String> skuList = new ArrayList<>();
                    skuList.add(ITEM_SKU_diamond_500);
                    final SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                    params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);

3: After establishing a successful connection, make a call with billingClient's querySkuDetailsAsync method to fetch SKU details asynchronously.

                    billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
                        @Override
                        public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
                            if (skuDetailsList != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                                for (SkuDetails skuDetails : skuDetailsList) {
                                    String sku = skuDetails.getSku();
                                    String price = skuDetails.getPrice();

                                    final BillingFlowParams params = BillingFlowParams.newBuilder()
                                            .setSkuDetails(skuDetails)
                                            .build();

                                    if (ITEM_SKU_diamond_500.equals(sku)) {
                                        premiumUpgradePrice = price;

                                        firstBtn500(params);

                                    }

                                    
                                }
                            } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ERROR) {
                                Toast.makeText(DiamondsActivity.this, "Error", Toast.LENGTH_SHORT).show();
                            }
                        }

                    });

                } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.SERVICE_TIMEOUT) {
                    Toast.makeText(DiamondsActivity.this, "Service timeout", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(DiamondsActivity.this, "Failed to connect to the billing client", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                Toast.makeText(DiamondsActivity.this, "Disconnected from the client", Toast.LENGTH_SHORT).show();
            }
        });

        acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
            @Override
            public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
                Toast.makeText(DiamondsActivity.this, "Purchase acknowledged", Toast.LENGTH_SHORT).show();
            }

        };

4: When a user tries to make an in-app purchase or subscribe to the product subscription, check if the product is supported using billngClient

isFeatureSupported(BillingClient.FeatureType```./* SUBSCRIPTIONS or other */)

method and make a call to billingClient's launchBillingFlow method

private void firstBtn500(final BillingFlowParams params) {

        firstPurchaseBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                billingClient.launchBillingFlow(DiamondsActivity.this, params);

            }
        });

    }

UPDATE

Here you can check if the item is already purchased or not

 @Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {

        if (purchases != null && billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

            for (Purchase purchase : purchases) {
                handlePurchases(purchase);
            }

        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
            Toast.makeText(this, "Purchased Canceled", Toast.LENGTH_SHORT).show();
        }

else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
            Toast.makeText(this, "Already Purchased", Toast.LENGTH_SHORT).show();
        }

    }

If you want to purchase an item once, you need to Acknowledge the purchase

private void handlePurchases(final Purchase purchase) {

        if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            //Acknowledge the purchase if it hasn't already been acknowledged.
            if (!purchase.isAcknowledged()) {
                AcknowledgePurchaseParams acknowledgePurchaseParams =
                        AcknowledgePurchaseParams.newBuilder()
                                .setPurchaseToken(purchase.getPurchaseToken())
                                .build();
                billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

            }
            

If you want to purchase the same item again and again (Like in-app/game in coins or credit or something like this). You need to consume purchase below is the code to consume purchase.

            // Todo: Consume the purchase async
            ConsumeParams consumeParams = ConsumeParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();

            ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {

                    Toast.makeText(DiamondsActivity.this, "Purchase successful", Toast.LENGTH_SHORT).show();

                    if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                        if (purchase.getSku().equalsIgnoreCase(ITEM_SKU_diamond_500)) {
                            Toast.makeText(DiamondsActivity.this, "Thank you for purchasing!", Toast.LENGTH_SHORT).show();
                        }

                    }

                }
            };

            billingClient.consumeAsync(consumeParams, consumeResponseListener);


        } else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {

            Toast.makeText(this, "Purchase pending", Toast.LENGTH_SHORT).show();

        }

    }
Marsad
  • 859
  • 1
  • 14
  • 35
  • hi, I have few questions - how to call billingClient.launchBillingFlow(MainActivity.this, params); from a function without implementing on click listener means if I want to call it from two different buttons, like from void buy(View view) function, second - how to Acknowledge purchase for each item do we need to use skudetails again here and how to query purchased items on app startup to set what is already purchased, and in which section to use shared preference to save purchased item, what is purchase.getSku().equalsIgnoreCase here do I need to save in it or before this – kunal Apr 13 '20 at 00:05
  • please help me in this, I asked after 2 days because my app was in pending publish testing status, please modify your answer little bit to answer these questions and try to make it with 2 items , I will appreciate your help. – kunal Apr 13 '20 at 00:18
  • Take a look: https://stackoverflow.com/questions/61319468/gpay-inappsubscription-setskudetails/61321347#61321347 – Marsad Apr 25 '20 at 16:10
  • to set if item is already purchased you need to acknowledge purchase not consume – Marsad Apr 25 '20 at 16:10