Google Play IAP event.transaction.state == "purchased" never gets called

Google recently changed their in-app purchase look when they changed their play store (I think it was a week ago) I’m wondering if that broke the in-app purchases?

I’ve tried using the lemonade sample code as well as this tutorial:

http://www.coronalabs.com/blog/2012/03/13/getting-started-with-android-in-app-billing/
 

Everything loads fine and prompts me for purchase. After the purchase is made the listener is never called.However if I cancel the purchase the listener is called just fine. Is anyone else noticing this behavior?

I submitted a bug request for this seeing as how their sample is doing the same thing. I wonder how long it will take to fix. I was so close to launch too, but now the app is on hold waiting for this =/

Same here! Right before the google play store changes all of my iap where working fine…now they are not. Not even the sample iap Code completes the purchase.

Glad I’m not the only one. Hopefully we can get someone to confirm this or at least confirm the fact that they’ve read this post.

@dmglakewood are your iap for iOS working ok?

Haven’t tried it on an iOS device yet

The “cancelled” listener works if you press the back button during checkout. If google play says “payment successful”… when returning to the game the activity indicator remains on and nothing else is called. You have to then restart the game. Is this also what everyone else is experiencing?

What is your bug ID #

Hi Rob, 

I opened one as well…

Case 22927

My bug ID is 22833

Yep that’s exactly what I’m seeing as well.

I’m getting the same bug.

Strangely, I still had the old store showing up until about an hour ago, and was trying to fix a different bug (I’m getting the “invalidClient” response when testing). Then at some point in the middle of testing the Google Play popup changed from the full screen one to a popup (which got my hopes up thinking I’d fixed my own bug) and now there is no “purchased” response.

Yeah google has bee pushing the new store out to everyone over the past week or two. Slowly but surely every corona app that allows in app purchases will no longer work. I think this is a HUGE bug as a lot of apps no a days rely on IAP as their only source of revenue . Not only that but if someone spends 1$ to but something in a game and it doesn’t work, do you think they will try it again?

Okay got a reply to my bug

"Hi,

Turns out we needed to find an Android device with the updated version
of Google Play.  We have recreated the problem and will be looking into
it.  Thanks for filing the bug."

Everyone,

We just tested this today with “managed” and “unmanaged” products and it is working.

We tested an app built with the release version (build #1076) on the following devices:

  • Galaxy Nexus 4 with OS version 4.2.2 with Google Play version 4.0.26

  • Galaxy Nexus with OS version 4.0.4 with Google Play version 4.0.27

  • Galaxy SII with OS version 2.3 with Google Play version 3.10.14

We verified that Corona does correctly receive a “purchased” event with a JSON receipt.

We also verified that in-app purchases work with the new and old versions of the Google Play app.

Now, I do know that purchases will fail for the following reasons:

  1. You cannot use your developer account to test purchases.  You need to set up a separate test account with Google Play on your device and via the Android Developer Console.

  2. If the purchase came from an app package name that doesn’t exist in your Android Developer Console.  I believe it must be signed with the same keystore as well, meaning that you cannot use our debug.keystore for testing in-app purchases.

I’ve also noticed that the Google Play app will crash when attempting to do an in-app purchase if the Google Play app is in the middle of updating itself.  That is, you’ll first see the old Google Play in-app purchase screen (which is full screen), you’ll be kicked out of the window almost immediately afterwards (because Google Play crashed), and when you attempt to purchase the same product again you’ll see the new Google Play in-app purchase popup dialog instead within your own.  It doesn’t cause your app to crash, it’s more like the Google Play app effectively reboots itself to use the newest version.  It’ll work correctly for subsequent in-app purchases.

By the way, we’ve tested with real purchasable products that charged our credit card.

We did not test with Google’s test products, such as “android.test.purchased”.

Okay looks like I have some tweaking to do. I was using googles test card to test. I will try a real card and report back.

Okay I just tried a bunch of orders using real products and real credit cards. I’m still seeing the same issue. My canceled transaction fires the listener but my successful one does not. Maybe it’s just my code? Can someone take a look at it?

storeinit.lua

local store = require("store") function transactionCallback( event ) local infoString -- Log transaction info. print("transactionCallback: Received event " .. tostring(event.name)) print("state: " .. tostring(event.transaction.state)) print("errorType: " .. tostring(event.transaction.errorType)) print("errorString: " .. tostring(event.transaction.errorString)) if event.transaction.state == "purchased" then infoString = "Transaction successful!" elseif event.transaction.state == "restored" then infoString = "Restoring transaction:" .. "\n Original ID: " .. tostring(event.transaction.originalTransactionIdentifier) .. "\n Original date: " .. tostring(event.transaction.originalDate) elseif event.transaction.state == "refunded" then infoString = "A previously purchased product was refunded by the store." elseif event.transaction.state == "cancelled" then infoString = "Transaction cancelled by user." elseif event.transaction.state == "failed" then infoString = "Transaction failed, type: " .. tostring(event.transaction.errorType) .. " " .. tostring(event.transaction.errorString) else infoString = "Unknown event" end toast.new(infoString,10000) store.finishTransaction(event.transaction) end --Load in the right store for the right phone if store.availableStores.apple then store.init("apple", transactionCallback) elseif store.availableStores.google then store.init("google", transactionCallback) else toast.new("No app store found on your device", 1000) end

store.lua

function checkStoreIsAvailable(purchaseItem) if(store.isActive == false) then showStoreNotAvailableWarning() elseif(store.canMakePurchases == false) then native.showAlert("Store purchases are not available, please try again later", {"OK"}) elseif purchaseItem then store.purchase({purchaseItem}) end end function doublePayouts() checkStoreIsAvailable("testprod") end function showStoreNotAvailableWarning() if isSimulator then native.showAlert("Notice", "In-app purchases is not supported by the Corona Simulator.", { "OK" } ) else native.showAlert("Notice", "In-app purchases is not supported on this device.", { "OK" } ) end end

It’s pretty basic code though I don’t see where the issue could be in the code.

I don’t see anything wrong with your code.

I recommend that you have a look at the log via Android SDK tool “adb logcat” or “ddms”.  Check to see if anything unusual gets logged after making a purchase.  Particularly from the Google Play app.  I’m wondering if Google is responding with an HTTP status code of 403, which means Google’s servers have temporarily banned your device from communicating with them too much… which typically happens to Android developers when doing too many in-app purchase “restores”.  I’ve heard that this ban lasts for about 3 weeks, in which case, you’ll have to test with another Android device.

Also, you may want to double check the following:

  • You have the “com.android.vending.BILLING” android permission set in your “build.settings” file.

  • Try launching the Google Play app separately to make sure that app can connect to Google’s servers.

  • Your in-app products are flagged as “Active” under the “Status” column in the Google Play Developer Console.

  • Check if your Merchant Account is “Active” in the Google Play Developer Console.

One more thing.  Are you building your app with the Corona Simulator or Corona Enterprise?  If it’s with Corona Enterprise, then I’ll have some follow-up questions for you about how your AndroidManifest.xml file is set up.

Other than that, I’m starting to run out of ideas.  I had one other person here test out Google’s in-app purchase system and it worked for him as well.  If there is a real issue here, then we’ll be happy to look into it.

Here is the log cat for the purchase, seems to be okay to me. The last line is the only thing that looks a little odd?

D/Finsky ( 4328): [30] InAppBillingUtils.getPreferredAccount: wheel.slots.le om.com: Account from first account - [In\_h0C\_V5hSY629rEleRs0SN5cg] D/Finsky ( 4328): [30] InAppBillingUtils.getPreferredAccount: wheel.slots.le om.com: Account from first account - [In\_h0C\_V5hSY629rEleRs0SN5cg] D/Finsky ( 4328): [1] MarketBillingService.sendResponseCode: Sending respons ESULT\_OK for request 7568336821629477583 to wheel.slots.leetcom.com. D/Finsky ( 4328): [8] InAppBillingUtils.getPreferredAccount: wheel.slots.lee m.com: Account from first account - [In\_h0C\_V5hSY629rEleRs0SN5cg] D/Finsky ( 4328): [8] InAppBillingUtils.getPreferredAccount: wheel.slots.lee m.com: Account from first account - [In\_h0C\_V5hSY629rEleRs0SN5cg] D/Finsky ( 4328): [1] MarketBillingService.sendResponseCode: Sending respons ESULT\_OK for request 8542737001937316334 to wheel.slots.leetcom.com. D/Finsky ( 4328): [1] MarketBillingService.sendResponseCode: Sending respons ESULT\_OK for request 3800187125826941047 to wheel.slots.leetcom.com. I/Gmail ( 4409): calculateUnknownSyncRationalesAndPurgeInBackground: queuei I/Gmail ( 4409): calculateUnknownSyncRationalesAndPurgeInBackground: runnin I/Gmail ( 4409): MainSyncRequestProto: lowestBkwdConvoId: 0, highestHandled verOp: 274246, normalSync: true D/Finsky ( 4328): [1] MarketBillingService.sendResponseCode: Sending respons ESULT\_OK for request 6218416608661063811 to wheel.slots.leetcom.com. D/Finsky ( 4328): [1] PendingNotificationsService.setMarketAlarm: Setting al for account=xxxxxxxxx@gmail.com, duration=120000
  • I do have the billing permission set in my settings

  • I can connect just fine and purchase other apps with no problem. I also purchased an in app purchased an in another app

  • The in app item is active in google play portal the app is in draft. The apk is signed and is the same version number

  • My merchant account is active as well

It doesn’t seem to be anything on google’s side as I can make the purchase just fine. I can see the payment in my finance report and everything seems to go through just fine. The listener for the purchase just doesn’t get called. If I cancel the order it gets called or if I try to place the order in air plane mode it also gets called.

I’ve tried using 2 different accounts on 2 devices. I will try a few other devices but I expect the same results. Also all the test have been done over wifi, not sure if that matters or not.

Is there anything else I can provide you with to help?