Google Play v3

do you have to use google play v3 will v2 work on all devices

V2 should still work, however Google will likely cut off V2 at some point.

Rob

Hi, Rob

I think there is a problem in Google Play v3 plugins.

I test the same code, with different parts

store = require(“store”)   vs.

store = require(“plugin.google.iap.v3”)

then

store.init( “google”, transactionCallback )

works fine on the old one, but fail (just hang there) on v3 plugins.

I do have the build.setting plugins right, I am pretty sure about that.

BOB

@bobyeh

I have the same problem. Google IAP v3 is causing hanging on my Android game.

I posted about it on another thread, but got no response:

http://forums.coronalabs.com/topic/52201-increase-in-anrs-on-google-play-with-iap-v3/

I think this is the same issue that I responded to here:

http://forums.coronalabs.com/topic/50156-storeavailablestores-returning-bill-with-google-yap-v3/?p=268421

Can you post your build.settings?

Are you seeing any error’s from the device’s console log (adb logcat)?

Rob

In david’s linked thread, there are a couple of issues mentioned. The first is a crash, which was resolved by david.

The other issue looks like the same ANR problem I had/have. 

st.tosi believes they fixed the problem by making themselves an alpha tester and doing a few other things, but I think it’s probably just random. I could only recreate my ANR issue on one of my Android devices (HTC One) so it’s not unreasonable that the problem can come and go depending on other factors. 

My guess for what happened is just that the main thread is hanging while waiting for IAP v3 module if there is too much other stuff going on. That’s why adding a delay before loading IAP v3 helped. I wrote a bit more at the other thread.

Also, the common factor between the two issues is this appearing in logcat:

V/Corona  (27335): > Class.forName: plugin.google.iap.v3.LuaLoader
V/Corona  (27335): < Class.forName: plugin.google.iap.v3.LuaLoader

Is there any update about fixes coming for the IAP V3 plugin? It seems like there are still issues with crashes and purchases getting called multiple times. I’m using build 2482.

The IAP V3 is a plugin so it’s not tied to a specific build.  Is there a filed bug report?

Rob

There isn’t. 

Here are some of the issues. Everything listed below works perfectly on iOS.

The listener doesn’t get called when you do store.loadProducts.

When you try to buy a non-consumable/managed IAP you already own, it crashes. In the logs:

In-app billing error: Unable to buy item, Error response: 7:Item Already Owned

Well I know for certain that store.loadProducts() does call it’s listener.  I just tested it in the game I’m working on.  The call back for the loadProducts call is a different function.

local function loadProductsListener( event ) &nbsp;&nbsp;&nbsp; print("In loadProductsListener") &nbsp;&nbsp;&nbsp; local products = event.products &nbsp;&nbsp;&nbsp; for i=1, #event.products do &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(event.products[i].title) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(event.products[i].description) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(event.products[i].localizedPrice) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(event.products[i].productIdentifier) &nbsp;&nbsp;&nbsp; end &nbsp;&nbsp;&nbsp; for i=1, #event.invalidProducts do &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("invalid", event.invalidProducts[i]) &nbsp;&nbsp;&nbsp; end end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; store.init( "google", transactionCallBack ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if store.canLoadProducts then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("Loading products!") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; store.loadProducts( productList, loadProductsListener ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.performWithDelay(2000, function() store.restore(); end) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print("Can't load products") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end

When you try to buy something you already own you should get the message: In-app billing error: Unable to buy item, Error response: 7:Item Already Owned in your console log.  Your transaction call back   I don’t know why you’re crashing.  Is there more to the error?

Also keep in mind you cannot test with your developer account.  You have to use a test account.

Rob

Hi @Rob Miracle

I just had the same situation. 

When I got the message from console,

In-app billing error: Unable to buy item, Error response: 7:Item Already Owned .

The app crashed without any logs.

There is always a console log on the device that you get to with “adb logcat”.   If you are filtering only on Corona generated messages, i.e.: 

adb logcat Corona:v \*:s

then please leave the Corona:v *:s off and just run adb logcat because that filtering only shows your print messages and Corona generated crashes.  If its in some other intent like Google Play, you won’t see those messages.

In-app billing error: Unable to buy item, Error response: 7:Item Already Owned

is a perfectly normal message.  You cannot buy items already owned.  But if you’re crashing there has to be more messaging to go on.  If not brute force debug and add in some print statements.  See where you’re getting to in your code.

Rob

I put the consume API into a timer, hope it could be better. But why should I do this?

Its possible that the store API isn’t in a state to call another store API.  It’s similar to while you can’t do something things in physics while in the middle of a collisions handler.

Rob

I just use the consume API in the state “purchased”, sometimes it’s ok, sometime is not. I just wonder how could I know when it would be in the right state.

Now, I’m using the code below, put the consume API into a timer, try to fix the issue, but I’m not sure whether it would be ok in every case:

 if transaction.state == “purchased” then

        LOG(“Transaction succuessful!”)

    if MobileStore.paymentMode == 1 then – google iab v3

    …

        timer.performWithDelay(10, function() store.consumePurchase( { transaction.productIdentifier }, transactionCallback); end)

       

    end

elseif transaction.state == “consumed” then

    LOG( “Transaction consumed!” )

elseif  transaction.state == “restored” then

    LOG(“Transaction restored (from previous session)”)

elseif transaction.state == “cancelled” then

    LOG(“User cancelled transaction”)

elseif transaction.state == “failed” then

    LOG(“Transaction failed, type:”, transaction.errorType, transaction.errorString)

else

    LOG(“unknown event”)

end

– Once we are done with a transaction, call this to tell the store

– we are done with the transaction.

– If you are providing downloadable content, wait to call this until

– after the download completes.

store.finishTransaction( transaction )

It shouldn’t hurt to have it in a timer.  It could help the issues this thread was talking about.

Rob

ok, thanks Rob. 

It’s good to take care the forum by you. Fast and best reply~  :)

Sometimes, shit happened again, catch the log this time.

E/IABUtil/Security(19324): Signature verification failed.

W/IabHelper(19324): In-app billing warning: Purchase signature verification **FAILED**. Not adding item.

W/dalvikvm(19324): threadid=21: thread exiting with uncaught exception (group=0x41a96ba8)

W/System.err(19324): java.lang.NullPointerException

W/System.err(19324): at plugin.google.iap.v3.LuaLoader$6.onQueryInventoryFinished(LuaLoader.java:373)

W/System.err(19324): at plugin.google.iap.v3.util.IabHelper$2.run(IabHelper.java:622)

W/System.err(19324): at java.lang.Thread.run(Thread.java:841)

W/FlurryAgent(19324): Error logged: uncaught

I/System.out(19324): WARNING: Could not load font Helvetica. Using default.

W/FlurryAgent(19324): End session with context: com.ansca.corona.CoronaActivity@4220cf10 count:0

I just got the following message, testing for a non-consumable: “Transaction failed:    7    Unable to buy item (response: 7:Item Already Owned)” … but I’m sure I don’t own the item. ??? Is this possible?