[Closed] Bizarre IAP behaviour on Android

In a recent build our IAP dialogs on Android have been showing up differently:

Once we purchase an item, instead of the normal message, we get the message “You’ve added X to your library”:

All our purchases are marked as consumables. When purchasing, no transactionID is returned with the product.

Does anyone know what’s going on here? The purchasing code hasn’t been touched since I made the change to Unity IAP, and worked when testing them. I have updated Unity versions since (currently on 5.3.5p4), so I guess I’ll have to redownload the old one, which is annoying.

Some weird additions:

  • In the mail from Google about the transaction, the order number is coming in as a string of random chars rather than an normal transaction: e.g. “Order number: onhgdhidhdablpedjbjjibck” or “Order number: pgaeenegbjfmjhojijgahhhd”. Previous successful transactions would have a transaction ID like “Order number: GPA.1345-9954-0950-90739”
  • When I look at the Order History in Google Play > Account > Order History, the transactions that worked from a few days ago (before the 23rd) are all marked with a price, while these new ones (23rd) are marked with a price €0.00:

It kind of seems like the purchase is coming in an a non-consumable or a restore, though the flow hasn’t changed since I originally did it, and when I print out all the products before the call to InitiatePurchase(), they all print as “Consumable”

So does this look like a Unity bug, or a Google Play bug?

Thanks

Can confirm the same behaviour when building on 5.3.5f1. Even downloading the current APK from the app store (i.e. before Unity IAP were included) will show the same, so I’m at a bit of a loss here. Any indications of where to look would be greatly appreciated.

Same here, started happening out of the blue for no apparent reason at all. This could be affecting a lot of live apps on the store. Come on guys.

It’s possible that this is a recent change in Google Play affecting test purchases. From a mail from Google Play:

Hello Google Play Developer,
Beginning June 20, 2016, we’ll be making a change to test purchases for one-time in-app purchases (IAPs).
Previously, test purchases for one-time IAPs generated order IDs. Starting June 20, 2016, one-time IAPs will not generate order IDs and will not appear in the Merchant Center. This behavior already applies to subscription IAPs.
You can learn more about testing in-app billing in the Android Developers Help Center (which will be updated with the information above on June 20).
Thanks for supporting Google Play,
The Google Play Team

On the page itself, there’s a note:

Note: For test purchases, leave the orderId field blank. You can use the purchaseToken field to identify test purchases.

I’ve yet to find an example of how they do that; the purchase token is either encrypted or compressed base64.

I haven’t been able to 100% confirm that this is the case though

This seems like the case, which would mean a real purchase should work as expected?

Hi @Cypras , @Nicolas1212 , and others,

Thanks for bringing this to our attention. This is definitely coming from a change from Google, but we are looking into/testing what, if any, effects it may be having on Unity IAP. Based on what the changes are and the description from Google, these changes should be localized to sandbox testing, and not affect live purchases.

[EDIT] Based on the posts, it does not sound like anyone is having any errors because of this change, but if so please post them here. [/EDIT]

We will update to this forum when we know more.

We are having the same issue

Can confirm too. Happened the day we were going to release our update. Lost 2 hours and a few euros to figure out that this was a change made by Google. They should have put this as an alert in the Google Play Console…

Hi there, the problem for us is that we can’t cancel non consumable in-app purchases right now! they used to appear in the merchant center, but after the 20th June they are not appearing anymore. So Talking with Google Developer Support they are telling me to go to a play store page under Account in order to cancel this orders… but you can’t! Are any of you solved this mystery?

Thanks.
Best.

We are working on a change to fix this, which is indeed caused by Google’s recent change. It should only be affecting payments made in Google’s sandbox, not their live system.

Hi Banderous,

We’ve bought Unibill from Asset Store for full price and you have removed it from the market in a week after we started using it (It wasn’t good customer experience at all). We can’t move to Unity payment because we still need to use Unity 4.7.1 for some serious reasons.

Now we have exactly same problem with latest version of Unibill, everything was working perfect till the last week, and now it is not…

One more issue I can add is, we tested live payments also, it is actually working but with problems. When you make the first purchase it is working but if you try to buy the product for the second time in the same session it says “You already own this item”. If you refresh the game (Init Unibill) and try again, you can buy any product for one time again but you can’t do it for the second time in the same session.

I hope you will help us by applying the fix to Unibill also. I think something changed at Google side and you could only help us as you promised at Unibill post when shutting down the Unibill development.

Thanks,
Best

This is because you don’t consume the purchase after buying. Unibill may consume them at start, that’s why you have to restart the game to buy it again. Check if you have a consume function in Unibill.

For Unibill you have to call:

public static void initiatePurchase (string purchasableId, string developerPayload = “”)

to start payment and after that everything works with callbacks:

Unibiller.onBillerReady += OnBillerReady;
Unibiller.onTransactionsRestored += OnTransactionsRestored;
Unibiller.onPurchaseFailed += OnFailed;
Unibiller.onPurchaseCompleteEvent += OnPurchased;
Unibiller.onPurchaseDeferred += OnDeferred;

consume is called automatically by Unibill when transaction is completed. Unibill has:

public void finishTransaction (PurchasableItem item, string transactionId)

in billing subsystem to consume the purchase, and it is called (not even a single line of code changed in 12 months).

I guess problem is some way Unibill was parsing transaction id and using it. Now transaction format is changed and Unibill can’t parse it and give empty transaction id (empty string) and record that one as a purchase, that is why you could only make one purchase in one session with same id. But these are all my guesses, Banderous could help me with that.

Has anyone been able to find any information from Google about the change ? Would really like to know if/when it would go live and if they api might have changed to fix it.

We are seeing issues with purchases as well (not just sandbox) on our live games.

We are not sure what is going on but certain players/accounts can no longer successfully complete purchases: the payment goes through but the confirmation from Unibill doesn’t come. Seems it parses something wrong and gets stuck (never returns the result).

Anybody has more information on what Google changed or how Unibill handles it wrong now?
We are trying to debug but without success so far.

Please contact support@outlinegames.com for a Unibill that uses purchase tokens where order ids are no longer supplied by Google.

@rbenami Live Apps should not be affected by Google’s recent change. Can you get some adb logging?

(Quoting post with question as it was posted on the briefly-live “new” forums, and has not been transitioned back to these forums)

Hi @TheGuru and @Arganoid1 ,

It sounds like the only ways Google gives for clearing out test purchases right now is either to consume them, or wait 14 days when they will be deleted. See the update part of the question in this StackOverflow page: android - Cancelling orders on Google Play IAB test purchases after June 20, 2016 - Stack Overflow

To “consume” non-consumables in Unity IAP, the current workaround would be to:

  1. Purchase the item as a non-consumable
  2. When you want to clear out the purchases, change the declaration of the item to consumable, and run the app, consuming all the purchases
  3. Change back to non-consumable to test again.

{copy-pasting old reply made before the forum rollback}

==MESSAGE1==

To follow-up on @Banderous’s post, a fix version is nearly complete. Unity IAP 1.6 should ship in a few hours.

I’ll reply again here when available. Also one should see inside Unity a small notification in the Service window announcing an upgrade being available. Click “Import” in the Services window to update.

Explanation: We believe conflation of two issues is causing trouble here - Google’s June 20 change to their test sandbox whereby “orderId” is no longer returned for consumables impacted Unity IAP since Unity IAP used orderId internally as its unique transaction ID. An email from Google annoucing this change was distributed to some Google Play developers, cited here by @Nicolas1212. Unity IAP 1.6 addresses this change by detecting an empty orderId and uses Google’s purchaseToken as a replacement for its transaction ID. This fixes the case a tester purchases a consumable, then a non-consumable, then a consumable, and after that seeing a bug where the tester could re-purchase the non-consumble.

The second issue can be seen in the logs with “In-app billing error: Unable to buy item, Error response: 7:Item Already Owned”, which to us appears to be a long standing Google issue relating to Google’s test purchase backend and the Google Play Store installed on a device. This bug seems to occur sporadically regardless of Unity IAP, especially with Google’s static products, e.g. product ID android.test.purchased. See this 2013 discussion of the same error message: In-App Billing test: android.test.purchased already owned - Stack Overflow. I am guessing this Google bug is now being triggered as a side effect of Unity IAP 1.5 struggling to understand how to convert an empty (“”) orderId into a transaction ID. There seems to be a strong coincidence between seeing an increased frequency of “Item Already Owned” errors in developer’s Android Logs with the June 20 Google IAB backend change. To be clear, this is a guess based upon coincidence. Regardless, it’s a severe issue when testing IAP since a test user’s account will be corrupted to a degree by this.

[ Important Note: 1.6 will fix the first issue. We expect the second issue will stop recurring after 1.6. However it may require a maintenance process of “clear your Google Play Store and also your Game cache, then reboot” for each affected test user. Concerningly, we have not successfully cleared this second issue on our local test devices and accounts. I invite other Android expert’s advice on clearing this error. Production non-test IAP is unaffected by this issue, fortunately. ]

We’re hoping this will fix the problems reported on this thread. And please let us know if you continue to experience issues after the change.

==MESSAGE2==

Thanks for your patience! 1.6 has been released.

[1.6.0] - 2016-7-7

Added

  • Support for redeeming Google Play promo codes for IAPs.

  • IAndroidStoreSelection extended configuration for accessing the currently selected Android store.


var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

Debug.Log(builder.Configure<IAndroidStoreSelection>().androidStore);

Fixed

  • Apple Stores - ProcessPurchase not being called on initialize for existing transactions if another storekit transaction observer is added elsewhere in the App. This addresses a number of issues when using third party SDKs, including Facebook’s.

  • Google Play - sandbox purchases. In Google’s sandbox Unity IAP now uses Google’s purchase token instead of Order ID to represent transaction IDs.

  • iOS not initializing when IAP purchase restrictions are active. IAP will now initialise if restrictions are active, enabling browsing of IAP metadata, although purchases will fail until restrictions are disabled.

  • Instantiating multiple ConfigurationBuilders causing purchasing to break on Google Play & iOS.

Thanks for your patience! 1.6 has been released.

Where can we find the version number? It doesn’t seem to be posted anywhere

Hi @Nicolas1212 ,

You can find out which version you currently have imported by going to Assets → Plugins → UnityPurchasing → Changelog.md. The first line of the file lists the version of IAP.

1 Like