Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
How to add Android InApp purchases — Gideros Forum

How to add Android InApp purchases

RadieselRadiesel Member
edited December 2012 in Step by step tutorials
Hi folks,

I’d like to share my experience with Android InApp purchasement. Since the following is working for me, users have asked for s Step-by-Step instructions. I’ll try me very best here...

First of all I have to say, that Android development is my weaker part, so if I did something wrong, please correct me.

Gideros documentation on googlebilling is not fully complete enough as Atilim stated himself. Or well, documentation is complete, but in my opinion there are missing samples...

Here’s the basic code to handle InApp purchases. Very simple code and very similar to StoreKit.

Step 1: Add the folling code
require "googlebilling"
 
--------------------------------------------------
-- GOOGLE Billing
-- <a href="http://forum.giderosmobile.com/profile/param" rel="nofollow">@param</a> event
-- <a href="http://forum.giderosmobile.com/profile/return" rel="nofollow">@return</a>
--------------------------------------------------
local function onRequestPurchaseComplete(event)
    if (event.responseCode == GoogleBilling.OK) then
		-- transaction has been sent to google (thanks Atilim)
		-- don't unlock items here
	else
		local msg = "purchase failed"
		if (event.responseCode == GoogleBilling.USER_CANCELED) then
			msg = "GoogleBilling.USER_CANCELED"
		end
		if (event.responseCode == GoogleBilling.SERVICE_UNAVAILABLE) then
			msg = "GoogleBilling.SERVICE_UNAVAILABLE"
		end
		if (event.responseCode == GoogleBilling.BILLING_UNAVAILABLE) then
			msg = "GoogleBilling.BILLING_UNAVAILABLE"
		end
		if (event.responseCode == GoogleBilling.ITEM_UNAVAILABLE) then
			msg = "GoogleBilling.ITEM_UNAVAILABLE"
		end
		if (event.responseCode == GoogleBilling.DEVELOPER_ERROR) then
			msg = "GoogleBilling.DEVELOPER_ERROR"
		end
		if (event.responseCode == GoogleBilling.ERROR) then
			msg = "GoogleBilling.ERROR"
		end
 
		print(msg)
    end
end
 
--------------------------------------------------
-- GOOGLE Billing
-- <a href="http://forum.giderosmobile.com/profile/param" rel="nofollow">@param</a> event
-- <a href="http://forum.giderosmobile.com/profile/return" rel="nofollow">@return</a>
--------------------------------------------------
local function onPurchaseStateChange(event)
	if (event.purchaseState == GoogleBilling.CANCELED) then
            if (event.productId == "your_product_001") then
			-- lock or don't unlock
		elseif (event.productId == "your_product_002") then
			-- lock or don't unlock
		elseif (event.productId == "android.test.purchased") then
			-- lock or don't unlock
		end
	elseif (event.purchaseState == GoogleBilling.PURCHASED) then
            if (event.productId == "your_product_001") then
			-- unlock 
			-- show Message, item bought
		elseif (event.productId == "your_product_002") then
			-- unlock 
			-- show Message, item bought
		elseif (event.productId == "android.test.purchased") then
			-- unlock 
			-- show Message, item bought
		end
	elseif (event.purchaseState == GoogleBilling.REFUNDED) then
            if (event.productId == "your_product_001") then
			-- lock or don't unlock
		elseif (event.productId == "your_product_002") then
			-- lock or don't unlock
		elseif (event.productId == "android.test.purchased") then
			-- lock or don't unlock
		end
	elseif (event.purchaseState == GoogleBilling.EXPIRED) then
		-- for subscriptions
	else
		-- unknown state
	end
 
	googlebilling:confirmNotification(event.notificationId)
end
 
-- maybe it better to modify original publicKey by XOR or split into parts as google suggests
googlebilling:setPublicKey("yourverylongpublickey")
googlebilling:addEventListener(Event.REQUEST_PURCHASE_COMPLETE, onRequestPurchaseComplete)
googlebilling:addEventListener(Event.PURCHASE_STATE_CHANGE, onPurchaseStateChange)
Somewhere in your code add an EventListener e.g. to a button (I've used the "button" class here from the forum)
 
local buybutton = Button.new(Bitmap.new(Texture.new("assets/gfx/buyanitem.png", true)))
stage:addChild(buybutton)
buybutton:addEventListener("click", 
function()	
    googlebilling:requestPurchase("your_product_001")
end)
To test that the basic purchasing functionallity is working correct, you can simulate purchasing by using static product IDs. Simply instead of

googlebilling:requestPurchase("your_product_001")

you can use

googlebilling:requestPurchase("android.test.purchased")

to simulate purchasing an item. No credit card need and there is no real payment made, but google sends the messages like you would have purchased a valid item. To test a canceled item, simply use

googlebilling:requestPurchase("android.test.canceled")

Both testproducts partly (!) work in gideros player on Android. Real products don't! You'll have to setup real products in GooglePlay and also have to create a testaccount which you have to use as the primary account on your android device. Either factory reset your device to the testaccount or use Android 4.2 which supports multiple logins on one device. In GooglePlay set the testaccounts email addresses under "Settings" - "Account details" - "GMail accounts with test-access" (if that is not 100% correct, it's because I have german GooglePlay Developer Console).

Step 2: Export your project as Android project and make sure your AndroidManifest.xml has the following line:
<uses-permission android:name="com.android.vending.BILLING"></uses-permission>

Step 3: Create a signed .apk of your project

Step 4: Upload to GooglePlay, don't publish/release the .apk, but you might want to fill in all the required fields

Step 5: Within "InApp-Products", create your InApp products, e.g. "your_product_001", etc...

Step 6: Set the InApp products to "active", otherwise you App will not have access to the items

Step 7: Install your signed .apk on the device with your testaccount and run it

As far as I recall that's basically all you have to do. It should work now. "Great" thing, it isn't...

Believe it or not, you have to wait some hours until google sets the items to a purchasable state.

I tried several times and got messages like
- "Application is not configured to make InApp purchases"
- "Retrieving data failed"
- "etc.etc."

Without changing anything error messages changed all the time and all of a sudden, it worked....

As the final test you can purchase one item using the testaccount with a valid credit card. You can refund the amount of your sold product in "Google Checkout" (don't know the english version here).

I hope I did not forget anything, if you have the feeling there is something missing, please let me know and I will modify/enhance the Step-by-Step instructions

best regards
Michael

PS: As a hint, don't try to make intensive tests in gideros player, even testproducts above don't work completely. You should create an .apk and first test using googlebilling:requestPurchase("android.test.purchased"). If that works, you can enter real product IDs.
+1 -1 (+11 / -3 )Share on Facebook
«13

Comments

  • I think you should alert the user if something goes wrong.
  • atilimatilim Maintainer
    that's a great tutorial. thank you.
  • @mertocan, not 100% sure if it's necessary - google throws a lot of dialogs itself ;-) But however, usually makes sense....

    Likes: mertocan

    +1 -1 (+1 / -0 )Share on Facebook
  • Step-by-Step instructions are not fully correct. I will adjust soon, so please be careful using the above code... Stay tuned...
  • I have modified the code which works pretty good for me. I also added some more comments/hints... Hope it helps!
  • It doesn't work for me. I am purchasing the item but onPurchaseStateChange function never gets executed.
  • Hello, I also have the same problem as mertocan, all work fine except onPurchaseStateChange is never called at all
  • But in the onRequestPurchaseComplete(event) you receive GoogleBilling.OK?
    Then maybe something is wrong on the Google Play setup part
  • nat12nat12 Member
    edited December 2012
    Yes, the onRequestPurchaseComplete do receive GoogleBilling.OK

    We have done the test with android.test.purchased, this dummy test item result available, I do see all the Android system popups, also the "purchase successful, your item will appear soon" popup (it appear over a black screen). after this our Gideros app reappear with the correct screen, the only problem is the onPurchaseStateChange callback is never called...
  • In my Google Play Developer Console I see a message that tells:
    On December 5th we begin to send third party apps a new order ID format within in-app billing notifications. Google Order Number will be replaced with Merchant Order Number. Developers using the Checkout XML V2 Notification API will no longer be able to use it. Developers can continue to use the  Checkout XML V2 Order Report API since that report supports both Merchant and Google Order Numbers.
    Maybe this have to do something with it?
  • That's why I wrote, in gideros player it only works partly (!). I had the same problems, but it works on a real device. Please install the App on a real device and use the "android.test.purchased" item. You might want to add an altertBox to make sure your function (onPurchaseStateChange()) got called.

    Michael
  • It doesnt work on real device also
  • Hello, same problem here, we have tested on a device using android.text.purchased, onPurchaseStateChange still never called... any other suggestion?
  • Hmm, just realized, that Step 2 above didn't show the android manifest information. I have modified that. I will try again workflow when I am back home.

    @nat12, hope "text" is a type, should be "test".

    Did you get any error messages?

    Michael
  • Just tested, still working without problems...

    If you call

    googlebilling:requestPurchase("android.test.purchase")

    first thing that shows up is a dialog showing "Sample Title",etc. There's a button "accept & buy", pay with "VISA xxx-FAKE". When you click on "accept & buy" a small hint shows up "your product will appear soon" (or similar). It takes up to 10 seconds on my device until the function onPurchaseStateChange() gets called. But it definitely gets called, because after about 10 scones, my test-alert shows up.

    If I test with real products, onPurchaseStateChange() gets called much sooner. Basically there is no real delay like I have when testing with the test product.

    One more thing, I am using a separate gmail account for testing purchasing products. Sooner or later you will have to set up such an account to test real products. To fully test real products you even have to add your credit card number for the new test-account. I will test if I am running into the same problem when using my real account instead of my test-account.

    If you're still stuck, you might want to send me your code, I will try to figure out what the problem is.

    regards!
    Michael
  • tested with my primary account, working good, too. test-alert dialog (within onPurchaseStateChange()) showed up sooner this time. Maybe it's some sort of random time period after google sends the message ;-)
  • Which gideros version do you use? I do same thing with you but onPurchaseStateChange() function never gets called. I have no idea how to fix it.
  • Yes, "text.purchased" is a typo in the message, in the code we have "test.purchased".
    I do see all the "Sample Title/accept&buy/your product will appear soon" system messages.
    I also see the lua alertBox from onRequestPurchaseComplete with responseCode==OK.
    No matter how much I do wait, onPurchaseStateChange alertBox never appear.

    We do use Gideros 2012.09.2 (we will try 9.5 soon), our testing device is a Samsung GT-i9000 with Android 2.2

    I have noticed these warning in the Eclipse problems window:
    Class is a raw type. References to generic type Class should be parameterized PurchaseObserver.java /Crash_Dummy_LITE/src/com/giderosmobile/android/plugins/googlebilling line 35 Java Problem
    The import android.os.Handler is never used PurchaseObserver.java /Crash_Dummy_LITE/src/com/giderosmobile/android/plugins/googlebilling line 17 Java Problem
    The method getInterfaceDescriptor() from the type IMarketBillingService.Stub.Proxy is never used locally IMarketBillingService.java /Crash_Dummy_LITE/gen/com/android/vending/billing line 80 Java Problem
    The value of the local variable packageName is not used Security.java /Crash_Dummy_LITE/src/com/giderosmobile/android/plugins/googlebilling line 171 Java Problem
  • I am using 9.5 but I have same problem with you. My testing device is HTC Desire HD 2.2 . These codes was working 2-3 ago. I doesn't work now. Maybe , Google changed something :S
  • I am using Nexus 7 with Android 4.2, still working good. Maybe it's android version related... Somewhere I am having an old HTC desire 2.3... I'll test with that device also...

    Did you add the line in Step 2 into your android manifest? I manually had to add it...
  • and I am still using gideros 9.2 since new versions seem to make problems....
  • When I had 9.2 it was working but I dont think it is about Gideros version. Because @nat12 has 9.2 and has same problem
  • tested on HTC desire, android 2.3 - working...
    tested on HTC desire S, android 4.0.4 - working...

    One test, android.test.canceled took 30 seconds until message arrived...

    At least for me still seems to work very good...
  • Damn! Why it is not working for me
  • I downloaded 9.2 and tried on it. When i buy test item, Gideros Player crashes. So strange things happenig for me :D
  • hmm, maybe it has something to do with the android SDK? I am using 4.1.2... You can still send me parts of your code via BM if you like... And android manifest....
  • Can you try this application. When you click on the screen it will go to play store and if you purchase the item , apk will be shut down.
  • which, where, what? ;-)
  • I forgot to upload sorry :)
    rar
    rar
    New Project.rar
    2M
Sign In or Register to comment.