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.
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:
-
Open the Android SDK Manager.
-
In the SDK Manager, expand the
Extras section.
-
Select Google Play Billing Library.
-
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:
-
Copy the
IinAppBillingService.aidl file to your Android project.
-
If you are using Eclipse:
-
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.
-
In the
/src directory, click File > New > Package, then create a package named com.android.vending.billing.
-
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.
-
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,
-
Create a sevice connection to facillate messaging between your application and google play.
-
Send Billing Request to google play application.
-
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.