Search Unity

There is no OnPurchaseFailed callback after second InitiatePurchase if no internet

Discussion in 'Unity IAP' started by yagodar, Mar 27, 2019.

  1. yagodar

    yagodar

    Joined:
    Oct 10, 2016
    Posts:
    17
    Hi!

    Problem in Unity IAP when using on device with bad internet.

    My purchasing script attached.

    Full device logs from when the app starts to the end of 'Case 1' also attached.

    Unity version 2018.3.10f1

    Unity IAP version 1.22.0

    Platform Android 4.4.2 (API 19)
    Device Samsung GT-N7100

    Store Google Play

    Case 1:
    1) Start game with internet
    2) Wait Unity IAP initialization
    3) Turn off intenet
    4) InitiatePurchase
    5) You`ll see "bad internet" message from google activity
    6) InitiatePurchase again
    7) ... no callback, no google activity
    8) InitiatePurchase again repeatedly
    9) Game goes into freeze state until internet becomes turned on

    Case 2:
    1) Start game with internet
    2) Wait Unity IAP initialization
    4) InitiatePurchase
    5) Cancel purchase in google activity
    3) Turn off intenet
    6) InitiatePurchase again
    7) ... no callback, no google activity
    8) InitiatePurchase again repeatedly
    9) Game goes into freeze state until internet becomes turned on

    In all cases even if the internet is turned on on step 7) -- still no callback, no google activity.
    Expect 'OnPurchaseFailed' callback on step 7).

    For now I made workaround - start timer after InitiatePurchase and if no response from Unity IAP within 10 seconds - show message of bad internet to user. Then my donation shop locks from user and unlocks only if internet becomes good. Works for now.

    Purchasing script:
    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.Purchasing;
    5. using UnityEngine.Purchasing.Extension;
    6.  
    7. public class ShopManager : IStoreListener
    8. {
    9.     public static ShopManager GetInstance()
    10.     {
    11.         if (Instance == null)
    12.         {
    13.             Instance = new ShopManager();
    14.         }
    15.  
    16.         return Instance;
    17.     }
    18.  
    19.     public bool IsInitialized
    20.     {
    21.         get
    22.         {
    23.             return storeController != null;
    24.         }
    25.     }
    26.  
    27.     public void InitializePurchasing()
    28.     {
    29.         Debug.Log("InitializePurchasing...");
    30.  
    31.         if (!IsInitialized)
    32.         {
    33.             var builder = ConfigurationBuilder.Instance(
    34.                 StandardPurchasingModule.Instance()
    35.             );
    36.  
    37.             //... add products
    38.             //builder.AddProduct("little_pack", ProductType.Consumable);
    39.  
    40.             UnityPurchasing.Initialize(this, builder);
    41.         }
    42.         else
    43.         {
    44.             Debug.Log("InitializePurchasing... already initialized - skip.");
    45.         }
    46.     }
    47.  
    48.     public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    49.     {
    50.         Debug.Log(GetType().Name + ' ' + MethodBase.GetCurrentMethod().Name + " PASS.");
    51.  
    52.         transactionHistoryExtensions = extensions.GetExtension<ITransactionHistoryExtensions>();
    53.        
    54.         foreach (var product in controller.products.set)
    55.         {
    56.             //... init products
    57.         }
    58.  
    59.         storeController = controller;
    60.     }
    61.  
    62.     public void OnInitializeFailed(InitializationFailureReason error)
    63.     {
    64.         Debug.LogErrorFormat("Initialize FAIL. Reason {0}", error);
    65.     }
    66.  
    67.     public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    68.     {
    69.         Debug.Log("ProcessPurchase... '" + args.purchasedProduct.definition.id + "'");
    70.  
    71.         // ... validate and provide purchase
    72.     }
    73.  
    74.     public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    75.     {
    76.         string callbackMessage = "[" + failureReason + "][" + transactionHistoryExtensions.GetLastStoreSpecificPurchaseErrorCode() + "]";
    77.         PurchaseFailureDescription purchaseFailureDescription = transactionHistoryExtensions.GetLastPurchaseFailureDescription();
    78.         if (purchaseFailureDescription != null)
    79.         {
    80.             callbackMessage += ' ' + transactionHistoryExtensions.GetLastPurchaseFailureDescription().message;
    81.         }
    82.  
    83.         Debug.LogFormat("Purchase FAIL. Product {0}. Reason {1}", product.definition.id, callbackMessage);
    84.     }
    85.  
    86.     public void BuyDonationItem(ShopItemBundleType type)
    87.     {
    88.         if (!IsInitialized)
    89.         {
    90.             // ... handle ShopNotInitialized
    91.         }
    92.         else
    93.         {
    94.             var productId = type.ToString();
    95.             var product = storeController.products.WithID(productId);
    96.             if (product == null)
    97.             {
    98.                 // ... handle ProductNotFoundInStore
    99.             }
    100.             else if (!product.availableToPurchase)
    101.             {
    102.                 // ... handle ProductNotAvailable
    103.             }
    104.             else
    105.             {
    106.                 Debug.Log(string.Format("Purchasing product asychronously: {0}", product.definition.id));
    107.                 storeController.InitiatePurchase(product);
    108.             }
    109.         }
    110.     }
    111.  
    112.     IStoreController storeController;
    113.     ITransactionHistoryExtensions transactionHistoryExtensions;
    114.  
    115.     static ShopManager Instance;
    116. }
    117.  
    From logs. After step 6) Unity IAP plugin stacks on:
    ...........
    I/UnityIAP(12606): Calling getPurchaseHistory with continuation token: null
    ...
    I/UnityIAP(12606): Purchase history response: 6
    I/UnityIAP(12606): getPurchaseHistory() failed: 6:Error
    I/UnityIAP(12606): Querying owned items' purchase history, item type: inapp
    ...
    I/UnityIAP(12606): Purchase history response: 6
    I/UnityIAP(12606): getPurchaseHistory() failed: 6:Error
    I/UnityIAP(12606): Failed to Query inventory. UnityIAP will automatically retry in 5000ms
    I/UnityIAP(12606): QueryInventory: 10
    I/UnityIAP(12606): invoking callback
    ...........
     

    Attached Files:

  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Your work around seems appropriate. We have chosen not to check the internet before every IAP call, so we poll, as you see.
     
  3. yagodar

    yagodar

    Joined:
    Oct 10, 2016
    Posts:
    17
    Yes, I see. But with this polling even if internet becomes good - no callback to my script anyway. And no google activity
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    "And no Google activity", we have no control over this. We are also waiting on their callback.
     
  5. rakshithjuego

    rakshithjuego

    Joined:
    May 13, 2019
    Posts:
    3
    Iam also facing same kind of issue but my issue
    When internet is turned on IAP initialisation will start.
    But if i called IAP purchase immediately after Initialisation success Iam facing issue.
    Issue is->Some UNITY "UnityIAP: invoking callback" is running in background.
    and google purchase UI is not appearing around 10sec.If i click on android back button with in that 10sec iam not receiving any failure callback.After 10 sec Google purchase UI is appears but On successful purchase iam not receiving success response.
    if anyone knows solution please post your answer.
     
  6. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please provide your device logs. I typically use "adb logcat | grep -i unity" (use findstr instead of grep on Windows)