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

Question Pending Purchase Not Working

Discussion in 'Unity IAP' started by LeventKaya19, Jul 21, 2022.

  1. LeventKaya19

    LeventKaya19

    Joined:
    Mar 1, 2017
    Posts:
    2
    Hello,

    I have been working on IAP API last few days and pending purchases doesn't seem to fire during Initialization phase on app restart.

    Project settings:
    Unity Version : 2021.2.10f1
    IAP Version : 4.1.2
    Used examples on this thread: https://forum.unity.com/threads/sample-iap-project.529555/

    My IAP flow is basically like this

    Initialization:

    Code (CSharp):
    1.  private void InitializePurchasing()
    2.     {
    3.         if (IsInitialized())
    4.             return;
    5.  
    6.         _catalog =  ProductCatalog.LoadDefaultCatalog();
    7.         var module = StandardPurchasingModule.Instance();
    8.         module.useFakeStoreUIMode = FakeStoreUIMode.StandardUser;
    9.         builder = ConfigurationBuilder.Instance(module);
    10.         SetAllProductIDs();
    11.  
    12.         IAPConfigurationHelper.PopulateConfigurationBuilder(ref builder,_catalog);    
    13.      
    14.         UnityPurchasing.Initialize(this, builder);
    15.      
    16.     }

    Initiate Purchase:

    Code (CSharp):
    1. public void BuyProductID(string productId)
    2.     {
    3.         if (IsInitialized())
    4.         {
    5.             Product product = m_StoreController.products.WithID(productId);
    6.  
    7.             if (product is {availableToPurchase: true})
    8.             {
    9.                 //MyDebug(string.Format("Purchasing product:" + product.definition.id.ToString()));
    10.                 m_StoreController.InitiatePurchase(product);
    11.             }
    12.             else
    13.             {
    14.                 //MyDebug("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
    15.             }
    16.         }
    17.         else
    18.         {
    19.             //MyDebug("BuyProductID FAIL. Not initialized.");
    20.         }
    21.     }
    Process Purchase:

    Code (CSharp):
    1. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
    2.     {
    3.         PurchaseTask(purchaseEvent.purchasedProduct);
    4.        
    5.         return PurchaseProcessingResult.Pending;
    6.     }

    Backend Communication:

    Code (CSharp):
    1. private async void PurchaseTask(Product product)
    2.     {
    3.         ProcessPopup.Instance.OpenProcessingPanel();
    4.         var productID = product.definition.id;
    5.         Task<bool> purchaseTask;
    6.         try
    7.         {
    8.             switch (productID)
    9.             {
    10.                 purchaseTask = //Create a different task depending on product ID
    11.                 break;
    12.             }
    13.             await purchaseTask;
    14.             ProcessPopup.Instance.CloseProcessingPanel();
    15.             if(purchaseTask.Result)
    16.             {
    17.                 m_StoreController.ConfirmPendingPurchase(product);
    18.             }
    19.         }
    20.         catch (Exception e)
    21.         {
    22.             //Exception handling for logger system
    23.         }
    24.     }

    I tried to mimick an unconfirmed purchase by directly returning PurchasTask method. But when I restarted the game on editor IAP didnt fire the pending pruchases on initialize.

    I have checked out the source code to understand how the pending purchases are handled but couldn't really find any code that handles it.

    Only part of the code that I have found that uses PurchasingResult enum is this part in PurchasingManager.cs:

    Code (CSharp):
    1. private void ProcessPurchaseIfNew(Product product)
    2.         {
    3.             if (useTransactionLog && m_TransactionLog.HasRecordOf(product.transactionID))
    4.             {
    5.                 m_Store.FinishTransaction(product.definition, product.transactionID);
    6.                 return;
    7.             }
    8.  
    9.             var p = new PurchaseEventArgs(product);
    10.             // Applications may elect to delay confirmations of purchases,
    11.             // such as when persisting purchase state asynchronously.
    12.             if (PurchaseProcessingResult.Complete == m_Listener.ProcessPurchase(p))
    13.                 ConfirmPendingPurchase(product);
    14.         }
    Also this method is used on ProcessPurchaseOnStart and there is a check whether the product has receipt and transaction ID. I thought this would be the place pending purchases would be found but there doesnt seem to be any products of this sort as it only loads these products from the catalog.

    Is ther something I am missing or doing wrong? I have converted this from codeless iap manager so I thought I might have missed some steps.

    Thanks
     
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    @LeventKaya19 That is not the code used (and recommended) from the Sample IAP Project, not even close. ProcessPurchase will be triggered for transactions still in Pending. I would recommend to get the Sample IAP Project v3 working exactly as it is, with no changes and publish to Google Play testing. Then apply lessons learned to your own project. This way, your game is never "broken" https://forum.unity.com/threads/sample-iap-project.529555/#post-7922275
     
  3. LeventKaya19

    LeventKaya19

    Joined:
    Mar 1, 2017
    Posts:
    2
    I have checked the link and it is definitiely a different project but contents seem to be the same. I still dont understand how pending transactions are not processed again after iap initialization
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    No the contents are not the same at all. Your code is completely different, and is the reason you are having issues. I'm not suggesting that you compare your code. I'm suggesting that you actually open and publish the Sample project, separate from your game. Get the basics working first, then customize the code as necessary. Then you have a second published project to test with. Then apply the lessons learned to your game. This way, your game is never "broken"
     
  5. Lilac-Envoy

    Lilac-Envoy

    Joined:
    Feb 3, 2022
    Posts:
    8
    Hi,

    Maybe it is because you called ConfirmPendingPurchase before the pending payment was completed.
    https://docs.unity3d.com/2021.3/Documentation/Manual/UnityIAPProcessingPurchases.html
    The documentation says, call ConfirmPendingPurchase only when you have successfully persisted the purchase.
    Your code appears to call ConfirmPendingPurchase() to complete the payment without waiting for the pending payment to complete.
    So, why not validate the product receipt in ProcessPurchase() and if it is not pending, call ConfirmPendingPurchase() and return PurchaseProcessingResult.Complete?