Search Unity

Unity IAP doesn't consume consumable acknowledged purchases

Discussion in 'Unity IAP' started by Olegleg, Apr 13, 2021.

  1. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Unity IAP doesn't consume consumable acknowledged purchases.

    I am using up to date (https://issuetracker.google.com/u/5/issues/184760924) Method: purchases.products.acknowledge on the server to acknowledge purchases.

    I know, that PurchaseProcessingResult.Complete automatically acknowledges purchases. But I should Acknowledge purchase on the server side to fight frauds, because my game is online game and player's inventory is stored on the server.

    Acknowledged consumable product starts to behave as Non-consumable in Unity IAP, because App doesn't allow to purchase it again and tries to purchase it every app reinstall.

    How to reproduce the problem:
    1. BuyProductID;
    2. On ProcessPurchase send receipt to server;
    3. Optional: On the server validate receipt and give the player product, if everything is ok;
    4. Important: Acknowledge purchase to avoid refund after 3 days. (I am using .NET and Google.Apis.AndroidPublisher.v3 - Purchases.Products.Acknowledge());
    5. On ProcessPurchase return PurchaseProcessingResult.Pending;
    6. Close the App;
    7. Wait a minute;
    8. Relaunch App and Consumable product becomes "Non-Consumable" and all problems, listed before, appears.

    What is not working as expected:
    1) BuyProductID - ProcessPurchase - PurchaseProcessingResult.Pending - Purchases.Products.Acknowledge() on the server - Relaunch app - ProcessPurchase - PurchaseProcessingResult.Complete
    2) BuyProductID - ProcessPurchase - PurchaseProcessingResult.Pending - Purchases.Products.Acknowledge() on the server - Relaunch app - ProcessPurchase - PurchaseProcessingResult.Pending - ConfirmPendingPurchase

    And after this two ways, the player's account become "broken". He can't buy this product again and this product will ProcessPurchase every app reinstall

    And also,
    What is not working as expected:
    1) Redeem promo code in Google Play - Google automatically Acknowledge - Open App - ProcessPurchase - PurchaseProcessingResult.Complete
    2) Redeem promo code in Google Play - Google automatically Acknowledge - Open App - ProcessPurchase - PurchaseProcessingResult.Pending - ConfirmPendingPurchase
    3) Redeem promo code in app - Google automatically Acknowledge - ProcessPurchase - PurchaseProcessingResult.Pending - Relaunch app - ProcessPurchase - PurchaseProcessingResult.Complete
    4) Redeem promo code in app - Google automatically Acknowledge - ProcessPurchase - PurchaseProcessingResult.Pending - Relaunch app - ProcessPurchase - PurchaseProcessingResult.Pending - ConfirmPendingPurchase

    The player's account becomes "broken" too, because the product, redeemed with promo code, is acknowledged immediately by Google, but not consumed.

    It is the same issue: Unity IAP doesn't consume consumable acknowledged purchases.

    More about these problems here:
    https://forum.unity.com/threads/bug...-confirmpendingpurchase.1023700/#post-6988988
    https://forum.unity.com/threads/android-promo-code-works-every-time-player-starts-the-game.1085549/

    Please, fix this problem.
     
    Last edited: Apr 13, 2021
  2. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Logs with detailed description. My code is almost the same as Sample IAP Project. All Debug.Log statements on the same place.

    1.txt - First launch of app with new account and new product - Works good.
    2.txt - BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Complete - Works good.
    3.txt - Again BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Complete - Works good.
    4.txt - Relaunch app - Works good.
    5.txt - Again BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Complete - Works good.
    6.txt - Relaunch app - Works good.
    7.txt - BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Pending - Works good.
    8.txt - Again try BuyProductID - Works good.
    9.txt - Relaunch app - ProcessPurchase - return PurchaseProcessingResult.Pending - Works good.
    10.txt - Again try BuyProductID - Works good.
    11.txt - Relaunch app - ProcessPurchase - return PurchaseProcessingResult.Complete - Works good.
    12.txt - BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Complete - Works good.
    13.txt - Relaunch app - Works good.
    14.txt - BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Pending - Works good.
    Now Purchases.Products.Acknowledge() on the server, using developer payload = null, AndroidPackageName, purchaseId and purchaseToken from receipt:
    AndroidPublisherService().Purchases.Products.Acknowledge(null, AndroidPackageName, purchaseId, purchaseToken);
    15.txt - Again try BuyProductID - ProcessPurchase - return PurchaseProcessingResult.Pending - Not working. Unity IAP tries to ProcessPurchase after PurchaseFailureReason: DuplicateTransaction. Compare working 8.txt with 15.txt.
    16.txt - Relaunch app - ProcessPurchase - return PurchaseProcessingResult.Complete - Not working. Compare working 11.txt with 16.txt
    17.txt - try BuyProductID - Not working.
    18.txt - Relaunch app - Not working.
    19.txt - try BuyProductID - Not working.
    20.txt - Reinstall app - ProcessPurchase - return PurchaseProcessingResult.Complete - Not working.
    21.txt - try BuyProductID - Not working.
     

    Attached Files:

    • logs.zip
      File size:
      10.5 KB
      Views:
      363
    Last edited: Apr 13, 2021
  3. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Do not acknowledge products server side, we do this for you on the client. The behavior is not guaranteed. The typical flow is to validate receipts only server side. You return Complete from ProcessPurchase, but do not award the product if the receipt validation fails.
     
  4. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    @JeffDUnity3D Just to clarify, are you saying to support Unity IAP servers have to implement their own system to acknowledge fulfilled purchases?
     
  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Nope, it's all done on the client. Don't acknowledge purchases on a server, just validate the receipts.
     
  6. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    Fulfillment happens on the server not the client. If you don't mark a receipt as acknowledged they can just send it again.

    If you don't have a mechanism to mark a receipt as acknowledged and the server is simply validating the receipt and then fulfilling it, then that receipt can be sent again unless the server has some way of marking the receipt as fulfilled.
     
  7. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, we acknowledge on the client. Users can buy as many consumables as they want. The store APIs won't let the user purchase a non-consumable or subscription more than once. You are free to do fulfillment on the server, but don't acknowledge the product there. We already do that for you. If you can offer steps to reproduce without using a server, we may be able to see if there is any issue at our end. Perhaps you could use Postman or similar from a local PC.
     
    Last edited: May 5, 2021
  8. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    The issue is google recommends using acknowledgement to mark purchases as fulfilled. But a game with servers has fulfillment happen on the server not the client.
     
    Menion-Leah likes this.
  9. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    I realize I'm just reiterating. I can try and give and basic example. You have a gems stored on a server. The user buys gems from the playstore gets a receipt for the purchase and sends it to the server for validation. However before the server can send a response to the client the user disconnects. However the server did get the receipt, the server validates the receipt it passes validation and they give the user gems. At this point google recommends that you mark that purchase as acknowledged because the purchase has been fulfilled. If you don't do that then the user boots up again, the purchase comes in again because it's marked as pending so the user sends the receipt to be validated again. The server gets it and without any system for marking receipts as acknowledged goes and validates the receipt again and gives the user gems again.
     
  10. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    Now if the server does mark the purchase as acknowledged then the user can't send the receipt again because it's already acknowledged. However since Unity IAP filters our acknowledged receipts from finishing transaction. The purchase is lost in the system and you can't buy gems anymore.
     
  11. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    As mentioned, you will need to provide specific steps to reproduce without a server. We have no way to try to reproduce this. More importantly, if there is an issue at our end, we would need to use the same steps to confirm any potential fix.
     
  12. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
  13. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    That article is very old. And they are only validating the receipt, not acknowledging the product. onConsumeFinished is done on the client in that example. We are now using the Google Billing Library v3. If you want us to take a look, you will need to provide steps to reproduce without a server. You should be able to make a simple Google API call to reproduce, perhaps using Postman. Perhaps the confusion is in your definition of "acknowledge the product". Are you calling a specific Google API, passing the user context and product info to ack the product from the server that changes the users' product status as seen on Google Play? https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/acknowledge Keep in mind this API is deprecated, developerPayload is no longer supported in the Google Billing Library v3
     
    Last edited: May 6, 2021
  14. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Have you really read my post?
    I wrote you, that this API is up to date.
    And here is a fresh proof from Google team: https://issuetracker.google.com/u/0/issues/184760924
    There is no problem with Google, or with my server, there is only problem with Unity IAP.
    Why don't you want to test and fix this critical bug?
     
    Menion-Leah likes this.
  15. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    We will check
     
  16. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Thank you.
    It is not safe to give a player items on the server without acknowledge.
    For example:
    Player buys gems. We give him gems on server and don't acknowledge. Player close the game in pending status. Player changes Google account on Google play and opens a game. The player will have gems, but after 3 days money will be returned to his card automatically.
    Player has gems, we have no money.
    And it is not the only security problem.
     
  17. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    If the user changes the Google account, how do they have gems? This is a consumable, the new user won't see ProcessPurchase even if the product is in Pending. The original user, yes.
     
  18. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    The user will have gems, because gems are stored on server. And server authorization may be not Google sign-in. It may be Facebook sign-in or email or phone number or something like this.
     
    Last edited: May 6, 2021
    Menion-Leah likes this.
  19. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Unity IAP is specific to the user signed into Google Play (Play Store) on the device. They second account would not see a ProcessPurchase. Unless you mean the UserA allows UserB to play the game without changing the phone profile account, and then they sign in as User A using Facebook, separate from the Google Play user ?
     
  20. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Yes. It is right. So I cannot give player an item on server for online game without acknowledge, because cheater user can change account.
     
  21. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Which cheater user? You have not described a valid scenario yet.
     
  22. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    And also I really want this bug to be fixed for working promo code. As I wrote before, items redeemed with promo codes are created in acknowledged: true status, consumed: false. And Unity IAP doesn't know, what to do with acknowledged items. So it is most likely the same issue. Two bugs will be fixed with one fix :)
     
  23. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    I described a valid scenario before. Server authorization doesn't depend on account, logged in Google play store for the second or next app launch.
    Even Google sign-in will use previous Google account on the next app launch, and will sign in silently.

    Also robbgray described potential security problems.

    We have no server API to consume item. Consumption have to be done on client. We have server API to acknowledge item. We can't give item to user on server without any mark. It is not safe. Acknowledgement for server, consumption for client. I think it is logical. Or acknowledgement + consumption on client for non multiplayer games, that Unity IAP does great.
     
    Last edited: May 6, 2021
    Menion-Leah likes this.
  24. nykwil

    nykwil

    Joined:
    Feb 28, 2015
    Posts:
    49
    @JeffDUnity3D The article is old but the github for it that I linked is kept up to date and uses Google v3 billing API.
     
  25. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    What link are you referring to? This is your first post on this thread. Yes, I missed the original link from that the OP posted. We are checking further here.
     
  26. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    There is no security issue here. Transactions are associated with the user logged into Google Play on the device. If you change the user account on the phone, they won't receive a ProcessPurchase from a transaction generated from another user, regardless if your game has it's own login mechanism. The only scenario that I see is the user who continues to receive ProcessPurchase in Pending state, which goes to your server again, perhaps to award the product again. You want to return Complete on the client in this case, but understood this could be problematic. Can you not look for the duplicate receipt on the server? It should contain the same purchaseToken. Then tell the client to return Complete. Regardless, we are checking further here.
     
  27. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    And it is a security problem, that they won't receive a ProcessPurchase. User will get gems on server, but client will not acknowledge purchase if user changed Google play store account, and Google will return money to user after 3 days. User has gems, we have no money.
    Yes, I done something like this.
     
    Menion-Leah likes this.
  28. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    How will the new user get gems on the server? Please help me to understand. Valid security issues will indeed raise the priority of this issue, but first we would need to understand the scenario. This is my understanding, please correct me

    * UserA owns phone, plays your game and makes a purchase but you have a server error. The transaction is left in Pending so continues to trigger ProcessPurchase on each IAP initialization. (I'm my view, the issue is limited to this scope)
    * UserA logs out of the Play Store, and UserB logs into it with their Google account (or any valid Play Store login)
    * UserB launches your game with their own user account as defined in your game, which is a separate login from their Play Store login. Assume they are a brand new user.
    * During app launch, no ProcessPurchase would be triggered for this user
    * How does UserB now own any content on your server?
     
  29. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    If UserA will not log out from the game, Google Play Store UserB will be logged to UserA account in game.
    Google sign-in, Facebook sign-in or others sign-ins use the previous account and sign-in silently, if user didn't logout.
    So Google Play Store UserB logged in UserA account in game will not get ProcessPurchase and the purchase will not be acknowledged.
     
  30. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    This was my original question on this thread, if servers have to implement their own purchase acknowledgment systems to support Unity IAP. This is not possible for us because our entitlement fulfillment system is shared with other games. And it is setup correctly as per how Google recommends ie acknowledge purchases upon fulfillment.

    "This acknowledgement communicates to Google Play that you have granted entitlement for the purchase."
    https://developer.android.com/google/play/billing/integrate
     
  31. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, this is expected. The problem lies when UserA logs in, and gets caught in the Pending cycle. Your ask is for us to detect that the transaction has been acknowledged on your server, we are checking into this.
     
  32. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @robbgray @Olegleg We could use your help, could one of you code up the curl request or Postman script to Acknowledge the transaction? The sooner we can reproduce, the sooner we can offer an update, thanks. Since it will contain your productID and an actual token, you can send the script to me in a private message. Also, please provide your client code that is calling the server method.
     
    Last edited: May 10, 2021
  33. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    @robbgray @Olegleg Was this flow working in a previous version of IAP? Engineering is asking.
     
  34. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    Unfortunately, I can't code up the curl request or Postman script to Acknowledge the transaction right now.
    The problem exists on 2.2.7, 3.0.1, 3.1.0.
     
  35. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Was this flow working in a previous version of IAP? Engineering is asking.
     
  36. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    I haven't tested it in earlier versions. Only 2.2.7+. Should I downgrade to previous versions?
     
  37. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    It works for us on older version but google is going to require billing api v3 (which is present in newer Unity IAP versions). All new games in august then all games by November.
     
    charles_yoon likes this.
  38. charles_yoon

    charles_yoon

    Joined:
    Oct 18, 2015
    Posts:
    1
    I have similar issue.
    Once using a google promo code,
    When I try to but same product, purchasing is failed with message "Duplicate Transaction"

    Unity version : 2019.2.17f1
    Issued IAP version : over 3.0.1
    Right working IAP version : 1.23.1

    I have same concern about..
    It works for us on older version but google is going to require billing api v3 (which is present in newer Unity IAP versions). All new games in august then all games by November.

    Please check this issue.

    Thank you!
     
  39. IceStormRUS

    IceStormRUS

    Joined:
    Sep 13, 2016
    Posts:
    4
    Hello, we have same problems with pre registration bonus. After receipt validation on our server client try consuming product. Its looks like the product was be consumed, but it generate order on next launch.
    We didn't send anything to google servers
     
  40. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Which version specifically? We would want to do a "diff" between versions to try to see what may have changed.
     
  41. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Slightly different topic, this issue is describing an explicit Google API call. I have confirmed that ConsumePendingPurchase works as expected using the Sample IAP Project v2 and IAP 3.1.0
     
    Last edited: May 24, 2021
  42. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    No need to downgrade, we haven't confirmed if this ever has worked. If this wasn't working in a previous release, we would have no plans to change the transaction flow, too risky for other users.
     
  43. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you reply to my first message back to you? What issue are you seeing, perhaps you have multiple accounts here on the forum?
     
  44. RobbGraySBL

    RobbGraySBL

    Joined:
    Feb 4, 2014
    Posts:
    40
    Sorry clearing things up.

    The working version we are running is 1.23.3. I'm pretty sure the first version we noticed the bug was 2.2.1 and we've tried a few other versions since then.

    Is there an update on the status of this bug? November is fast approaching (date for the required v3 billing update), and we have also noticed that our working version of Unity IAP (1.23.3) is not compatible with newer versions of unity. We are currently on 2019.4.5f1
     
  45. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, I have passed this along to engineering. They are looking into it, no ETA yet however.
     
  46. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    I am using pre registration bonus too. It works like promo code and Unity IAP doesn't consume it.
    My game is in pre registration now and if this problem will not be fixed before launch I will have to use crutch and to give a bonus to the user only once and to ignore ProcessPurchase for this product in future. :(
    But now I don't know what to do with this: "If you decide to use pre-registration rewards, failure to deliver pre-registration rewards to users may result in suspension of your app from the Play Store." Can Google decide that it is failure, because bonuses are not consumed? It will be very pity, if my app will be suspended.
     
  47. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Separate topic, we are also working on promo code support.
     
  48. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    This topic is: "Unity IAP doesn't consume consumable acknowledged purchases". The product, redeemed with promo code, is acknowledged immediately by Google, but not consumed by Unity IAP. It is not separate topic.
    I am pretty sure, if you will fix promo codes, server side verification will be fixed too and vice versa. Logs, behavior and reason of these problems are the same: "Unity IAP doesn't consume consumable acknowledged purchases".
     
    Last edited: May 27, 2021
    Menion-Leah likes this.
  49. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Good point. That's good news then, since we are already working on promo code support.
     
  50. Olegleg

    Olegleg

    Joined:
    Mar 30, 2021
    Posts:
    47
    I have tested a lot of different versions of Unity IAP to confirm.
    Here are my results.
    In versions from 2.2.0 to 3.1.0 the problem exists.
    But in version 2.1.1 and earlier versions everything works great! Unity IAP consumes acknowledged purchases. Acknowledgment on the server works. Promo codes works too.
    So problem appears for the first time in version 2.2.0 with Google Play Billing Library v3.
    Please, fix this problem.
    Tell me please, is version 2.1.1 stable? Can I use it before fix?