From 768dba6d8cd6ad56fb6d4e7e30b3260e0d5e0ffd Mon Sep 17 00:00:00 2001
From: Quddus Chong In this class, you'll learn how to perform common In-app Billing operations from Android applications. In-app billing is a service hosted on Google Play that lets you charge for digital content or for upgrades in your app. The In-app Billing API makes it easy for you to integrate In-app Billing into your applications. You can request product details from Google Play, issue orders for in-app products, and quickly retrieve ownership information based on users' purchase history. You can also query the Google Play service for details about in-app products, such as local pricing and availability. Google Play provides a checkout interface that makes user interactions with the In-app Billing service seamless, and provides a more intuitive experience to your users. This class describes how to get started with the Version 3 API. To learn how to use the version 2 API, see Implementing In-App Billing (V2). Before publishing your In-app Billing application, you'll need to define the product list of digital goods available for purchase in the Google Play Developer Console. From the Developer Console, you can define product information for in-app products and associate the product list with your application. To add new in-app products to your product list: Important: The In-app Billing Version 3 service only supports managed in-app products, so make sure that you specify that the purchase type is 'Managed' when you add new items to your product list in the Developer Console. Warning: It may take up to 2-3 hours after uploading the APK for Google Play to recognize your updated APK version. If you try to test your application before your uploaded APK is recognized by Google Play, your application will receive a ‘purchase cancelled’ response with an error message “This version of the application is not enabled for In-app Billing.” You can query Google Play to programmatically retrieve details of the in-app products that are associated with your application (such as the product’s price, title, description, and type). This is useful, for example, when you want to display a listing of unowned items that are still available for purchase to users. Note: When making the query, you will need to specify the product IDs for the products explicitly. You can manually find the product IDs from the Developer Console by opening the In-app Products tab for your application. The product IDs are listed under the column labeled Name/ID. To retrieve the product details, call {@code queryInventoryAsync(boolean, List, QueryInventoryFinishedListener)} on your IabHelper instance.
+Dependencies and prerequisites
+
+
+
+You Should Also Read
+
+
+Lessons
+
+
+
+
+
diff --git a/docs/html/training/in-app-billing/list-iab-products.jd b/docs/html/training/in-app-billing/list-iab-products.jd
new file mode 100644
index 0000000..36ff34a
--- /dev/null
+++ b/docs/html/training/in-app-billing/list-iab-products.jd
@@ -0,0 +1,91 @@
+page.title=Establishing In-app Billing Products for Sale
+parent.title=Selling In-app Products
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Preparing Your In-app Billing Application
+previous.link=preparing-iab-app.html
+next.title=Purchasing In-app Billing Products
+next.link=purchase-iab-products.html
+
+@jd:body
+
+This lesson teaches you to
+
+
+You should also read
+
+
+
+Specify In-app Products in Google Play
+
+
+
+Query Items Available for Purchase
+
+
+If you use the the convenience classes provided in the sample, the classes will handle background thread management for In-app Billing requests, so you can safely make queries from the main thread of your application.
+
The following code shows how you can retrieve the details for two products with IDs {@code SKU_APPLE} and {@code SKU_BANANA} that you previously defined in the Developer Console.
+ ++List+ +additionalSkuList = new List (); +additionalSkuList.add(SKU_APPLE); +additionalSkuList.add(SKU_BANANA); +mHelper.queryInventoryAsync(true, additionalSkuList, + mQueryFinishedListener); +
If the query is successful, the query results are stored in an {@code Inventory} object that is passed back to the listener.
+The following code shows how you can retrieve the item prices from the result set.
+ ++IabHelper.QueryInventoryFinishedListener + mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() { + public void onQueryInventoryFinished(IabResult result, Inventory inventory) + { + if (result.isFailure()) { + // handle error + return; + } + + String applePrice = + inventory.getSkuDetails(SKU_APPLE).getPrice(); + String bananaPrice = + inventory.getSkuDetails(SKU_BANANA).getPrice(); + + // update the UI + } +} ++ diff --git a/docs/html/training/in-app-billing/preparing-iab-app.jd b/docs/html/training/in-app-billing/preparing-iab-app.jd new file mode 100644 index 0000000..ab33ccc --- /dev/null +++ b/docs/html/training/in-app-billing/preparing-iab-app.jd @@ -0,0 +1,144 @@ +page.title=Preparing Your In-app Billing Application +parent.title=Selling In-app Products +parent.link=index.html + +trainingnavtop=true +next.title=Establishing In-app Billing Products for Sale +next.link=list-iab-products.html + +@jd:body + + +
Before you can start using the In-app Billing service, you'll need to add the library that contains the In-app Billing Version 3 API to your Android project. You also need to setting the permissions for your application to communicate with Google Play. In addition, you'll need to establish a connection between your application and Google Play. You should also verify that the In-app Billing API version that you are using in your application is supported by Google Play.
+ +In this training class, you will use a reference implementation for the In-app Billing Version 3 API called the {@code TrivialDrive} sample application. The sample includes convenience classes to quickly set up the In-app Billing service, marshal and unmarshal data types, and handle In-app Billing requests from the main thread of your application.
+To download the sample application:
+The sample files will be installed to {@code /your/sdk/location/extras/google/play_billing/in-app-billing-v03}.
+ +The Google Play Developer Console is where you publish your In-app Billing application and manage the various digital goods that are available for purchase from your application. When you create a new application entry in the Developer Console, it automatically generates a public license key for your application. You will need this key to establish a trusted connection from your application to the Google Play servers. You only need to generate this key once per application, and don’t need to repeat these steps when you update the APK file for your application.
+To add your application to the Developer Console:
+Your application should now appear in the list of applications in Developer Console.
+ +To use the In-app Billing Version 3 features, you must add the {@code IInAppBillingService.aidl} file to your Android project. This Android Interface Definition Language (AIDL) file defines the interface to the Google Play service.
+You can find the {@code IInAppBillingService.aidl} file in the provided sample app. Depending on whether you are creating a new application or modifying an existing application, follow the instructions below to add the In-app Billing Library to your project.
+To add the In-app Billing Version 3 library to your new In-app Billing project:
+To add the In-app Billing Version 3 library to your existing In-app Billing project:
+Your project should now contain the In-app Billing Version 3 library.
+ +Your app needs to have permission to communicate request and response messages to the Google Play’s billing service. To give your app the necessary permission, add this line in your {@code AndroidManifest.xml} manifest file:
++<uses-permission android:name="com.android.vending.BILLING" /> ++ +
You must bind your Activity to Google Play’s In-app Billing service to send In-app Billing requests to Google Play from your application. The convenience classes provided in the sample handles the binding to the In-app Billing service, so you don’t have to manage the network connection directly.
+To set up synchronous communication with Google Play, create an {@code IabHelper} instance in your activity's {@code onCreate} method. In the constructor, pass in the {@code Context} for the activity, along with a string containing the public license key that was generated earlier by the Google Play Developer Console.
+Security Recommendation: It is highly recommended that you do not hard-code the exact public license key string value as provided by Google Play. Instead, you can construct the whole public license key string at runtime from substrings, or retrieve it from an encrypted store, before passing it to the constructor. This approach makes it more difficult for malicious third-parties to modify the public license key string in your APK file.
+ ++IabHelper mHelper; + +@Override +public void onCreate(Bundle savedInstanceState) { + // ... + String base64EncodedPublicKey; + + // compute your public key and store it in base64EncodedPublicKey + mHelper = new IabHelper(this, base64EncodedPublicKey); +} ++ +
Next, perform the service binding by calling the {@code startSetup} method on the {@code IabHelper} instance that you created. Pass the method an {@code OnIabSetupFinishedListener} instance, which is called once the {@code IabHelper} completes the asynchronous setup operation. As part of the setup process, the {@code IabHelper} also checks if the In-app Billing Version 3 API is supported by Google Play. If the API version is not supported, or if an error occured while establishing the service binding, the listener is notified and passed an {@code IabResult} object with the error message.
+ ++mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { + public void onIabSetupFinished(IabResult result) { + if (!result.isSuccess()) { + // Oh noes, there was a problem. + Log.d(TAG, "Problem setting up In-app Billing: " + result); + } + // Hooray, IAB is fully set up! + } +}); ++ +
If the setup completed successfully, you can now use the {@code mHelper} reference to communicate with the Google Play service. When your application is launched, it is a good practice to query Google Play to find out what in-app items are owned by a user. This is covered further in the Query Purchased Items section.
+ +Important: Remember to unbind from the In-app Billing service when you are done with your activity. If you don’t unbind, the open service connection could cause your device’s performance to degrade. To unbind and free your system resources, call the {@code IabHelper}'s {@code dispose} method when your {@code Activity} gets destroyed.
+ ++@Override +public void onDestroy() { + if (mHelper != null) mHelper.dispose(); + mHelper = null; +} ++ + + + + diff --git a/docs/html/training/in-app-billing/purchase-iab-products.jd b/docs/html/training/in-app-billing/purchase-iab-products.jd new file mode 100644 index 0000000..d5f6634 --- /dev/null +++ b/docs/html/training/in-app-billing/purchase-iab-products.jd @@ -0,0 +1,138 @@ +page.title=Purchasing In-app Billing Products +parent.title=Selling In-app Products +parent.link=index.html + +trainingnavtop=true +previous.title=Establishing In-app Billing Products for Sale +previous.link=list-iab-products.html +next.title=Testing Your In-app Billing Application +next.link=test-iab-app.html + +@jd:body + +
Once your application is connected to Google Play, you can initiate purchase requests for in-app products. Google Play provides a checkout interface for users to enter their payment method, so your application does not need to handle payment transactions directly.
+When an item is purchased, Google Play recognizes that the user has ownership of that item and prevents the user from purchasing another item with the same product ID until it is consumed. You can control how the item is consumed in your application, and notify Google Play to make the item available for purchase again.
+You can also query Google Play to quickly retrieve the list of purchases that were made by the user. This is useful, for example, when you want to restore the user's purchases when your user launches your app.
+ +To start a purchase request from your app, call {@code launchPurchaseFlow(Activity, String, int, OnIabPurchaseFinishedListener, String)} on your {@code IabHelper} instance. You must make this call from the main thread of your {@code Activity}. Here’s an explaination of the {@code launchPurchaseFlow} method parameters:
+Security Recommendation: It’s good practice to pass in a string that helps your application to identify the user who made the purchase, so that you can later verify that this is a legitimate purchase by that user. For consumable items, you can use a randomly generated string, but for non-consumable items you should use a string that uniquely identifies the user.
The following example shows how you can make a purchase request for a product with ID {@code SKU_GAS}, using an arbitrary value of 10001 for the request code, and an encoded developer payload string.
+ ++mHelper.launchPurchaseFlow(this, SKU_GAS, 10001, + mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ"); ++ +
If the purchase order is successful, the response data from Google Play is stored in an {@code Purchase} object that is passed back to the listener.
+ +The following example shows how you can handle the purchase response in the listener, depending on whether the purchase order was completed successfully, and whether the user purchased gas or a premium upgrade. In this example, gas is an in-app product that can be purchased multiple times, so you should consume the purchase to allow the user to buy it again. To learn how to consume purchases, see the Consuming Products section. The premium upgrade is a one-time purchase so you don’t need to consume it. It is good practice to update the UI immediately so that your users can see their newly purchased items.
+ ++IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener + = new IabHelper.OnIabPurchaseFinishedListener() { + public void onIabPurchaseFinished(IabResult result, Purchase purchase) + { + if (result.isFailure()) { + Log.d(TAG, "Error purchasing: " + result); + return; + } + else if (purchase.getSku().equals(SKU_GAS)) { + // consume the gas and update the UI + } + else (purchase.getSku().equals(SKU_PREMIUM)) { + // give user access to premium content and update the UI + } + } +}; ++ +
Security Recommendation: When you receive the purchase response from Google Play, make sure to check the returned data signature, the {@code orderId}, and the {@code developerPayload} string in the {@code Purchase} object to make sure that you are getting the expected values. You should verify that the {@code orderId} is a unique value that you have not previously processed, and the {@code developerPayload} string matches the token that you sent previously with the purchase request. As a further security precaution, you should perform the verification on your own secure server.
+ +Upon a successful purchase, the user’s purchase data is cached locally by Google Play’s In-app Billing service. It is good practice to frequently query the In-app Billing service for the user’s purchases, for example whenever the app starts up or resumes, so that the user’s current in-app product ownership information is always reflected in your app.
+ +To retrieve the user’s purchases from your app, call {@code queryInventoryAsync(QueryInventoryFinishedListener)} on your {@code IabHelper} instance. The {@code QueryInventoryFinishedListener} argument specifies a listener that is notified when the query operation has completed and handles the query response. It is safe to make this call fom your main thread.
+ ++mHelper.queryInventoryAsync(mGotInventoryListener); ++ +
If the query is successful, the query results are stored in an {@code Inventory} object that is passed back to the listener. The In-app Billing service returns only the purchases made by the user account that is currently logged in to the device.
+ ++IabHelper.QueryInventoryFinishedListener mGotInventoryListener + = new IabHelper.QueryInventoryFinishedListener() { + public void onQueryInventoryFinished(IabResult result, + Inventory inventory) { + + if (result.isFailure()) { + // handle error here + } + else { + // does the user have the premium upgrade? + mIsPremium = inventory.hasPurchase(SKU_PREMIUM); + // update UI accordingly + } + } +}; ++ +
You can use the In-app Billing Version 3 API to track the ownership of purchased items in Google Play. Once an item is purchased, it is considered to be "owned" and cannot be purchased again from Google Play while in that state. You must send a consumption request for the item before Google Play makes it available for purchase again. All managed in-app products are consumable. How you use the consumption mechanism in your app is up to you. Typically, you would implement consumption for products with temporary benefits that users may want to purchase multiple times (for example, in-game currency or replensihable game tokens). You would typically not want to implement consumption for products that are purchased once and provide a permanent effect (for example, a premium upgrade).
+It's 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.
+Security Recommendation: You must send a consumption request before provisioning the benefit of the consumable in-app purchase to the user. Make sure that you have received a successful consumption response from Google Play before you provision the item.
+To record a purchase consumption, call {@code consumeAsync(Purchase, OnConsumeFinishedListener)} on your {@code IabHelper} instance. The first argument that the method takes is the {@code Purchase} object representing the item to consume. The second argument is a {@code OnConsumeFinishedListener} that is notified when the consumption operation has completed and handles the consumption response from Google Play. It is safe to make this call fom your main thread.
+In this example, you want to consume the gas item that the user has previously purchased in your app.
+ ++mHelper.consumeAsync(inventory.getPurchase(SKU_GAS), + mConsumeFinishedListener); ++ +
The following example shows how to implement the {@code OnConsumeFinishedListener}.
+ ++IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = + new IabHelper.OnConsumeFinishedListener() { + public void onConsumeFinished(Purchase purchase, IabResult result) { + if (result.isSuccess()) { + // provision the in-app purchase to the user + // (for example, credit 50 gold coins to player's character) + } + else { + // handle error + } + } +}; ++ +
It’s important to check for consumable items when the user starts up your application. Typically, you would first query the In-app Billing service for the items purchased by the user (via {@code queryInventoryAsync}), then get the consumable {@code Purchase} objects from the Inventory. If your application detects that are any consumable items that are owned by the user, you should send a consumption request to Google Play immediately and provision the item to the user. See the {@code TrivialDrive} sample for an example of how to implement this checking at startup.
+ + diff --git a/docs/html/training/in-app-billing/test-iab-app.jd b/docs/html/training/in-app-billing/test-iab-app.jd new file mode 100644 index 0000000..376b981 --- /dev/null +++ b/docs/html/training/in-app-billing/test-iab-app.jd @@ -0,0 +1,56 @@ +page.title=Testing Your In-app Billing Application +parent.title=Selling In-app Products +parent.link=index.html + +trainingnavtop=true +previous.title=Purchasing In-app Billing Products +previous.link=purchase-iab-products.html + +@jd:body + +To ensure that In-app Billing is functioning correctly in your application, you should test the test the application before you publish it on Google Play. Early testing also helps to ensure that the user flow for purchasing in-app items is not confusing or slow, and that users can see their newly purchased items in a timely way.
+ +Because Google Play does not allow you to use your developer account to directly purchase in-app products that you have created yourself, you'll need to create test acccounts under your developer account profile. To create a test account, simply enter a valid Google email address. Users with these test accounts will then be able to make in-app-billing purchases from uploaded, unpublished applications that you manage.
+To test your In-app Billing Version 3 application using your own product IDs: +
Warning: It may take up to 2-3 hours after uploading the APK for Google Play to recognize your updated APK version. If you try to test your application before your uploaded APK is recognized by Google Play, your application will receive a ‘purchase cancelled’ response with an error message “This version of the application is not enabled for In-app Billing.”