I'm testing in-app purchase using the three reserved product IDs for testing static Google Play Billing responses:
However, setSku
and setType
seem to be deprecated in the BillingFlowParams.Builder
class. Instead, we should be using setSkuDetails(SkuDetails)
.
How should I change the BillingFlowParams
in the example code to use SkuDetails
for the test product IDs?
BillingFlowParams flowParams = BillingFlowParams.newBuilder() .setSku(skuId) .setType(SkuType.INAPP) .build(); int responseCode = mBillingClient.launchBillingFlow(flowParams);
you should get SkuDetails from BillingClient.querySkuDetailsAsync, the sample code may seems like this:
private BillingClient mBillingClient; // .... mBillingClient = BillingClient.newBuilder(this).setListener(new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(int responseCode, @Nullable List<Purchase> purchases) { if (responseCode == BillingClient.BillingResponse.OK && purchases != null) { // do something you want } else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) { } else { } } }).build(); mBillingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponseCode) { if (billingResponseCode == BillingClient.BillingResponse.OK) { // The billing client is ready. You can query purchases here. List<String> skuList = new ArrayList<>(); skuList.add("android.test.purchased"); SkuDetailsParams skuDetailsParams = SkuDetailsParams.newBuilder() .setSkusList(skuList).setType(BillingClient.SkuType.INAPP).build(); mBillingClient.querySkuDetailsAsync(skuDetailsParams, new SkuDetailsResponseListener() { @Override public void onSkuDetailsResponse(int responseCode, List<SkuDetails> skuDetailsList) { BillingFlowParams flowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetailsList.get(0)) .build(); int billingResponseCode = billingClient.launchBillingFlow(SkuActivity.this, flowParams); if (billingResponseCode == BillingClient.BillingResponse.OK) { // do something you want } } }); } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. } });
You can also take a look to https://developer.android.com/google/play/billing/billing_library_overview
I'm posting a step by step process for in-app billing, which I had tested recently after the release of Billing Library version 4.0
Google help resource can be found here
First things first: Update your build.gradle
dependencies { def billing_version = "4.0.0" implementation "com.android.billingclient:billing:$billing_version" }
Now, comes the coding part: BillingActivity.java
private BillingClient mBillingClient; // ... submitButton.setOnClickListener(v -> { mBillingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) { for (Purchase purchase : purchases) { handlePurchase(purchase); } // Perform your Successful Purchase Task here Snackbar.make(findViewById(android.R.id.content), "Great!! Purchase Flow Successful! :)", Snackbar.LENGTH_LONG).show(); dismiss(); } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. Snackbar.make(findViewById(android.R.id.content), "User Cancelled the Purchase Flow!", Snackbar.LENGTH_LONG).show(); } else { // Handle any other error codes. Snackbar.make(findViewById(android.R.id.content), "Error! Purchase Task was not performed!", Snackbar.LENGTH_LONG).show(); } } }).build(); mBillingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingSetupFinished(@NonNull BillingResult billingResult) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { // The BillingClient is ready. You can query purchases here. List<String> skuList = new ArrayList<>(); skuList.add("billing_template_1"); skuList.add("billing_template_2"); SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder(); params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP); mBillingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() { @Override public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) { // Process the result. // Retrieve a value for "skuDetails" by calling querySkuDetailsAsync(). BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetailsList.get(0)) .build(); int responseCode = mBillingClient.launchBillingFlow(activity, billingFlowParams).getResponseCode(); } }); } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to Google Play by calling the startConnection() method. Toast.makeText(BillingActivity.this, "Service Disconnected!", Toast.LENGTH_SHORT).show(); } }); }); void handlePurchase(Purchase purchase) { ConsumeParams consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); ConsumeResponseListener listener = new ConsumeResponseListener() { @Override public void onConsumeResponse(BillingResult billingResult, @NonNull String purchaseToken) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { // Handle the success of the consume operation. } } }; mBillingClient.consumeAsync(consumeParams, listener); } private void dismiss() { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); finish(); }
FYI:
.enablePendingPurchase()
skuList.add("billing_template_1")
which has to be done from your Developer Console. So, billing_template_1
is the name of your Monetise > Products > In-app products > Prouduct ID If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With