Google Play v3

Okay, then I guess someone missed to refund this non-consumable in the past and the purchase is still ‘active’.

In this case I will search it and doing a refund (in Google Wallet) for the purchase.

What exactly is happening after I did a refund for the purchased item with the new V3? Will Google then automatically allow buying this item again and deactivate the “restore” possibility for this item (by deleting stored data for the item)?

UPDATE: I just noticed you wrote "non-Consumables are now considered “Managed” … but they were before considered “Managed”, right?

I mis wrote…  consumables are now considered managed.

When you issue a refund, the next time that user runs the app and store.restore() is called (I think) you will get a transaction with a “refunded” state.  At this point you should undo whatever purchasing did (lock the levels, take away the power, etc.)

Rob

I just tested code for a non-consumable WITHOUT store.consumePurchase and the refund was not detected.

So I think it will work like this:

I always have to use store.consumePurchase! With consumables AND with non-consumables.

With a “refunded” state I will lock everything the non-consumable purchase has unlocked.

A “restore” state can still be detected by Google… even with store.consumePurchase used.

Is this right?

UPDATE:

I now have tested the new V3 with a Non-consumable and it worked. But after deleting the app from the device and reinstalling it I wanted to RESTORE it and the restore is not working. How is a restore with the new V3 and the store.consumePurchase handled correctly?

Did you figure this out?

I have managed products (non-consumable products) for sale in my game. I have not yet been able to get a refund state from the transaction callback listener. I have been able to get the product to restore after the game is uninstalled and then reinstalled. I refunded the item and waited a few minnutes, uninstalled the game and then reinstalled, and the item was restored after calling store.restore()… I waited 24 hours. Now after calling the store.restore() I am getting nothing back from the transaction listener. (At this point I expected to see a refunded state returned)

You have confirmed that the non-consumable products also need to be run through store.consumePurchase in order to properly get a refund? Have you figured out why you were not getting it to restore using this method?

I don’t know that consumables can be refunded.  In the normal game model, if you buy 10 gems, use them then go to Google Play and request a refund, what happens if your gem total is 0?  How does your game handle -10 gems?  How do you know what things they bought with those specific gems to take away from them?

Rob

I don’t know anything about consumables, because I only have one non-consumable to unlock a full version of the app.

I did the following so far:

I purchased the full version which worked fine. Then I deinstalled the app and installed it again to test the restore, which worked fine.

I deinstalled it again and then cancelled the purchase in Google Wallet. I waited some hours and tested the restore again, which still worked!

I deinstalled the app again, installed the locked version again and tested a purchase which didn’t work, because I still got the message the product already was bought before and I own it already. The restore still worked!

I had to wait for over 24 hours until a normal purchase of the product was possible again. I haven’t tested the restore after this point, but I guess it isn’t working because Google had got the info about the cancelled Google Wallet money transaction.

I don’t know about the refunded state so far. I think you have to test in a full unlocked version for an already purchased non-consumable if this non-consumable is still ‘owned’… which means you have to use the store code even in a full unlocked game from time to time to test for the refunded state. Is this correct?

I wish you all a Happy New Year! :slight_smile:

Best,

Daniela

So are you using store.consumePurchase() on your non-consumable items?

I run a restore everytime the game is loaded… I have not yet been able to get a refunded state… Actually what happens is I cancel the purchase by requesting a refund through my test account, which cancels the order in my google wallet merchant account… wait around 24 hours (Ive read you have may have to wait between 24-48 hours before google will send a refund notification). After 24 hours I no longer recieve a purchased state (or restore)… I dont recieve anything from the transaction listener after google refunds (Im assuming) the item. 

Is it possible to test for a refund with an app that is side loaded with a gmail account with license testing?

No. I’m not using it.

We’re experiencing a strange problem with the “already owned” consumables, and it doesn’t happen every time.

The first step is to cut off the internet connection between pressing buy, and seeing the next google popup - this should cause it to show the “no internet connection” message.

When we try and make the purchase again and see this message, the callback to lua has:

table: 0x7be9e488 { 02-09 17:23:19.215: I/Corona(13878): [name] =\> "storeTransaction" 02-09 17:23:19.215: I/Corona(13878): [transaction] =\> table: 0x7be9e488 { 02-09 17:23:19.215: I/Corona(13878): [state] =\> "failed" 02-09 17:23:19.215: I/Corona(13878): [errorString] =\> "User canceled. (response: -1005:User cancelled)" 02-09 17:23:19.215: I/Corona(13878): [isError] =\> true 02-09 17:23:19.215: I/Corona(13878): [errorType] =\> -1005 02-09 17:23:19.215: I/Corona(13878): } 02-09 17:23:19.215: I/Corona(13878): }

instead of error string saying:

Unable to buy item (response: 7:Item Already Owned) 

It means we have no way of differentiating between when a user has genuinely cancelled a transaction, or if this has happened. We can’t make the assumption that this error has happened and grant them the items anyway, otherwise it would be really easy for user’s to exploit.

However there is a “solution” but we don’t understand why it is working. If we purchase a different consumable item successfully and then call restore, the original “owned” purchase that was stuck in limbo appears as expected in our restorable items. So then we can consume it and make it available for purchase again.

Any ideas what could be happening here?

Edit:

Just found this on stackoverflow: http://stackoverflow.com/a/26682883/1182532

It seems that the IABhelper java code will return error code -1005 instead of 7, it’s hardcoded to do that.

So now my question is: is that in fact still the case, or have Google fixed this and now the Corona plugin need to be updated? And also, why would making a second purchase suddenly add the first purchase to the restorable items data returned by Google?

The latest Google Play IAP plugin is now returning the “already owned” code which is great!

When we detect this happening we call store.consumePurchase() like we would with a regular purchase, but for some reason the consume doesn’t seem to be processed by Google.

The plan was that if we detect the purchase is already owned, we reward the user with the item (as we normally would with a purchase) and then consume it. But as things are now, the consume fails so the user would actually be able to get lots of free items for just one purchase, because the “already owned” message keeps appearing.

 

If you wait long enough (I think about 15 mins but I’m not sure yet), then suddenly the IAP item becomes purchasable. It’s as if the consume request does go through, but with a huge delay. 

 

I’m not sure whether the issue lies in Google’s API or in the plugin. Has anyone at Corona ever noticed anything like this?

Hi Alan,

Well, with IAP in general, basically nothing on the server side (Apple or Google) happens “instantly”. This is just the nature of IAP, and you have to assume that purchases may take some time to be processed.

I’m not sure how you are “detecting the purchase is already owned” so I can’t provide any specific assitance on that point at the moment.

Take care,

Brent

The GP IAP plugin was updated 2 days ago. 

When we make a consumable purchase which Google determines is “already owned” because it was not previously consumed, Google returns “Error code 7: item already owned”. This is then passed to the plugin, which passes it to our IAP listener, and that’s how we determine it is already owned. Note that this is referring to consumables, as non-consumables can be checked easily by calling restore().

This is the part of our listener where that would be captured:

elseif event.transaction.state == "failed" then      if tostring(event.transaction.errorType) == "-1050" or tostring(event.transaction.errorType)=="-1005" or event.transaction.errorString == "User canceled. (response: -1005:User cancelled)" then         if storeCallback then              storeCallback(nil, "Purchase cancelled, you have not been charged")         end     elseif (tostring(event.transaction.errorType) == "7" or event.transaction.errorString == "Unable to buy item (response: 7:Item Already Owned)") then      storeCallback(lastProductID, "Item Already Owned")     end end

The storeCallback function is in our shop scene, which is where it then takes the lastProductID, checks which item that is, rewards it to the user, and then calls store.consumePurchase()

For a regular purchase, the consume function does happens instantly for all intents and purposes. I can make a purchase, then the same again, and again…

When a network interruption causes a purchase to become stuck in this way, calling consume is not working correctly, and you have to wait some length of time before it resolves itself. When store.consumePurchase is called during this time for this purchase, there is no callback to the store’s listener to say whether it has succeeded or failed. To me this means that either Google is failing to process it there and then, or the plugin is failing to send to Google / return to lua.

Can I get you to file a bug report on this?  You will need a small sample app that can demonstrate the issue.  Package it and any thing needed to build the app in a .zip file including config.lua, build.settings for SDK builds, project files for Enterprise builds, etc.

Please post the case id # back here when you get the email from the bug tracker.

Thanks

Rob

Danny Chan pointed me to a workaround. It turns out that the Google Play Store app caches information locally on the device, and this was causing the issue. Clearing the cache allowed the item to be consumed the next time we tried it, and then the item can be purchased again. 

Not a perfect solution, but also a Google problem rather than a Corona one it seems.

Thanks Danny (and everyone else at Corona)!

I got V3 working with full in game currency and remove ads plus a full store i wish i could give it to you all for free. But I have college bills to pay $4.99 http://romangaming.com/short-codes