THIS CONTENT DOWNLOAD SHORTLY

Objective

Main objective of this android in app purchase tutorial is to give you an idea about how to implement in-app purchase in version 3.

 

Introduction:

In-app Purchase Version 3 (IAP V3) makes it easier to integrate In-app Purchase into your android app. There are number of features includes in this version to improved APIs to track ownership of consumable goods, synchronous purchase flow and local caching of in-app purchase data. It also known as Google play In App billing.

Follow the below steps to implement In-app Purchase or Google play In App billing system into your Android app:

 

Step 1 Create Application

Create an Android project and add billing permission to your Android project’s manifest file. 

manifest billing permissions

 

Step 2 Export signed apk file

Export signed apkfile as per below image. 

export signed apk

 

Step 3 InAppPurchase Products

Upload signed apk to Google Play Store Developer Console and add desired In App Purchase products. 

adding products

 

Step 4 Add Products

Add New Product in your play store admin console. There are 3 types of products you can purchase on Android via IAP, such as Managed Products, Unmanaged Products & Subscription.

 

4.1 Managed Product

Managed items that can be purchased only once per user account on Google Play.
managed product

 

4.2 Unmanaged Products

Unmanaged products are not managed by Google Play. You are responsible for managing the transaction information and cannot query Google Play to retrieve transaction.

unmanaged product

Note

As we can see in the screenshot, from IAP V3 – Google has removed unmanaged products, if you want to have unmanaged product, you can rather treat it as managed consumable product.

 

4.3 Subscription

Subscription let you sell content, services or features in your app with automated, recurring billing.
subscription

 

Step 5 Download Android Billing Library

Download Latest Android Billing Library that is also known as Google Market Billing. 

download latest android billing library

 

Step 6 Import Sample Project

Browse through the path given below and import the TrivialDrive Project in Eclipse/ ADT. 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
 
 

Step 7 Import TrivalDriveSample Project

Import TrivialDriveSample Project into Eclipse/ ADT.

import trivial drive project

 

Step 8 Get util Package

Copy and Paste util package in your project. You can rename this package name if you wish. 

copy paste util package

 

Step 9 Get Billing Package

Copy and Paste billing package in your project.

Note

Make sure you don’t rename billing package.

copy paste billing package

Note

This is how your project structure should look like.

after importing libraries

 

Step 10 PlaceHolderFragment.java file

Now we will move towards coding portions for this project. Check PlaceHolderFragment.java file in the project given along with this blog.

Over here in onCreate method we are doing setup for in app purchase service (check step 11 to get your base64EncodedPublicKey)

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String base64EncodedPublicKey = "YOUR KEY";// CONSTRUCT_YOUR_KEY_AND_PLACE_IT_HERE
count = PreferenceManager.getDefaultSharedPreferences(getActivity())
.getInt("coin", 0);
Log.d(TAG, "Creating IAB helper.");
mHelper = new IabHelper(getActivity(), base64EncodedPublicKey);
 
// enable debug logging (for a production application, you should set
// this to false).
mHelper.enableDebugLogging(true);
 
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
 
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Toast.makeText(getActivity(),
"Problem setting up in-app billing: " + result,
Toast.LENGTH_LONG).show();
return;
}
 
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null)
return;
 
// IAP is fully set up. Now, let's get an inventory of stuff we
// own.
Log.d(TAG, "Setup successful. Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
}
 

Step 11 License Key

Copy License key from Android Developer Console. 

license key

 

Step 12 QueryInventoryFinishedListener

Implementing code for Query Inventory Finished Listener.

// Listener that's called when we finish querying the items and
// subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(final IabResult result,
final Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
 
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) {
return;
}
 
// Is it a failure?
if (result.isFailure()) {
Toast.makeText(getActivity(),
"Failed to query inventory: " + result,
Toast.LENGTH_LONG).show();
return;
}
 
Log.d(TAG, "Query inventory was successful.");
 
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
 
// Do we have the premium upgrade?
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
isFullVersion = premiumPurchase != null
&& verifyDeveloperPayload(premiumPurchase);
Log.d(TAG, "User is " + (isFullVersion ? "PREMIUM" : "NOT PREMIUM"));
 
// // Do we have the subscibtion?
Purchase subscriptionForFullVersion = inventory
.getPurchase(SKU_SUBSCRIBED);
isSubscribe = subscriptionForFullVersion != null
&& verifyDeveloperPayload(subscriptionForFullVersion);
Log.d(TAG, "User " + (isSubscribe ? "HAS" : "DOES NOT HAVE")
+ " full version subscription.");
 
// Check for coins -- you can get coins
// tank immediately
Purchase coinsPurchase = inventory.getPurchase(SKU_COINS);
if (coinsPurchase != null && verifyDeveloperPayload(coinsPurchase)) {
Log.d(TAG, "We have Coins. Consuming it.");
mHelper.consumeAsync(inventory.getPurchase(SKU_COINS),
mConsumeFinishedListener);
return;
}
 
Log.d(TAG, "Initial inventory query finished; enabling main UI.");
}
};

Note

Monitor premiumPurchase to check that IAP is already subscribed or Purchased or none.

Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
isFullVersion = premiumPurchase != null
&& verifyDeveloperPayload(premiumPurchase);
Log.d(TAG, "User is " + (isFullVersion ? "PREMIUM" : "NOT PREMIUM"));
 

Step 13 launchPurchaseFlwo() method

Purchase flow call onClick event of button or view. Simple one time purchase call

mHelper.launchPurchaseFlow(this, SKU_GAS, RC_REQUEST,
                mPurchaseFinishedListener, payload);

Subscribe flow call onClick event of button or view for subscribe. Subscribe flow

  mHelper.launchPurchaseFlow(this,
                SKU_INFINITE_GAS, IabHelper.ITEM_TYPE_SUBS,
                RC_REQUEST, mPurchaseFinishedListener, payload);

Purchase flow call onClick event of button or view. Multiple time purchase call

mHelper.launchPurchaseFlow(this, SKU_GAS, RC_REQUEST,
                mPurchaseFinishedListener, payload);

Along with the in finish listener with following code

if (purchase.getSku().equals(SKU_GAS)) {
                // bought 1/4 tank of gas. So consume it.
                Log.d(TAG, "Purchase is gas. Starting gas consumption.");
                mHelper.consumeAsync(purchase, mConsumeFinishedListener);
            }
 

Step 14 OnlabPurchaseFinishedLisenter

With OnIabPurchaseFinishedListener do whatever you want when purchase finish successfully or unsuccessfully.

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
            Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
 
            // if we were disposed of in the meantime, quit.
            if (mHelper == null) return;
 
            if (result.isFailure()) {
                complain("Error purchasing: " + result);
                setWaitScreen(false);
                return;
            }
            if (!verifyDeveloperPayload(purchase)) {
                complain("Error purchasing. Authenticity verification failed.");
                setWaitScreen(false);
                return;
            }
 
            Log.d(TAG, "Purchase successful.");
 
            if (purchase.getSku().equals(SKU_GAS)) {
                // bought 1/4 tank of gas. So consume it.
                Log.d(TAG, "Purchase is gas. Starting gas consumption.");
                mHelper.consumeAsync(purchase, mConsumeFinishedListener);
            }
            else if (purchase.getSku().equals(SKU_PREMIUM)) {
                // bought the premium upgrade!
                Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
                alert("Thank you for upgrading to premium!");
                mIsPremium = true;
                updateUi();
                setWaitScreen(false);
            }
            else if (purchase.getSku().equals(SKU_INFINITE_GAS)) {
                // bought the infinite gas subscription
                Log.d(TAG, "Infinite gas subscription purchased.");
                alert("Thank you for subscribing to infinite gas!");
                mSubscribedToInfiniteGas = true;
                mTank = TANK_MAX;
                updateUi();
                setWaitScreen(false);
            }
        }
    };
 

Step 15 OnConsumerFinishedLisetener

OnConsumeFinishedListener for multiple time buy same item.

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
        public void onConsumeFinished(Purchase purchase, IabResult result) {
            Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
 
            // if we were disposed of in the meantime, quit.
            if (mHelper == null) return;
 
            // We know this is the "gas" sku because it's the only one we consume,
            // so we don't check which sku was consumed. If you have more than one
            // sku, you probably should check...
            if (result.isSuccess()) {
                // successfully consumed, so we apply the effects of the item in our
                // game world's logic, which in our case means filling the gas tank a bit
                Log.d(TAG, "Consumption successful. Provisioning.");
                mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
                saveData();
                alert("You filled 1/4 tank. Your tank is now " + String.valueOf(mTank) + "/4 full!");
            }
            else {
                complain("Error while consuming: " + result);
            }
            updateUi();
            setWaitScreen(false);
            Log.d(TAG, "End consumption flow.");
        }
    };
 

Step 16 VerifyDeveloperPayload() method

Verify payload of the purchase flow

boolean verifyDeveloperPayload(Purchase p) {
        String payload = p.getDeveloperPayload();
 
        /*
         * TODO: verify that the developer payload of the purchase is correct. It will be
         * the same one that you sent when initiating the purchase.
         *
         * WARNING: Locally generating a random string when starting a purchase and
         * verifying it here might seem like a good approach, but this will fail in the
         * case where the user purchases an item on one device and then uses your app on
         * a different device, because on the other device you will not have access to the
         * random string you originally generated.
         *
         * So a good developer payload has these characteristics:
         *
         * 1. If two different users purchase an item, the payload is different between them,
         *    so that one user's purchase can't be replayed to another user.
         *
         * 2. The payload must be such that you can verify it even when the app wasn't the
         *    one who initiated the purchase flow (so that items purchased by the user on
         *    one device work on other devices owned by the user).
         *
         * Using your own server to store and verify developer payloads across app
         * installations is recommended.
         */
 
        return true;
    }
 

Step 17 Get result of IAPHandler

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mHelper != null
&& !mHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
}
}

I hope you found this blog helpful while Implementing In-App Purchase Version 3 in Android. Let me know if you have any questions or concerns regarding Android, please put a comment here and we will get back to you ASAP.

Learning Android sounds fun, right? Why not check out our other Android Tutorials?

Got an Idea of Android App Development? What are you still waiting for? Contact us now and see the Idea live soon. Our company has been named as one of the Best Android App Development Company in India.

I am professional Android application developer with experience of 2 years in Android Application Development. I worked with so many technology but android is the only one which interests me.