Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

ProcessPurchase is not called after application restart on IOS

Discussion in 'Unity IAP' started by ds73, Feb 11, 2021.

  1. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    Unity 2020.2.1
    UnityIAP: v2.2.7

    Hello,

    We found that ProcessPurchase is not called after restarting the app on IOS if the purchase was completed after the app was closed.

    Steps to reproduce:
    1. Initiate an in-app purchase
    2. Kill the application before the native window appears
    3. Confirm purchase at the native window
    4. Run the application

    ProcessPurchase does not appear after OnInitialized completes
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    @ds73 Kill the application before the purchase window appears, yet the purchase window still appears? Interesting, we'll have to test that. What type of product is it, are you able to purchase again? I'm suspecting you might receive Duplicate Transaction. How are you killing the app?
     
  3. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    Yes, the native window appears after the application is killed, if the purchase was initiated.
    This is a consumable product.
    There is no duplication of the transaction. If you buy this product again, then only one ProcessPurchase is called
    The application is killed by throwing it out of the tray
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    So the user pays twice for one actual consumable purchase, that's not good. I'll look into this. There is a chance that even a native iOS app might see this behavior, so no guarantees.
     
  5. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    It looks like it worked correctly in version 2.2.5. But there was an extra ProcessPurchase called for Android in a similar situation (this is fixed in 2.2.6)
     
  6. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    2.2.6 is a stable release. If you are only seeing this issue with 2.2.7, then you'll want to use 2.2.6 for now.
     
  7. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    I have a stupid question: how to downgrade the package? It doesn't present at "Packages: In Project" or "Packages: Unity Registry". And "Packages: My Assets" has no version selection
     
  8. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    And one more thing, if you make a purchase of another product, then both of them will be in the received recipe, but only the new purchase will be finalized. Am I correct in understanding that the ConfirmPendingPurchase must finalize all purchases in the recipe?
     
  9. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    We tested the work on version 2.2.5 again and found out that it still does not work in it either. So I don't see any point in testing 2.2.6
    It was found that if you call RestoreTransactions, then this purchase will be processed. However, this is the wrong path that we cannot take. Because it requires the user to enter a password even if he hasn't bought anything yet
     
  10. John_Corbett

    John_Corbett

    Unity Technologies

    Joined:
    May 17, 2019
    Posts:
    151
    Hi @ds73,

    If you check if the consumable has a receipt when IAP initializes, you could call
    ConfirmPendingPurchase 
    on that product. (This is the correct thing to do and not
    RestoreTransactions
    , as you pointed out). Does that work for your problem?

    As for downgrading the PackageManager version, for 2020.2, it's as follows:

    First, expand the list of versions by clicking the right-facing triangle next to the version, then click See All Versions

    upload_2021-2-12_17-48-56.png

    You should then be able to scroll to the version you want. Select it and run the update.

    upload_2021-2-12_17-49-23.png
     
    Last edited: Feb 15, 2021
  11. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    Sorry, I did not understand what ConsumePendingPurchase is and where to find it?
    PackageManager: Unity Registry contains only "In App Purchasing", not "Unity IAP" (it is downloaded separately and visible in PackageManager: My Assets). But I already found old versions here on the forum, thanks
     
  12. John_Corbett

    John_Corbett

    Unity Technologies

    Joined:
    May 17, 2019
    Posts:
    151
    Oops! I meant to type ConfirmPendingPurchase(), and not Consume. Sorry about that I will fix my post above.

    It's a function of IStoreController.
     
  13. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    ConfirmPendingPurchase requires a Product as a parameter. If we pass null and call it at the end of OnInitialized, then nothing happens.
     
  14. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Correct. This method assumes you are receiving a ProcessPurchase during initialization and the Product is passed as the parameter. So your first step is to confirm whether ProcessPurchase is being triggered, you can place a Debug.Log statement there as in the Sample IAP Project, or step debug using Visual Studio.
     
  15. ds73

    ds73

    Joined:
    Sep 1, 2020
    Posts:
    9
    The actual problem is that ProcessPurchase is not called after initialization. But if you call RestorePurchase, then ProcessPurchase will be called.
     
  16. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    That is expected behavior on iOS. Restore requires a user action.
     
  17. zz2020

    zz2020

    Joined:
    Jul 8, 2020
    Posts:
    6
    I also encountered this problem, and if I place an order again, the value of Payload is the value of the previous order, and the value of TransactionID is the new order number.
     
  18. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide steps to reproduce, versions, the code you are using, etc.
     
  19. zz2020

    zz2020

    Joined:
    Jul 8, 2020
    Posts:
    6
    Unity 2019.4.16
    UnityIAP:1.22.0

    Steps to reproduce:
    1. Initiate an in-app purchase
    2. Kill the application before the native window appears
    3. Confirm purchase at the native window
    4. Run the application
    5. Initiate an in-app purchase(Buy different goods)
    6. Receive ProcessPurchase callback data
     
    Last edited: Mar 1, 2021
  20. zz2020

    zz2020

    Joined:
    Jul 8, 2020
    Posts:
    6
    UnityIAP 2.2.7 also have this problem
     
  21. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    These steps are expected. What is the specific issue?
     
  22. zz2020

    zz2020

    Joined:
    Jul 8, 2020
    Posts:
    6
    There is a problem with the returned "Product" data, and the "Payload" is the value of the last interrupted order. This does not match "transactionID".
     
  23. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry, we will need additional specifics. What transactionID are you comparing to, for example.
     
  24. zz2020

    zz2020

    Joined:
    Jul 8, 2020
    Posts:
    6
    Sorry I am using Google Translate to talk to you, I hope you can understand.
    After performing the above operations, the Payload in the returned Product.receipt data is the data of the last abnormal operation order. When I use Payload to request verification from Apple, I will find that the TransactionID returned by Apple does not match the Product.transactionID.
     
  25. nicholasr

    nicholasr

    Unity Technologies

    Joined:
    Aug 15, 2015
    Posts:
    183
    @zz2020 - I apologize before I ask a question, and giving an answer, because I do not understanding the problem completely.

    To help me better understand the problem, let me list some ideas:
    One hypothetical problem:
    • If a user owns two iOS devices (example: user owns iphone and also owns ipad) the user can purchase a Product on iphone.
    • User must synchronize the ipad. They must download the IAP Product into the receipt file on the ipad: Apple has features (Unity IAP API) IAppleExtensions.RestoreTransactions and IAppleExtensions.RefreshAppReceipt.

    Maybe this helps?

    Apple RestorePurchase (RestoreTransactions) changes Transaction ID values. RestoreTransactions creates new Transaction ID for old purchases for all owned NonConsumables, and Subscriptions. ( RestoreTransaction does not create new Transaction ID for consumables, because that would be bad, and give a user "+1000 gold" every time the user presses "Restore" button. )

    1. Buy Non-Consumable Product ID "A"
    2. ProcessPurchase: Product ID "A", Transaction ID == "4321"
    3. IAppleExtensions.RestoreTransactions()
    4. Optional "User Login" dialog displayed by iOS ... click button ...
    5. ProcessPurchase: Product ID "A", Transaction ID == "4322" (different)

    Is this the problem?