Monday, June 20, 2011

In-app-billing for Android? Looks like a PITA

In an attempt to actually make some money off this crazy app I've developed, I decided to make the first 100 words and audio files free, then the next ones for like $6.99. That's only for levels 4 and 5. For the other levels, you just get the words. I might or might not change the price for that.

So, where to start. The Google site looks *boring*. And long.

But, let's break it down.

http://developer.android.com/guide/market/billing/index.html

Topics

Overview of In-app Billing
Implementing In-app Billing
Security and Design
Testing In-app Billing
Administering In-app Billing

Reference

In-app Billing Reference

Downloads

Sample Application



Android Market In-app Billing is an Android Market service that lets you sell digital content in your applications. You can use the service to sell a wide range of content, including downloadable content such as media files or photos, and virtual content such as game levels or potions.

When you use Android Market's in-app billing service to sell an item, Android Market handles all checkout details so your application never has to directly process any financial transactions. Android Market uses the same checkout service that is used for application purchases, so your users experience a consistent and familiar purchase flow (see figure 1). Also, the transaction fee for in-app purchases is the same as the transaction fee for application purchases (30%).


Any application that you publish through Android Market can implement in-app billing. No special account or registration is required other than an

Android Market publisher account and a

Google Checkout Merchant account.

Also, because the service uses no dedicated framework APIs, you can add in-app billing to any application that uses a minimum API level of 4 or higher.

To help you integrate in-app billing into your application, the Android SDK provides a sample application that demonstrates a simple implementation of in-app billing.

// ok, that's good

The sample application contains examples of billing-related classes you can use to implement in-app billing in your application. It also contains examples of the database, user interface, and business logic you might use to implement in-app billing.

// ok.






Figure 1. Applications initiate in-app billing requests through their own UI (first screen). Android Market responds to the request by providing the checkout user interface (middle screen). When checkout is complete, the application resumes.



Important: Although the sample application is a working example of how you can implement in-app billing, we strongly recommend that you modify and obfuscate the sample code before you use it in a production application. For more information, see Security and Design.

// Obfuscate? So yo can decompile this dex stuff, huh.



To learn more about Android Market's in-app billing service and start integrating it into your applications, read the following documents:


To learn more about Android Market's in-app billing service and start integrating it into your applications, read the following documents:

Overview of In-app Billing
Learn how the service works and what a typical in-app billing implementation looks like.
Implementing In-app Billing
Use this step-by-step guide to start incorporating in-app billing into your application.
Security and Design
Review these best practices to help ensure that your in-app billing implementation is secure and well designed.
Testing In-app Billing
Understand how the in-app billing test tools work and learn how to test your in-app billing implementation.
Administering In-app Billing
Learn how to set up your product list, register test accounts, and handle refunds.
In-app Billing Reference
Get detailed information about Android Market response codes and the in-app billing interface.

http://developer.android.com/guide/market/billing/billing_overview.html


In-app Billing Overview
In this document
In-app Billing Architecture
In-app Billing Messages
Request messages
Broadcast intents
Messaging sequence
Handling IN_APP_NOTIFY messages
Security Controls
Requirements and Limitations
Downloads
Sample Application

See also

Implementing In-app Billing
Security and Design
Testing In-app Billing
Administering In-app Billing
In-app Billing Reference

Wow. There's a lot of ground to cover. doh! Here we go.


Android Market In-app Billing is an Android Market service that provides checkout processing for in-app purchases.

To use the service, your application sends a billing request for a specific in-app product.

The service then handles all of the checkout details for the transaction, including requesting and validating the form of payment and processing the financial transaction.

When the checkout process is complete, the service sends your application the purchase details, such as the order number, the order date and time, and the price paid.

At no point does your application have to handle any financial transactions; that role is provided by Android Market's in-app billing service.


// Ok. So far, so good.

In-app Billing Architecture

In-app billing uses an asynchronous message loop to convey billing requests and billing responses between your application and the Android Market server.

In practice, your application never directly communicates with the Android Market server (see figure 1).

Instead, your application sends billing requests to the Android Market application over interprocess communication (IPC) and receives purchase responses from the Android Market application in the form of asynchronous broadcast intents.

Your application does not manage any network connections between itself and the Android Market server or use any special APIs from the Android platform.

Some in-app billing implementations may also use a private remote server to deliver content or validate transactions, but a remote server is not required to implement in-app billing.

A remote server can be useful if you are selling digital content that needs to be delivered to a user's device, such as media files or photos.

// That's me.

You might also use a remote server to store users' transaction history or perform various in-app billing security tasks, such as signature verification.

// I hate anything to do with signatures.

Although you can handle all security-related tasks in your application, performing those tasks on a remote server is recommended because it helps make your application less vulnerable to security attacks.

// Whatever.

A typical in-app billing implementation relies on three components:

A Service (named BillingService in the sample application), which processes purchase messages from the application and sends billing requests to Android Market's in-app billing service.



A BroadcastReceiver (named BillingReceiver in the sample application), which receives all asynchronous billing responses from the Android Market application

.
A security component (named Security in the sample application), which performs security-related tasks, such as signature verification and nonce generation. For more information about in-app billing security, see Security controls later in this document.


You may also want to incorporate two other components to support in-app billing:

// There's always more.

A response Handler (named ResponseHandler in the sample application), which provides application-specific processing of purchase notifications, errors, and other status messages.

// I could use this to enable the rest of the words to be displayed.

An observer (named PurchaseObserver in the sample application), which is responsible for sending callbacks to your application so you can update your user interface with purchase information and status.

// Right. What's the diference between that and the Response handler?


Figure 1. Your application sends and receives billing messages through the Android Market application, which handles all communication with the Android Market server.


In addition to these components, your application must provide a way to store information about users' purchases and some sort of user interface that lets users select items to purchase.

// Yarghh! I just want a link like paypal. give me a break.

You do not need to provide a checkout user interface. When a user initiates an in-app purchase, the Android Market application presents the checkout user interface to your user. When the user completes the checkout process, your application resumes.

In-app Billing Messages

When the user initiates a purchase, your application sends billing messages to Android Market's in-app billing service (named MarketBillingService) using simple IPC method calls.

//k

The Android Market application responds to all billing requests synchronously, providing your application with status notifications and other information.

// great.

The Android Market application also responds to some billing requests asynchronously, providing your application with error messages and detailed transaction information.

// alright.

The following section describes the basic request-response messaging that takes place between your application and the Android Market application.

// ok.

In-app billing requests

Your application sends in-app billing requests by invoking a single IPC method

(sendBillingRequest()),

which is exposed by the MarketBillingService interface.

This interface is defined in an Android Interface Definition Language file (IMarketBillingService.aidl).

// ok

You can download this AIDL file with the in-app billing sample application.

// ok

The sendBillingRequest() method has a single Bundle parameter.

The Bundle that you deliver must include several key-value pairs that specify various parameters for the request, such as

the type of billing request you are making,

the item that is being purchased,

and the application that is making the request.


For more information about the Bundle keys that are sent with a request, see In-app Billing Service Interface.

// sure.

One of the most important keys that every request Bundle must have is the BILLING_REQUEST key.

// Ok.

This key lets you specify the type of billing request you are making.

Android Market's in-app billing service supports the following five types of billing requests:

CHECK_BILLING_SUPPORTED

This request verifies that the Android Market application supports in-app billing.

You usually send this request when your application first starts up.


This request is useful if you want to enable or disable certain UI features that are relevant only to in-app billing.

// ok. What if they're not connected? I could use my own current logic.

REQUEST_PURCHASE

This request sends a purchase message to the Android Market application and is the foundation of in-app billing.

You send this request when a user indicates that he or she wants to purchase an item in your application.

Android Market then handles the financial transaction by displaying the checkout user interface.

// The interface get's displayed.

GET_PURCHASE_INFORMATION

This request retrieves the details of a purchase state change.

A purchase changes state when a requested purchase is billed successfully or when a user cancels a transaction during checkout.

//k

It can also occur when a previous purchase is refunded.

//k

Android Market notifies your application when a purchase changes state, so you only need to send this request when there is transaction information to retrieve.

//k. I guess I have to watch for that.

CONFIRM_NOTIFICATIONS

This request acknowledges that your application received the details of a purchase state change.

// ok, I have to send something back.

Android Market sends purchase state change notifications to your application until you confirm that you received them.

// ok. I should make sure to implement this.

RESTORE_TRANSACTIONS

This request retrieves a user's transaction status for managed purchases.


You should send this request only when you need to retrieve a user's transaction status, which is usually only when your application is reinstalled or installed for the first time on a device.


// What's the difference between this and CHECK PURCHASE TRANSACTIONS?

In-app Billing Responses

The Android Market application responds to in-app billing requests with both synchronous and asynchronous responses. The synchronous response is a Bundle with the following three keys:

RESPONSE_CODE

This key provides status information and error information about a request.

// ok

PURCHASE_INTENT

This key provides a PendingIntent, which you use to launch the checkout activity.

// Ok - so when I get this, I launch the checkout activity. Ok.


REQUEST_ID

This key provides you with a request identifier, which you can use to match asynchronous responses with requests.

// ok

Some of these keys are not relevant to every request. For more information, see Messaging sequence later in this document.


The asynchronous response messages are sent in the form of individual broadcast intents and include the following:

com.android.vending.billing.RESPONSE_CODE

This response contains an Android Market server response code, and is sent after you make an in-app billing request. A server response code can indicate that a billing request was successfully sent to Android Market or it can indicate that some error occurred during a billing request.

// what the diff betw. this and the regular response code?


This response is not used to report any purchase state changes (such as refund or purchase information). For more information about the response codes that are sent with this response, see Server Response Codes for In-app Billing.



com.android.vending.billing.IN_APP_NOTIFY

This response indicates that a purchase has changed state, which means a purchase succeeded, was canceled, or was refunded.

// wasn't this also covered somewhere? It was talked about.

This response contains one or more notification IDs.

// ok this was where you had to send something to acknowledge you got the notification.

Each notification ID corresponds to a specific server-side message, and each messages contains information about one or more transactions.

After your application receives an IN_APP_NOTIFY broadcast intent, you send a GET_PURCHASE_INFORMATION request with the notification IDs to retrieve message details.

// So, I have to act on it?


com.android.vending.billing.PURCHASE_STATE_CHANGED

This response contains detailed information about one or more transactions.

The transaction information is contained in a JSON string.

The JSON string is signed and the signature is sent to your application along with the JSON string (unencrypted).

To help ensure the security of your in-app billing messages, your application can verify the signature of this JSON string.

The JSON string that is returned with the PURCHASE_STATE_CHANGED intent provides your application with the details of one or more billing transactions. An example of this JSON string is shown below:

{ "nonce" : 1836535032137741465,
"orders" :
{ "notificationId" : "android.test.purchased",
"orderId" : "transactionId.android.test.purchased",
"packageName" : "com.example.dungeons",
"productId" : "android.test.purchased",
"developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
"purchaseTime" : 1290114783411,
"purchaseState" : 0 }
}

For more information about the fields in this JSON string, see In-app Billing Broadcast Intents.


// Could the make this thing more complex?

Messaging sequence

The messaging sequence for a typical purchase request is shown in figure 2. Request types for each sendBillingRequest() method are shown in bold, broadcast intents are shown in italic. For clarity, figure 2 does not show the RESPONSE_CODE broadcast intents that are sent for every request.

The basic message sequence for an in-app purchase request is as follows:

Your application sends a purchase request (REQUEST_PURCHASE type), specifying a product ID and other parameters.
// ok

The Android Market application sends your application a Bundle with the following keys: RESPONSE_CODE, PURCHASE_INTENT, and REQUEST_ID.

// ok

The PURCHASE_INTENT key provides a PendingIntent,

which your application uses to start the checkout UI for the given product ID.

Your application launches the pending intent, which launches the checkout UI.

// ok

When the checkout flow finishes (that is, the user successfully purchases the item or cancels the purchase), Android Market sends your application a notification message (an IN_APP_NOTIFY broadcast intent).

// ok

The notification message includes a notification ID, which references the transaction.

// ok - how?


Your application requests the transaction information by sending a GET_PURCHASE_STATE_CHANGED request, specifying the notification ID for the transaction.

// it just sent me a notice to request a notice. Why not just send it?


The Android Market application sends a Bundle with a RESPONSE_CODE key and a REQUEST_ID key.

// Ok. Are we done?

Android Market sends the transaction information to your application in a PURCHASE_STATE_CHANGED broadcast intent.

// Ok... I couldn't have got that originally?

Your application confirms that you received the transaction information for the given notification ID by sending a confirmation message (CONFIRM_NOTIFICATIONS type), specifying the notification ID for which you received transaction information.

// Ok - now is it done?

The Android Market application sends your application a Bundle with a RESPONSE_CODE key and a REQUEST_ID key.

Note: You must launch the pending intent from an activity context and not an application context.
// Is that part of the PURCHASE_STATE_CHANGED?



Figure 2. Message sequence for a purchase request.


// Wow, that's complicated.

Ok. I really need to get feedback on the app. The best way to do this is to get it out on the marketplace. I can introduce in-ap-billing if the interest supports it. For now, I'm just going to provide a link to the full product. We'll see what that entails.

No comments:

Post a Comment