Going to try and walk you through creating an inapp payment method with the new android market payment system. This isn’t live yet (you can’t publish the app for general use) but you can upload it to the market and do full testing.

Ok first the outline.

Were going to create and app that has one button, when you click this button it informs the android market you want to make a purchase. On confirmation of this purchase you have bought a picture of a passport and it is shown to you in the app.

There is an AIDL file that you have to include your project, this gives you access to the Remote Methods of the Android Market service. Don’t worry about this, just know that this is what is under the com.android.vending.billing package in the test project.

InApp Billing in android basically means:
Tell the Android Market what the user is buying In the test project it is “android.test.purchase”
The Android Market compares this against a list you create (on your publisher page) [url=Testing]http://developer.android.com/guide/market/billing/billing_testing.html[/url]
User fills in their details You dont have to worry about this
You receive a message saying purchase complete or failed.

In order to tell the Android Market what you are buying you need to be running the billing service. ( A service that talks between your app and the android market) This looks like:

When a request to the android market from your BillingHelper is instantiated, the market sends back certain intent’s these need to be caught in a receiver and dealt with appropriately (so the market will say “yes I confirm this user has just bought…” ):

To keep the code a bit tidier all constants are stored in a class called C:

package com.blundell.test;
public class C {
// The response codes for a request, defined by Android Market.
public enum ResponseCode {
RESULT_OK,
RESULT_USER_CANCELED,
RESULT_SERVICE_UNAVAILABLE,
RESULT_BILLING_UNAVAILABLE,
RESULT_ITEM_UNAVAILABLE,
RESULT_DEVELOPER_ERROR,
RESULT_ERROR;
// Converts from an ordinal value to the ResponseCode
public static ResponseCode valueOf(int index) {
ResponseCode[] values = ResponseCode.values();
if (index < 0 || index >= values.length) {
return RESULT_ERROR;
}
return values[index];
}
}
// The possible states of an in-app purchase, as defined by Android Market.
public enum PurchaseState {
// Responses to requestPurchase or restoreTransactions.
PURCHASED, // User was charged for the order.
CANCELED, // The charge failed on the server.
REFUNDED; // User received a refund for the order.
// Converts from an ordinal value to the PurchaseState
public static PurchaseState valueOf(int index) {
PurchaseState[] values = PurchaseState.values();
if (index < 0 || index >= values.length) {
return CANCELED;
}
return values[index];
}
}
// These are the names of the extras that are passed in an intent from
// Market to this application and cannot be changed.
public static final String NOTIFICATION_ID = "notification_id";
public static final String INAPP_SIGNED_DATA = "inapp_signed_data";
public static final String INAPP_SIGNATURE = "inapp_signature";
public static final String INAPP_REQUEST_ID = "request_id";
public static final String INAPP_RESPONSE_CODE = "response_code";
// Intent actions that we send from the BillingReceiver to the
// BillingService. Defined by this application.
public static final String ACTION_CONFIRM_NOTIFICATION = "com.example.dungeons.CONFIRM_NOTIFICATION";
public static final String ACTION_GET_PURCHASE_INFORMATION = "com.example.dungeons.GET_PURCHASE_INFORMATION";
public static final String ACTION_RESTORE_TRANSACTIONS = "com.example.dungeons.RESTORE_TRANSACTIONS";
// Intent actions that we receive in the BillingReceiver from Market.
// These are defined by Market and cannot be changed.
public static final String ACTION_NOTIFY = "com.android.vending.billing.IN_APP_NOTIFY";
public static final String ACTION_RESPONSE_CODE = "com.android.vending.billing.RESPONSE_CODE";
public static final String ACTION_PURCHASE_STATE_CHANGED = "com.android.vending.billing.PURCHASE_STATE_CHANGED";
}

And finally, this code I took from the Android sample project. What it does is decrypt the messages that the Android Market is sending back to you and package them into a purchased item object. YOU NEED TO EDIT ONE LINE, to add your public key from your market account (edit profile):

This code tutorial isn’t foolproof and I feel I may of swept over a few things. But I really want to just give an alternative to the tutorial that is on the developer.android site. You could read this and understand the smaller concepts then go on to make a better implementation.

I’ve created a sample project with this code.
For android.test.purchased- it is working fine.
But when i used myown product Id and public key(i’ve uploaded my app in drafts)
then im getting an error message in the pop up as “The item you were attempting to purchase could not found” Y i’m getting this error??My App is not published and the product id is in activated state.

I love the tutorial. Thank you for posting it. Im making a flash game using “adobe flash pro cc ” and would like to implement in-app purchase that is consumable such as “speed boost” that would last for only one game when you use it. My question is would this tutorial work for games that are made in flash pro? What program do others use to make android games? What program would work with this tutorial? I dont know much about this topic. I need your help.

I am new in android field. I want to attach the inapp api with restore transaction for only managed product. Can anyone help me to send the sample complete code. Thanks in advance. My email id is- mail2dibyendu@rediffmail.com

Hi there, love the tutorial. Im new to android and have struggled to grasp the concept of in app billing however have found this one alot more user friendly. So i have a silly question. Can i use this code for my app? not sure the legal issues are if i do. Regards Charlie =)

Hi everybody!
Great and it is a good sample! But I got errors
item is not shown after BillingHelper.requestPurchase(Main.this, “My Product item”) but the billing works perfectly
plz help me regarding this issue.

Your tutorial is really good for beginners. You have mentioned that it can be uploaded to market as test app. How to get the public key? 1) By what name i need to upload this test app to market(In in app product id field what should i mention in the account while uploading)? 2) How to test the app without really paying something like using dummy card details?

If you just want to test dummy purchases you don’t need to upload to the market. Just use the item id “android.test.purchase”. Your public key is part of your Google Play account, if you want to test with real products it is explained Here – Testing with Product IDs

THANKS. When i launch the app in device it is connecting to market and showing app title as “Sample Title” and “Sample Merchant” as the publisher when i click accept and buy. I receive a toast message that “Thank you your item will appear shortly”. But it is not showing that image after successful responds. I am trying to upload this sample app and to learn the purchasing process in real time. So as you mentioned added the base64 public key in code after that what modification i need to do, so that i can upload this sample app in market and test in real time, So can you please help me in sorting this out Thanks in advance.

Not really sure where you are up to. If you read the LogCat as you are doing it it might give you a clue what is going on and what code is not being called, sounds like it is missing a handler callback somewhere.

im trying this sample app by uploading to the account as draft and to understand by having 1 in app and purchasing. I have changed the package name and also included the public key and generated the apk in release mode i have uploaded it in market but whan i run the app in logcat it under application it is showing “com.blundell.test” but i have changed the packages name and app name in the project and if i run the app it should show the app name in which i have uploaded but instead it is showing “Sample Title” thats what i asked. Thanks once again

Hello sir … i am using your In app purchase code . I did not change any thing except (internet permission )in this code , when i have clicked on YES button then Google play store opened , when i am clicking on (Accept & bye ) then it shows message “thank you ! your item will appear shortly” and than force close…… shall i make any change in the code please suggest me

Using the code you’ve shared with us here, is it possible to restore managed transactions? For example, someone makes a purchase, deletes the app, re-downloads it, and wants to use the same feature again.

Thank you very much for this tutorial – it was extremely helpful in getting help with InAppBilling setup in my application.

So your simplified code performs the exact same operations as the Dungeons example just in less code and easier to understand? Your BillingService and BillingReceiver are much smaller so just want to confirm that it will perform the same operations.

Also can you confirm this works with the new “Play Store” as well since it was converted from the Google Market?

Hello, I downloaded your sample project. I changed the public key to my publisher key. Then uploaded it. And I added a test account to my publisher key.I log in the device with the test account and test your project with this test account. When I click “Accept and Buy” then it will show “Your item will appear shortly” and then “the application has stopped unexpectedly.Please try again”. I really don’t know why it is so. Please help. Thank you.

Thank you so much for this tutorial!!! it’s very helpful and easy to understand
i am new in this domain! i have implemented your code in my app, did everything you explained here and
uploaded it as a signed test app, but when i run it on my device and click on an item to purchase, it gives me this error: “Application error This version of the application is not configured for billing through google play. check the help center for more information” (the version of the activated test app and the one used on my device are the same). if you can help me with this i will be so thankful!

i’m having problem on calling unbindService(). In ur code stopService() is called but no unbinding service. I am confused where is to unbind the service as I found that onServiceDisconnected() is not being called…..otherwise service leak error is hampering the approach.

Really great tutorial… lot better than the fu**ed up sample of android play_billing….

though I had a question to be clear.
I am testing through sending “android.test.purchased” and I’m using my PUBLIC KEY but didn’t publish the apk on the market. But on mTransactionHandler, I’m receiving BillingHelper.latestPurchase == null.

My question is “is this for not publishing the apk on market or else?”

Thx :), there is another tiny thing , I think I am doing something wrong I integrated your code with my app but there is a tiny issue after it make the purchase that showItem() does not get exec for some reason and this is wot I get:

Hi,
I would appreciate some help integrating it with my application.
I do not want the checkout screen to appear, instead, i want to display a message regarding one time purchase like “Do you want to buy this product for 2 Dollars, Yes or No”, If user clicks on Yes button then request purchase is called and i should get a boolean response that purchase was successful or not.

Right not, a blank screen appear and when i press the back button i get the purchase response Successful in my Log.

Is there any way to make a product validation purchase without having to deal with the market purchase window? I need to make a verification once a week or so, in case the storeddata is wiped or something and i want to avoid the market popup saying me that the item is already bought.

i add public key and use android.test.purchased (id) ….can u tell me what is my mistake …?
and i am not upload any project on google i just install and run on my device …
so its must be need to upload sign apk on market as draft…

Fake purchase works okay.
But when I try to buy real item in my game, billing window shows me item name correctly
and the message “there is not such item to puchase”. I ‘ve created and tryed another item. The same problem.
Does anybody has this code workable?

Nice sample, however ‘Null pointer exception’ on ‘handleMessage’ or the mTransactionHandler found in the main activity, both in your full sample application and my own test project, is the code no longer supported?

I’m also having a crash in ‘confirmTransaction’ and it’s caused because “latestPurchase.notificationId” is NULL.

I do a ‘restoreTransactionInformation()’ to check if my item is already bought, and i got that error. Finally y remade a bit the code to make it more suitable for me..
Now my ‘BillingHelper.verifyPurchase’ returns a List of {productId,purchaseState} and i check if my productId is there and what’s it’s purchase state

No way to find about a notificationId!=null when i’ve already bought the product (real one, not the example one)

Got it. ‘latestPurchase.notificationId’ works only at buying time. If you check it later, it breaks so in BillingHelper() add the ‘if’ statement
if(latestPurchase.notificationId!=null){
confirmTransaction(new String[]{latestPurchase.notificationId});
}

in BillingSecutiry i’ve added a ‘private Static String productId=null’ and in ‘restoreTransactionInformation’ i’ve added a public Static setCheckId(String productId) that saves my productId. So i can check if the requested item is checked.
Then in ‘verifyPurchase’ i only add the line if productId==null (default, when i’m not checking) or it matches.

I’ve installed the app on Market and added published content for sale.
I replace this line:
BillingHelper.requestPurchase(mContext, “myitem_001″);
If I hit “YES!!” I got “File not found” pop-up window.
Maybe I have to wait after publishing the app?
Thanks.

Hi everybody!
Now the billing works perfectly but the restoreTransactionInformation not. I received the signedData, signature, and after the verifications was good, the next method “confirmTransaction(new String[]{latestPurchase.notificationId});” crashes my app at this line: mService.sendBillingRequest(request);

And it doesnt run into the catch branch. Can somebody help me to find the problem?pnyako@gmail.com
Thank you!

Hi. thanks for the tutorial. however I’m getting an error saying “The item you requested is not available for purchase” while trying to buy a real item with a preserved id. I’ve signed the application and uploaded it as a draft version, added products and published them. I have the same version(signed) on my device as the uploaded one. any ideas ?
THanks in advance.

HI!
Great and it is a good sample! But I got errors
I signed the app with eclipse android tools then I uploaded it.
I didn’t create in-app product item because in the main activity the item id is android.test.purchased so I would like to test something wrong.
A could buy the item, and after this (“please wait until the item will be listed”… or something like that) the log says: Signature verification failed.

The key is correct. Another case: when I try to purchase with Id android.test.purchse then I can test buying, but after this event when I receive the sign data etc. then it says Signature failed.
Maybe I have to create a new project.

Fantastic tutorial. Thank you. It was taking my hours to sort through the google docs and your app really made things more clear. Is there a release date for a follow up that included directions on reflection? I see that is TODO. Thanks again.

which function will execute after the in app billing in this code (is it getitem() function)and can i make multiple in app purchase by modifying this code please do replay sir and thank you for all previous replays

hi sir am using your test app it works fine but when i use my in app id .which i have published(not the app) it show item not found i have also set my public key sir please replay what wrong to my email address i need your help my email address rameshmnairmlm@gmail.com

im still working on an app that has an in-app purchase. i used your sample app and it’s working fine. i added some codes to work with restorePurchase… it’s working well but the problem is when restorePurchase is called this time, i havent made a purchase yet. the app crashes. can you help me on this?

hello!
This is a great tutorial, but i am really confused while implementing in app purchase. Can u plz clear those?
1st: I copied the public key from publisher account, but when i am running app, it is giving null pointer exception.
so should i upload this app in my publisher account?
I am confused with the sequence of steps… please help

What does the LogCat say about the null pointer? Yes you need to upload the application and save it as a ‘draft’ apk. This will allow you to test purchases using ‘android.test.purchased’ if you want to test your own in app products (that you create on Google Play) you will need to create a signed APK and push it onto your device using ADB.

Now i have uploaded ur app in my publisher account, but still there is an exception of ArrayIndexOutOfBound.

at java.util.ArrayList.throwIndexOutOfBoundsException

at com.blundell.abc.BillingHelper.verifyPurchase
at com.blundell.abc.BillingReceiver.purchaseStateChanged(BillingReceiver.java:44)

at com.blundell.abc.BillingReceiver.onReceive(BillingReceiver.java:27)

This is what logcat is saying, at this line:
latestPurchase = purchases.get(0); in verifyPurchase method of BillingHelper class.
Actually the ArrayList of VerifiedPurchase does have anything after purchasing from google play site, which causes this exception.

I just uploaded ur application (didnt publish it) and copied public key from account and run the app. M i missing something or doing something wrong uptil now?

I found a solulation of nullpointer exception after successfully purchased “android.test.purchased” item, just rename the app package from “com.blundell.test” to an unique package, something like “com.blundell.test3242342″, and everything will work fine.

First of all, thanks a million for this post, it helped me a lot understanding google’s inapp billing with your simple, straight to the point explanation.

However, I came across a problem that may be looked up in your sample and may get people into problem. The billing service is started and stopped, but it is never unbound. Since the StartService call also binds it to the ServiceConnection, the binding is already done, but the service should be unbound after stopping it.

We have a problem. If user uninstall app, then install again. The database is lost, and user must buy in app again. It is too bad. Your code does not contain this feature. Could you explain this for me?

First of all, thank you for this tutorial and the sample project; Very useful!

I have a question. I’m on the last leg of the In App Billing implementation. I am able to bind successfully, and initiate the purchase for the reserved id “android.test.purchased” using my developer email address as the purchasing account.

However, when the code begins verification, the signature coming back is blank and hence nothing gets added to the purchase array. This leads to a nullpointer exception on “latestPurchase = purchases.get(0);” in BillingHelper.java.

I have already uploaded a draft (unpublished) app with the same version number to Google Play. I’m limited in my debugging since I’m testing on a signed release version. Any idea what could be happening here?

Just wanted to let you know something I just found out. You may have received messages from loads of users saying they get a NullPointerException when using restoreTransaction. In case you haven’t noticed this, you don’t need to send a CONFIRM_NOTIFICATIONS for the PURCHASE_STATE_CHANGED that you get back when you send a RESTORE_TRANSACTIONS. The reason is that when you send a RESTORE_TRANSACTIONS request, the PURCHASE_STATE_CHANGED that comes back does not need a CONFIRM_NOTIFICATIONS, like the rest of the requests. In the signed data that you get back on calling RESTORE_NOTIFICATIONS, there are no notification_id’s that come back; In your code, you go ahead and send the CONFIRM_NOTIFICATIONS for this situation also, which you don’t need to (Google Docs confirm this). The NullPointerException takes place because of the null notification_id’s that you add to the confirmation bundle for a RESTORE_TRANSACTION.

Sorry if the above paragraph seems long winded haha. I’m very hopped up on coffee right now.

Hi, Are you talking about the mCompletedHandler? Handlers are used a callback mechanism, allowing you to notify your activity after a certain event has happened on another thread ( or in a service ). This is what the completed handler does, when you create your BillingHelper you inform it that the handler is the activity. Therefore when the helper completes a purchase it tells the Activity ‘transaction complete’.

yes and no. You create mTransactionHandler in your AppMainTest.java. If the handler is used for callback to inform an activity it must have some kind of callback method which someone else, e.g. a service, calls. Where is that callback mehtod defined and where can I see in the server that it is called? Thanks.

What shall I tell the user to do if it returns false? Is there anything I can check why it returned false? Just telling the user “sorry cannot bind, no purchase possible” is probably not what you want to show a user. What are examples when this can fail?

Binding to the Android marketing service can fail when the Android Market (Google Play) application is out of date and needs updating. i.e. You are attempting you bind communication between your app and Google Play, so it’s upto Google Play to ensure this works. If you cannot bind to the service i.e. ‘bindResult’ == false, you could write a message something along the lines of “Sorry can’t make purchases until you update to the latest Android Market / Google Play. You could also show them how to do it or link to this FAQ here: https://support.google.com/googleplay/bin/answer.py?hl=en&answer=190860 . Hope that helps.

If your doing this in onCreate the Activity may not have been bound to the service yet. you could create a callback for when the service is bound, or add it to a queue and do it when the service is bound. Add some Log into ‘onServiceConnected()’ to help you understand the timings.

Great tips, thanks. To avoid any problems I might have with making a callback in the wrong place, I simply threw in a dialog with a button I can hit to trigger the check. I added a Toast to show when billing is connected, so I know that I’m hitting the button after it’s connected ok. Of course, when I try to run this on USB debug, all I get is a “RESULT_DEVELOPER_ERROR” response from the market, which is because I’m using the debugger.

When I sign the package and install & run on a real device, I see the message telling me billing has connected, but then when I trigger the check it just errors and tells me to force close it.

Any ideas what else could be wrong? Any suggestions how to even diagnose it without a debugger?

I’ve worked out (or rather been told) how to use adb to view logs on my real device. I’ve posted the logcat at this StackOverflow question. It looks like the response is received fine, but then it attempts to call the rever again, and fails to do so – after the request is received, shouldn’t that simply trigger the payment handler? Do you have any other suggestions?

I’ve looked at that SO question. Is the item you have purchased a managed item? You know you can build your app live but not obfuscated to rule that out. You know you can just plug your ‘real device’ into eclipse and it’ll bring up your LogCat? Your getting a NPE so I’d Log out all the variables you send to Market to make sure you’ve got everything.

Just to confirm, Siddharth Iyer above has it exactly right. I simply wrapped the confirmTransaction cal in a check to make sure latestPurchases.notificationId isn’t null, and no more errors. Perhaps you could update the tutorial to include those changes?

Thanks for posting this. The code is much easier to follow than the spaghetti that is the Google sample app.

I’m also looking to restore previous purchases after a reinstall – calling restoreTransactionInformation doesn’t seem to do anything though. I mean literally no responses – do you have any tips on how to use it?

Simple question though : how do you restore transactions? If I buy my product, then uninstall and install the app back again, I’m not able to purchase the product anymore (error text is something like “transaction in progress). Noticed about the restoreTransactionInformation() method but when I launch it when installing the app, the handler is not triggered at all and my logs show a RESULT_DEVELOPER_ERROR.

I’d have to see more code, make a question on http://stackoverflow.com , all I can say make sure your passing in the transaction handler correctly and that it you stepp through it with breakpoints. Adding extra log output is always good as it shows you what is exactly going on

It doesn’t, this depends on what type of product your selling, you may not want to save it. If you did you would save it when you get the response saying bought you. It’s up to you to use SharedPreferences or a database or whatever.