Thursday, 17 September 2015

Google Play In App Billing

In App billing , a service which can be access through our app using an API provided by the google play app, which is already installed in the device.

This service can only be implemented in the applications which will publish through Google Play. Version 3 API is the currently latest version, and maintains very broad compatibility across the range of Android devices. In-app Billing Version 3 is supported on devices running Android 2.2 or higher that have the latest version of the Google Play store installed.

In App billing allow you to sell in-app products. In app-products can be any digital goods like in-game currency(i.e coins, fruits, diamonds which helps you to upgrade your gaming profile). We cant sell any physical goods through in-app billing, or any personel services which require physical delivery. Unlike Priced application, because if once an in-app product purchase, it can refund as there is no refund process provided by the google play.
So, for integrating In-App Billing in your application all you need to have a developer account in google play developer console. Below link will move you into developer console.

Publish Your APP


        If you already have a developer account there then it bit makes a sense that you have already publish some apps there, and just looking here to know how to integrate In-App Billing, So just skip the below para.
This is for all who are looking to create an developer account in google developer console, So for continue to publish your app with In-app Billing, you have to agree with the google terms, and have to paid a sum of $25, to make an account in the developer console. Once all the registration process completes. You can start with In-App Billing.
Download In-appBilling library from sdk manger, and Add AIDL (Android Interface Definition Language) file, to your project, which is an interface of In-app Billing version 3 service, we will use this for all billing request through IPC.
To get the AIDL file:
  1. Open the Android SDK Manager.
  2. In the SDK Manager, expand the Extras section.
  3. Select Google Play Billing Library.
  4. Click Install packages to complete the download.
The IinAppBillingService.aidl file will be installed to <sdk>/extras/google/play_billing/.
To add the AIDL to your project:
  1. Copy the IinAppBillingService.aidl file to your Android project.
    • If you are using Eclipse:
      1. If you are starting from an existing Android project, open the project in Eclipse. If you are creating a new Android project from scratch, click File > New > Android Application Project, then follow the instructions in the New Android Application wizard to create a new project in your workspace.
      2. In the /src directory, click File > New > Package, then create a package named com.android.vending.billing.
      3. Copy the IinAppBillingService.aidl file from <sdk>/extras/google/play_billing/ and paste it into the src/com.android.vending.billing/ folder in your workspace.
    • If you are developing in a non-Eclipse environment: Create the following directory/src/com/android/vending/billing and copy the IInAppBillingService.aidl file into this directory. Put the AIDL file into your project and use the Ant tool to build your project so that theIInAppBillingService.java file gets generated.

  2. Build your application. You should see a generated file named IInAppBillingService.java in the
Update Your Manifest File

For making your application to allow all in app purchases, add the below code in your projects manifest file
uses-permission android:name="com.android.vending.BILLING"
In the next three steps you will finished the In-app purchases tasks,
  1. Create a sevice connection to facillate messaging between your application and google play.
  2. Send Billing Request to google play application.
  3. Handle the synchronus response of your billing request.
Step 1: Bind to InAppBilling Service
IInAppBillingService mService;

ServiceConnection mServiceConn = new ServiceConnection() {
   @Override
   public void onServiceDisconnected(ComponentName name) {
       mService = null;
   }
   @Override
   public void onServiceConnected(ComponentName name, 
      IBinder service) {
       mService = IInAppBillingService.Stub.asInterface(service);
   }
};

Set an Intent of binding In-appBilling service in your activity's on create Method, and unregister it in your onDestroy message.
Note :- Use setPackage method to make your billing transactions safe. It ensures that the billing request generated is only for google play app and preventing other apps to intercepting those requests.
 
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
  serviceIntent.setPackage("com.android.vending");
  bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
 
@Override
public void onDestroy() {
    super.onDestroy();
    if (mService != null) {
        unbindService(mServiceConn);
    }   
}

Step 2: Send Billing Request
Once your application is connected with the google play, now you can start all the purchase request for your in app products, you dont need to handle any transaction setup in your application code , in case if the user has not setup the transactions medium in their google play, google play itself handle the transactions setup. The user can find the number of purchasing items available to purchase, by calling a “Item available for puchase” query which we will disscuss in the next para. Once all the purchases gets sucessful google play recognizes that the user has ownership of that item and prevents him for further transaction with the same product id. You can define the process of consumption in your application for that in app product, and once the product gets consume it can be reset to purchase again.
For Querying Items Available For Purchase
      ArrayList<String> skuList = new ArrayList<String> (); 
     skuList.add("premiumUpgrade");
     skuList.add("gas");
    Bundle querySkus = new Bundle();
   querySkus.putStringArrayList(“ITEM_ID_LIST”, skuList);

These array list items are the product [I.e productID] for which you will make a transaction. This product id will be the same as when you will add the in-app product in your developer console account. We will disscuss it later that how to add the in app products from google developer console. For now you just assume that there is a in-app product already with the above specified product Ids.
To retrieve this information from Google Play, call the getSkuDetails method on the In-app Billing Version 3 API, and pass the method the In-app Billing API version (“3”), the package name of your calling app, the purchase type (“inapp”), and the Bundle that you created.
Bundle skuDetails = mService.getSkuDetails(3, getPackageName(), "inapp", querySkus);
make the above request in background, otherwise it will block your main thread.
In case of successful request , the response code will be BILLING_RESPONSE_RESULT_OK
This will help you to find out all the response code
To get the price of your in app product
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
   ArrayList<String> responseList  = skuDetails.getStringArrayList("DETAILS_LIST");
   for (String thisResponse : responseList) {
      JSONObject object = new JSONObject(thisResponse);
      String sku = object.getString("productId");
      String price = object.getString("price");
      if (sku.equals("premiumUpgrade")) mPremiumUpgradePrice = price;
      else if (sku.equals("gas")) mGasPrice = price;
   }
}
Call getStringArrayList method to get list of available items to purchase, the response will come in JSON Format string. Parse it to Json Objet and get the product price.
Step – 3 Purchasing an Item
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(),
   sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");
Call getBuyIntent to make a purchase request, Pass in to the method the In-app Billing API version (“3”), the package name of your calling app, the product ID for the item to purchase, the purchase type (“inapp” or "subs"), and a developerPayload String. The developerPayloadString is used to specify any additional arguments that you want Google Play to send back along with the purchase information.
If the request is successful, the returned Bundle has a response code of BILLING_RESPONSE_RESULT_OK (0) and aPendingIntent that you can use to start the purchase flow. Next, extract a PendingIntent from the response Bundle with key BUY_INTENT.
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
To complete the purchase transaction, call the startIntentSenderForResult method and use thePendingIntent that you created. In this example, you are using an arbitrary value of 1001 for the request code
startIntentSenderForResult(pendingIntent.getIntentSender(), 1001,  
new Intent(),       Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
If the above request gets successful, you will get a JSON response of the transaction
'{ 
   "orderId":"12999763169054705758.1371079406387615", 
   "packageName":"com.example.app",
   "productId":"exampleSku",
   "purchaseTime":1345678900000,
   "purchaseState":0,
   "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
   "purchaseToken":"rojeslcdyyiapnqcynkjyyjh"
 }'
Google play sends the above respnse to your pending intent to the onActivityResult method of your application.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
   if (requestCode == 1001) {           
      int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
      String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
      String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
        
      if (resultCode == RESULT_OK) {
         try {
            JSONObject jo = new JSONObject(purchaseData);
            String sku = jo.getString("productId");
            alert("You have bought the " + sku + ". Excellent choice, 
               adventurer!");
          }
          catch (JSONException e) {
             alert("Failed to parse purchase data.");
             e.printStackTrace();
          }
      }
   }
}

Querying for Purchased Items

You can make a call to get the list of items which are purchased by the user, the purchase request contains In-app Billing API version (“3”), the package name of your calling app, and the purchase type (“inapp” or "subs").
Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
The Google Play service returns only the purchases made by the user account that is currently logged in to the device. If the request is successful, the returned Bundle has a response code of 0. The response Bundle also contains a list of the product IDs, a list of the order details for each purchase, and the signatures for each purchase.
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
   ArrayList<String> ownedSkus =
      ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
   ArrayList<String>  purchaseDataList =
      ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
   ArrayList<String>  signatureList =
      ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
   String continuationToken = 
      ownedItems.getString("INAPP_CONTINUATION_TOKEN");
   
   for (int i = 0; i < purchaseDataList.size(); ++i) {
      String purchaseData = purchaseDataList.get(i);
      String signature = signatureList.get(i);
      String sku = ownedSkus.get(i);
  
      // do something with this purchase information
      // e.g. display the updated list of products owned by user
   } 
   // if continuationToken != null, call getPurchases again 
   // and pass in the token to retrieve more items
}
For the performance reasons, the above request only return upto 700 products, in one response. If the User has more purchases then google play include a string token mapped to the key INAPP_CONTINUATION_TOKEN in the response Bundle to indicate that more products can be retrieved. Your application can then make a subsequent getPurchases call, and pass in this token as an argument. Google Play continues to return a continuation token in the response Bundle until all products that are owned by the user has been sent to your app.
Consuming A Purchase
____________________________________________________________________
Once an in-app product gets purchased it is assumed as owned by the google play, and cannot be purchase again, until the request of comsumption is not send. Only Managed In-app product are consumable, but subscriptions are not.

int response = mService.consumePurchase(3, getPackageName(), token);

Its your responsibility to control and track how the in-app product is provisioned to the user. For example, if the user purchased in-game currency, you should update the player's inventory with the amount of currency purchased.

No comments:

Post a Comment