Google Play Billing Library

About the code snippets

TrivialDrive v2 - How to list the available products. - Start a purchase flow. - Record product consumption

Steps to add Google Play Billing to an app

  1. Update your app's dependencies.
  2. Connect to Google Play.
  3. Query for in-app product details.
  4. Enable the purchase of an in-app product.
  5. Query for purchased items.
  6. Add one-time product-specific or subscription-specific code.

Update your app dependencies

dependencies {
    ...
    api 'com.android.billingclient:billing:1.2'
}

Connect to Google Play

Connect to Google play using BillingClient.

mBillingClient = BillingClient.newBuilder(mActivity).setListener(this).build();
mBillingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(@BillingResponse int billingResponseCode) {
        if (billingResponseCode == BillingResponse.OK) {
            // The billing client is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

Query for in-app product details

  • SkiType.INAPP for one-time products.
  • SkiType.SUBS for subscription.

Query products.

List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(int responseCode, List<SkuDetails> skuDetailsList)
            // Process the result.
        }
    });
  • non-consumable: A one-time product that can be used indefinitely is called a non-consumable.
  • consumable: A one-time product with non-infinite use is called consumable.

Show product details.

for (SkuDetails skuDetails : skuDetailsList) {
   String sku = skuDetails.getSku();
   String price = skuDetails.getPrice();
}

Enable the purchase of an in-app product

Start billing process

BillingFlowParams flowParams = BillingFlowParams.newBuilder()
         .setSku(skuId)
         .setType(SkuType.INAPP) // SkuType.SUB for subscription
         .build();
int responseCode = mBillingClient.launchBillingFlow(flowParams);

It will call onPurchasesUpdated to give us a result.

@Override
void onPurchasesUpdated(@BillingResponse int responseCode, List<Purchase> purchases) {
    if (responseCode == BillingResponse.OK
            && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (responseCode == BillingResponse.USER_CANCELED) {
        // Handle an error caused by a user cancelling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

Successful purchases also generate a purchase token, which is unique identifier representing the user and the product ID for in-app product they purchased. The purchase token for subscription stays the same for each billing period.

Verify a purchase

Verify a purchase on a server

  • Ensure that the device-server handshake is secure.
  • Verify order Id is a unique value that you have not previously processed.
  • Verify that your app's key has signed the INAPP_PURCHASE_DATA that you process.
    sequenceDiagram Client ->>+ Google : purchase(appid, skuid) Google -->>- Client : purchaseToken, orderId Client ->>+ YourServer : verify(purchaseToken, orderId, account) YourServer ->>+ Google : Get purchase(appid, purchaseToken) Google -->>- YourServer : Purchase Detail YourServer -->>- Client : verifyed

Best Practices

  • Use a real-time service to deliver your content.
  • User a remote server to deliver your content.
  • Encrypt the content.
  • Whenever a user accesses the content, you should verify the user entitlement.

From

Android Doc