Search Unity

Google Play IAP Problem

Discussion in 'Unity IAP' started by bardia68, Jul 13, 2021.

Thread Status:
Not open for further replies.
  1. bardia68

    bardia68

    Joined:
    Apr 1, 2016
    Posts:
    7
    Hi everyone!

    We encountered a big problem since we upgraded our In-app purchase from old "AIDL" to "Unity In App Purchasing". The problem is simple and critical:

    "Some users somehow manage a way to never pay their bill but the game charges their inventory!"

    We do not know how some users manage to do this issue but due to some unknown reason and conditions (at least unknown to us!), a user starts in app purchase order, even though the corresponding order is in "Payment pending" state in the Google Play Console, the "ProcessPurchase" is called in our game and this transaction is treated as a valid transaction. Then after a while, the transaction status will change to either "Canceled" or "Payment declined".

    I think that these users make this on purpose and it is not accidental, because these users only buys our most expensive IAP Items rapidly several times a row. Also we know that our IAP system is working correctly because we have checked it using our test users and test devices.

    Has anybody encountered the same problem or know the solution?
     
  2. TeemuTee

    TeemuTee

    Joined:
    Jun 10, 2016
    Posts:
    21
  3. bardia68

    bardia68

    Joined:
    Apr 1, 2016
    Posts:
    7
    We implemented SetDeferredPurchaseListener (as you said) but the problem still exists.
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    You need to ensure to return Pending instead of Complete from ProcessPurchase until the purchaseState is not 2 and not 4. You'll need to parse the receipt to do so.
     
    Petr777 and IAVAR like this.
  5. bardia68

    bardia68

    Joined:
    Apr 1, 2016
    Posts:
    7
    I am a little confused here, I checked IAP examples at this thread:
    https://forum.unity.com/threads/sample-iap-project.529555/
    but I did not find any thing related to the purchaseState or how to parse receipt. How may I parse receipt?
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    In ProcessPurchase, you can obtain the receipt via the passed argument args.purchasedProduct.receipt. We will be exposing the purchaseState as a property in a future release. For now, you would need to parse the receipt yourself.
     
  7. WilliamOD

    WilliamOD

    Unity Technologies

    Joined:
    May 31, 2021
    Posts:
    16
    Hi @bardia68 another solution would be to use the GooglePlayExtension.IsPurchasedProductDeferred API.
    So in your ProcessPurchase function, you would use GooglePlayExtension.IsPurchasedProductDeferred on your product and if the function returns true then you should return Pending.
     
    JeffDUnity3D likes this.
  8. bardia68

    bardia68

    Joined:
    Apr 1, 2016
    Posts:
    7
    I just find out that I can use GooglePlayReceipt.purchaseState instead of manually parse the receipt:
    Code (CSharp):
    1. var result = validator.Validate(receipt);
    2. foreach (var productReceipt in result)
    3. {
    4.        if (productReceipt is GooglePlayReceipt google)
    5.        {
    6.                     // This is Google's Order ID.
    7.                     // Note that it is null when testing in the sandbox
    8.                     // because Google's sandbox does not provide Order IDs.
    9.                     orderId = google.orderID;
    10.                     token = google.purchaseToken;
    11.                     purchaseState = google.purchaseState;
    12.                     if ((int) purchaseState == 4)
    13.                     {
    14.                         ParsisDebug.Log("Deferred IAP, Not bought yet!");
    15.                         return PurchaseProcessingResult.Pending;
    16.                     }
    17. }
    Thank you for the hint, I just ended up using aforementioned piece of code!

    By the way I think this is a BIG problem that every Android game developer WOULD DEFINITELY encounter, so I think that it would be wise to mention this problem clearly in Unity Documents and every IAP Sample projects.
     
    Last edited: Jul 22, 2021
    Petr777, afilkin, Felicionato and 4 others like this.
  9. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Totally agree! This is a new feature from Google, documentation updates are on the way. And thanks for the code!
     
    bardia68 likes this.
  10. Darktemplar1

    Darktemplar1

    Joined:
    Apr 26, 2021
    Posts:
    6
    That is very strange. UnityProcessPurchase API should only be called when the purchase completes as mentioned in their documents here. Also, as shown in Unity's docs below, ProcessPurchase is only notified after a purchase succeeded step when the transaction is complete from the stores, not before or while it's pending or deferring:

    At the point it gets back to the App in the ProcessPurchase() call, the purchase should be complete as mentioned in the docs.

    Thus, this sounds like a bug on the Unity IAP Plugins due to the recent google change @JeffDUnity3D
    If so, is there going to be a fix for this that we can track?
     
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    The diagram and the documentation refers to the Google Play Billing Library v2, we are now using v3 as required by Google. And v4 is on the way! The behavior is expected and is how our major studios are handling it.
     
  12. BBO_Lagoon

    BBO_Lagoon

    Joined:
    Mar 2, 2017
    Posts:
    200
    Hi, I use in app package v4 and implemented the deferred purchase as in the exemple:
    Code (CSharp):
    1. if( m_GoogleExtensions.IsPurchasedProductDeferred( args.purchasedProduct ) )
    2. {
    3.     return PurchaseProcessingResult.Pending;
    4. }
    But I still get purchasesState = 4 going to my server validation process. Doesn't this IsPurchasedProductDeferred function suposed to check this purchaseState ?
     
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We are not sending it to your server, you are. It's up to you if you want to validate the receipt. The code you provided is correct, continue to return Pending if it's a deferred purchase with purchaseState = 4. I don't think you need to check the receipt until purchaseState = 1 (when you actually award the product to the user), but it's up to you.
     
  14. BBO_Lagoon

    BBO_Lagoon

    Joined:
    Mar 2, 2017
    Posts:
    200
    to be more clear here is my code in ProcessPurchase

    Code (CSharp):
    1. if( m_GoogleExtensions.IsPurchasedProductDeferred( args.purchasedProduct ) )
    2. {
    3.     return PurchaseProcessingResult.Pending;
    4. }
    5.  
    6. // HERE I DO THE SERVER SIDE VALIDATION
    7.  
    8. // then
    9. return  PurchaseProcessingResult.Complete;
    It seems that m_GoogleExtensions.IsPurchasedProductDeferred( args.purchasedProduct ) doesn't returns true if the purchaseState = 4 as on my server side validation I receive some receipt with purchaseState = 4.

    Is it a bug in IsPurchasedProductDeferred function or do I have to handle it myself ?
     
    Last edited: Aug 18, 2021
  15. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I'm not familiar with that method myself, I have been recommending this code https://forum.unity.com/threads/google-play-iap-problem.1140367/#post-7351220
     
    bardia68 likes this.
  16. makomarkus

    makomarkus

    Joined:
    Oct 28, 2020
    Posts:
    61
    I think the
    GooglePurchaseState
    enum needs to be updated in the docs if we're expected to handle
    4
    , as currently only
    0-2
    are documented:
    https://docs.unity3d.com/Packages/c....Purchasing.Security.GooglePurchaseState.html

    I understand that C++ won't cause an exception for enum's that are out of bounds, but it definitely would help in finding a solution to this problem to know what values we can expect. Also I'm curious now what 3 equals to.
     
  17. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Those are Google values, not Unity. And yes, they need to update their docs (then we can). There is not a 3 value to my knowledge.
     
  18. makomarkus

    makomarkus

    Joined:
    Oct 28, 2020
    Posts:
    61
    roointan likes this.
  19. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  20. makomarkus

    makomarkus

    Joined:
    Oct 28, 2020
    Posts:
    61
    I see now where the confusion comes from. The 4 is being returned from their API in the json, whereas the 2 is returned from their library, which has this implementation :

    Code (CSharp):
    1. public int getPurchaseState() {
    2.     switch(this.zzc.optInt("purchaseState", 1)) {
    3.     case 4:
    4.         return 2;
    5.     default:
    6.         return 1;
    7.     }
    8. }
    So we're basically working with the raw json return, vs with the documented
    Purchase.PurchaseState.PENDING
    .
    But I think that would mean they have a documentation for the pending state, right. So would be good to have this also mentioned in the Unity IAP docs.
     
  21. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, the Unity IAP docs need updating! This has already been stated. So does Google. We would likely not update ours until we see it in the Google enum documentation. https://developer.android.com/reference/com/android/billingclient/api/Purchase.PurchaseState is outdated
     
  22. Leonid

    Leonid

    Joined:
    Aug 20, 2013
    Posts:
    90
    Hello!
    Some time ago I implemented the PurchaseState state check and today I got this message in the Google Play Console:

    "We've noticed that you don't always acknowledge the delivery of in-app content to users after they've paid outside your app. Or you don't integrate pending transactions correctly. As a result, payment methods that require pending transactions, like paying with cash, have been turned off. Other payment methods aren't affected. Contact us once you've fixed the issue so that we can turn these payment methods back on."

    Anyone got this too? Should I worry about it? And the main question - is the current version of Unity IAP allows correct workflow for these deferred payment methods?
    Thank you!
     
    Zeeppo-Games likes this.
  23. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Are you returning Pending until the deferred transaction is paid, then return Complete from ProcessPurchase when they do? However if you are using Codeless IAP, the behavior would be expected. Use Scripted IAP instead.
     
  24. Leonid

    Leonid

    Joined:
    Aug 20, 2013
    Posts:
    90
    I'm using Scripted IAP, and I return "Pending" state if GooglePlayReceipt.purchaseState == 4 and "Complete" state in all other cases
     
  25. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    I believe you also want to return Pending if purchaseState = 2
     
  26. Leonid

    Leonid

    Joined:
    Aug 20, 2013
    Posts:
    90
    Thanks for the advice!
    However, I don't think this will solve the problem outlined in the message Google sent me. I hope there will be more clarity on this next week as more people get this message.
     
  27. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  28. Leonid

    Leonid

    Joined:
    Aug 20, 2013
    Posts:
    90
  29. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, it's been a bit confusing for us also. purchaseState = 4 is not documented anywhere (so far it appears), and it seems that 2 and 4 are the same thing. We are hoping this becomes more clear in the next version of the Google billing library v4.
     
  30. vokh_demetro

    vokh_demetro

    Joined:
    Dec 4, 2019
    Posts:
    7
    Hi, I have this problem with purchase. If I open the game, go to the play market and activate the gift code, and return to the game, I will make a purchase error. I use 4.1.4 unity purchase. purchase error.PNG


    UPD: The error remained, but the purchases were made.https://forum.unity.com/threads/android-in-app-purchasing-issue-with-play-store-promo-api.1218147/
     
    Last edited: Apr 19, 2022
  31. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Do non-gift-code, normal purchases work OK? Make sure you add yourself as a tester on Google Play, accept the tester invite on your device, and download your game from Google Play. Your issue is likely separate from this thread, I'm locking this thread now. If you continue to have issues, please open a new thread.
     
Thread Status:
Not open for further replies.