Search Unity

Unity IAP How to Retry PurchaseProcessingResult.Pending Purchase?

Discussion in 'Unity IAP' started by TitanUnity, Jun 26, 2018.

  1. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    176
    Hi,

    We're having trouble retrying Pending purchases since upgrading to Unity 2018.1.3f1. Our payment flow works like this:

    PurchaseProcessingResult.Pending.png


    The specific problem occurs if our App Server is unavailable for any reason. So in a test scenario let's say we disable our App server (preventing steps 6 and 7 from completing). You can see that the ConfirmPendingPurchase call will never fires so the purchase is left in a Pending state.

    Our assumption was that by retrying the purchase of the product we could "retrigger" the validation process and the purchase would be completed, but this doesn't work:
    m_StoreController.InitiatePurchase(product);

    It just fires an error: PurchaseFailureReason.DuplicateTransaction

    Was something changed? The only way we've found to make this work so far is to close the app and restart, forcing the store to re-initialize which will retrigger ProcessPurchase for the Pending transaction.
     
  2. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    176
  3. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    I am checking the IAP team and will follow up
     
  4. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    If previously you attempted to purchase again and if it succeeded, wouldn't that orphan the first transaction and leave it in pending? Cannot you retry Step 6 above and implement a time out and/or error return with a retry mechanism, instead of attempting to purchase again? We suspect that the previous behavior was in error. What would be your ideal behavior for the IAP system (other than attempt to repurchase)?
     
  5. TitanUnity

    TitanUnity

    Joined:
    May 15, 2014
    Posts:
    176
    Before installing Unity 2018, if a purchase was left in a Pending state as described above, if we called InitiatePurchase
    Code (CSharp):
    1. m_StoreController.InitiatePurchase(product);
    the Unity IAP system would automatically retrigger ProcessPurchase:
    Code (CSharp):
    1. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e){ ..  }
    and the Pending purchase for the user would be automatically Completed and delivered.

    It seems now that when calling InitiatePurchase() for a product that is in a pending state, the Unity IAP system throws a PurchaseFailureReason.DuplicateTransaction error instead.

    As you mentioned, if the original behavior of the Unity IAP system automatically calling ProcessPurchase was an error that at least makes sense, but you're right, we now need to implement our own retry logic for player's that encounter purchase problems during their session and then manually call
    Code (CSharp):
    1. m_StoreController.ConfirmPendingPurchase(product);
    when the purchase has been validated.

    We actually started built a flow last night that simulates what the Unity IAP did before. But to answer your question about our ideal behavior, the only thing that makes sense to us in the case that our App Server is inaccessible is to present the user with an error message suggesting that the purchase was NOT delivered successfully and to please try again. At that point, the user has 2 options:

    1. Relaunch our app and open our store UI which will automatically complete the transaction on IAP init:
    Code (CSharp):
    1. UnityPurchasing.Initialize();
    2. Try again (tap the product they wanted to buy again). The system would call a smart InitiatePurchase() that would detect an incomplete Pending transaction for that product and proceed to ProcessPurchase, if no Pending purchases were outstanding it would create a new transaction so there would be no orphan transactions. << We just built this flow manually, it looks something like this:

    Code (CSharp):
    1.     public override void PurchaseProduct(string sku)
    2.     {
    3.         try
    4.         {
    5.             if (!IsInitialized())
    6.             {
    7.                 OnPurchaseFailed("Store not initialized.");
    8.             }
    9.             else
    10.             {
    11.                 Product product = m_StoreController.products.WithID(sku);
    12.                 if (product == null)
    13.                 {
    14.                     OnPurchaseFailed("Product not found.");
    15.                 }
    16.                 else if (IsProductPending(product))
    17.                 {
    18.                     StartCoroutine(ValidateTransaction(product));
    19.                 }
    20.                 else if (!product.availableToPurchase)
    21.                 {
    22.                     OnPurchaseFailed("Product not available for purchase.");
    23.                 }
    24.                 else
    25.                 {
    26.                     m_StoreController.InitiatePurchase(product);
    27.                 }
    28.             }
    29.         }
    30.         catch (Exception e)
    31.         {
    32.             OnPurchaseFailed("Could not initiate purchase transaction. Error: " + e.Message);
    33.         }
    34.     }
    So you can see we're manually checking if the product is Pending by calling IsProductPending(). We also implement our own ValidateTransaction() coroutine that calls m_StoreController.ConfirmPendingPurchase(product) on success.
     
    Last edited: Jun 27, 2018
  6. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    Attempting to purchase again is not valid flow. As mentioned, it would leave the previous transaction in an orphaned state. A DuplicatePurchase error the second time would be expected. Apologies if you saw different behavior in a previous version, the current flow is now correct as far as we can tell. During the Step 6 above, you would want to retry as you agreed. You can test Pending behavior with this sample project. It might make sense to create a separate button for Initialize, instead of in the Start() method. The Toggle button allows you to either return Pending or Complete from ProcessPurchase. Currently, if you have a product left in Pending, the next time the app starts and IAP initializes, ProcessPurchase (for the original purchase left in Pending) is triggered, and you can retry your validation again. Otherwise, if your server is down, you will need to retry at run time. Otherwise, you have two options. Simply pass the product to ConfirmPendingPurchase without the server validation, or relaunch the game.

    https://forum.unity.com/threads/sample-iap-project.529555/
     
    MihaPro_CarX likes this.
  7. stokato

    stokato

    Joined:
    Aug 20, 2018
    Posts:
    1
    But how can I check what the product is pending?
     
  8. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    @stokato Do you mean at app launch? If so, are you receiving a ProcessPurchase callback for the product? I've been testing with this sample app which allows you to configure Pending vs Complete at run time (using the Toggle button). I also write debug information to the UI. https://forum.unity.com/threads/sample-iap-project.529555/
     
  9. Lesha-VH

    Lesha-VH

    Joined:
    Jul 3, 2012
    Posts:
    76
    Unity 2017.4.8f1
    IAP 1.21.0
    Android/Google Play store

    I make purchase (press buy button after enter password), than - BEFORE google answer - disconnect device from internet.

    After restore internet connection and press the same item I get error in
    public void OnPurchaseFailed(Product i, PurchaseFailureReason p)
    with reason UserCancelled

    After re-launch application IAP plugin does not call
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
    and I can not buy the same consumable item with reason UserCancelled

    I think purchases hangs somewhere - or I miss something?
    Thanks!
     
    Last edited: Sep 5, 2018
  10. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    Understood, thank you for the description. Are you able to purchase after you reinstall the app?
     
  11. Lesha-VH

    Lesha-VH

    Joined:
    Jul 3, 2012
    Posts:
    76
    Jeff, after re-install I CAN NOT buy the same consumable product. (no call ProcessPurchase at app launch, when try to buy - OnPurchaseFailed with reason UserCancelled)
     
  12. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    Got it, we are investigating.
     
  13. Lesha-VH

    Lesha-VH

    Joined:
    Jul 3, 2012
    Posts:
    76
    Jeff, did you reproduce the bug?
    Only install NEW application version from google play version fix it))
     
  14. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    @Lesha-VH Can you elaborate? Did you fix it?
     
  15. ThiagoUken

    ThiagoUken

    Joined:
    Sep 26, 2018
    Posts:
    1
    I'm having the same issue with pending purchases. Is there a more elegant way to handle it without having to restart the app? I tried calling UnityPurchasing.Initialize again without restarting but it doesn't fire the ProcessPurchase event.
     
  16. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
  17. SyedUmair

    SyedUmair

    Joined:
    Sep 2, 2013
    Posts:
    38
    I am also having exact problem. Unity Team should handle it in a better way or at least provide a method to fetch pending purchases at run-time. So, we can check and call ConfirmPendingPurchase without the need to re-launch the app.
     
  18. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    Your pending purchases will be available when you initialize IAP. You can initialize IAP at any time. But yes, we are working on an improved solution.
     
  19. SyedUmair

    SyedUmair

    Joined:
    Sep 2, 2013
    Posts:
    38
    it's great, if you guys are working to improve the flow.
    Yes, for now, I would do multiple initializes to get the pending transactions. But, I guess, its not the best idea to call Init methods once SDK is initialized, successfully. :)
     
  20. jjurica

    jjurica

    Joined:
    Feb 14, 2017
    Posts:
    1
    Hello. I was wondering if you would kindly share IsProductPending() and ValidateTransaction() coroutine? There still seems to be missing information on how to access the list of pending purchases. Thanks
     
  21. Alexander_DEV

    Alexander_DEV

    Joined:
    Jun 22, 2015
    Posts:
    1
    @TitanUnity
    Hey. I ran into the same problem that you described.
    Can you tell how you determine that the purchase is still pending after the application is restarted? Can you show the "IsProductPending" method code?
     
  22. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    There is no specific product pending method. Your ProcessPurchase will automatically fire upon IAP initialization if you have any products in Pending, it's the same method that fires when someone attempts to purchase the product in your game. You can confirm with the Sample IAP Project here, it allows you to toggle between Pending and Complete during purchase for testing. If you choose Pending, the next time you launch the game, you'll see the ProcessPurchase debug messages in the UI https://forum.unity.com/threads/sample-iap-project.529555/
     
  23. Ritwik_Sinha

    Ritwik_Sinha

    Joined:
    Apr 30, 2018
    Posts:
    2
    07-31 09:18:17.815: I/Unity(26850): UnityIAP Version: 1.22.0
    07-31 09:18:17.815: I/Unity(26850):
    07-31 09:18:17.815: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:17.884: I/UnityIAP(26850): IAB helper created.
    07-31 09:18:17.950: W/UnityMain(26850): type=1400 audit(0.0:1833): avc: granted { create } for name="IAP" scontext=u:r:untrusted_app:s0:c12,c258,c512,c768 tcontext=u:eek:bject_r:sdcardfs:s0:c12,c258,c512,c768 tclass=dir
    07-31 09:18:18.506: I/Unity(26850): Using configuration builder objects
    07-31 09:18:18.506: I/Unity(26850):
    07-31 09:18:18.506: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:18.540: I/UnityIAP(26850): Starting in-app billing setup.
    07-31 09:18:18.545: I/UnityIAP(26850): Billing service connected.
    07-31 09:18:18.546: I/UnityIAP(26850): invoking callback
    07-31 09:18:18.546: I/UnityIAP(26850): Checking for in-app billing 3 support.
    07-31 09:18:18.553: I/UnityIAP(26850): In-app billing version 3 supported for com.Idivarts.SpaceKill
    07-31 09:18:18.557: I/UnityIAP(26850): Subscriptions AVAILABLE.
    07-31 09:18:18.559: I/UnityIAP(26850): Subscription upgrade and downgrade are AVAILABLE.
    07-31 09:18:18.562: I/UnityIAP(26850): Subscriptions information parse AVAILABLE.
    07-31 09:18:18.576: I/UnityIAP(26850): VR supported.
    07-31 09:18:18.577: I/UnityIAP(26850): onIabSetupFinished: 0
    07-31 09:18:18.577: I/UnityIAP(26850): Requesting 11 products
    07-31 09:18:18.577: I/UnityIAP(26850): QueryInventory: 11
    07-31 09:18:18.578: I/UnityIAP(26850): invoking callback
    07-31 09:18:18.578: I/UnityIAP(26850): Querying owned items, item type: inapp
    07-31 09:18:18.578: I/UnityIAP(26850): Package name: com.Idivarts.SpaceKill
    07-31 09:18:18.578: I/UnityIAP(26850): Calling getPurchases with continuation token: null
    07-31 09:18:18.582: I/UnityIAP(26850): Owned items response: 0
    07-31 09:18:18.582: I/UnityIAP(26850): Continuation token: null
    07-31 09:18:18.582: I/UnityIAP(26850): Querying SKU details.
    07-31 09:18:18.623: I/UnityIAP(26850): Querying owned items, item type: subs
    07-31 09:18:18.623: I/UnityIAP(26850): Package name: com.Idivarts.SpaceKill
    07-31 09:18:18.623: I/UnityIAP(26850): Calling getPurchases with continuation token: null
    07-31 09:18:18.623: I/UnityIAP(26850): [ 07-31 09:18:18.657 26850:27252 D/ ]
    07-31 09:18:18.623: I/UnityIAP(26850): addLayerName, tid:27252
    07-31 09:18:18.833: I/UnityIAP(26850): Owned items response: 0
    07-31 09:18:18.833: I/UnityIAP(26850): Continuation token: null
    07-31 09:18:18.834: I/UnityIAP(26850): Querying SKU details.
    07-31 09:18:18.847: I/UnityIAP(26850): Querying owned items' purchase history, item type: subs
    07-31 09:18:18.847: I/UnityIAP(26850): Package name: com.Idivarts.SpaceKill
    07-31 09:18:18.847: I/UnityIAP(26850): Calling getPurchaseHistory with continuation token: null
    07-31 09:18:19.355: I/UnityIAP(26850): Purchase history response: 0
    07-31 09:18:19.355: I/UnityIAP(26850): Continuation token: null
    07-31 09:18:19.355: I/UnityIAP(26850): Querying owned items' purchase history, item type: inapp
    07-31 09:18:19.355: I/UnityIAP(26850): Package name: com.Idivarts.SpaceKill
    07-31 09:18:19.355: I/UnityIAP(26850): Calling getPurchaseHistory with continuation token: null
    07-31 09:18:19.627: I/UnityIAP(26850): Purchase history response: 0
    07-31 09:18:19.628: I/UnityIAP(26850): Continuation token: null
    07-31 09:18:19.628: I/UnityIAP(26850): onQueryInventoryFinished: true
    07-31 09:18:19.628: I/UnityIAP(26850): Inventory refresh successful. (response: 0:OK)
    07-31 09:18:19.637: I/UnityIAP(26850): invoking callback
    07-31 09:18:19.725: I/Unity(26850): UnityIAP: Promo interface is available for 11 items
    07-31 09:18:19.725: I/Unity(26850):
    07-31 09:18:19.725: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:19.725: I/Unity(26850): [ 07-31 09:18:19.741 26850:27252 D/ ]
    07-31 09:18:19.725: I/Unity(26850): addLayerName, tid:27252
    07-31 09:18:19.725: I/Unity(26850): [ 07-31 09:18:19.782 26850:27252 D/ ]
    07-31 09:18:19.725: I/Unity(26850): addLayerName, tid:27252
    07-31 09:18:20.215: I/UnityIAP(26850): invoking callback
    07-31 09:18:20.717: I/UnityIAP(26850): invoking callback
    07-31 09:18:21.269: I/UnityIAP(26850): invoking callback
    07-31 09:18:21.829: I/UnityIAP(26850): invoking callback
    07-31 09:18:22.381: I/UnityIAP(26850): invoking callback
    07-31 09:18:22.913: I/UnityIAP(26850): invoking callback
    07-31 09:18:23.461: I/UnityIAP(26850): invoking callback
    07-31 09:18:23.966: I/UnityIAP(26850): invoking callback
    07-31 09:18:24.481: I/UnityIAP(26850): invoking callback
    07-31 09:18:37.243: I/Unity(26850): Tag Name : OtherUI
    07-31 09:18:37.243: I/Unity(26850):
    07-31 09:18:37.243: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:37.243: I/Unity(26850): [ 07-31 09:18:37.288 26850:27252 D/ ]
    07-31 09:18:37.243: I/Unity(26850): addLayerName, tid:27252
    07-31 09:18:38.943: I/Unity(26850): Tag Name : OtherUI
    07-31 09:18:38.943: I/Unity(26850):
    07-31 09:18:38.943: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.248: I/Unity(26850): Receipt ;
    07-31 09:18:39.248: I/Unity(26850):
    07-31 09:18:39.248: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.248: I/Unity(26850): Transaction Id :
    07-31 09:18:39.248: I/Unity(26850):
    07-31 09:18:39.248: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.248: I/Unity(26850): Meta data : unlockAllLevels (Space Kill)
    07-31 09:18:39.248: I/Unity(26850):
    07-31 09:18:39.248: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.248: I/Unity(26850): Meta data : unlockAllLevels
    07-31 09:18:39.248: I/Unity(26850):
    07-31 09:18:39.248: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.248: I/Unity(26850): Meta data : ? 450.00
    07-31 09:18:39.248: I/Unity(26850):
    07-31 09:18:39.248: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.249: I/Unity(26850): Availability : True
    07-31 09:18:39.249: I/Unity(26850):
    07-31 09:18:39.249: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.249: I/Unity(26850): Has Receipt : False
    07-31 09:18:39.249: I/Unity(26850):
    07-31 09:18:39.249: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.249: I/Unity(26850): Definition store Id : offer4
    07-31 09:18:39.249: I/Unity(26850):
    07-31 09:18:39.249: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.249: I/Unity(26850): Purchasing product asychronously: offer4
    07-31 09:18:39.249: I/Unity(26850):
    07-31 09:18:39.249: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.251: I/Unity(26850): Unable to confirm purchase; Product has missing or empty transactionID
    07-31 09:18:39.251: I/Unity(26850):
    07-31 09:18:39.251: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Receipt ;
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Transaction Id :
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Meta data : unlockAllLevels (Space Kill)
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Meta data : unlockAllLevels
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Meta data : ? 450.00
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.499: I/Unity(26850): Availability : True
    07-31 09:18:39.499: I/Unity(26850):
    07-31 09:18:39.499: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.500: I/Unity(26850): Has Receipt : False
    07-31 09:18:39.500: I/Unity(26850):
    07-31 09:18:39.500: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.500: I/Unity(26850): Definition store Id : offer4
    07-31 09:18:39.500: I/Unity(26850):
    07-31 09:18:39.500: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.500: I/Unity(26850): Purchasing product asychronously: offer4
    07-31 09:18:39.500: I/Unity(26850):
    07-31 09:18:39.500: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:39.500: I/Unity(26850): Unable to confirm purchase; Product has missing or empty transactionID
    07-31 09:18:39.500: I/Unity(26850):
    07-31 09:18:39.500: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:40.227: I/UnityIAP(26850): isUnityVrEnabled = false
    07-31 09:18:40.229: I/UnityIAP(26850): onPurchaseProduct: offer4
    07-31 09:18:40.229: I/UnityIAP(26850): ITEM TYPE:inapp
    07-31 09:18:40.264: I/Unity(26850): purchase({0}): offer4
    07-31 09:18:40.264: I/Unity(26850):
    07-31 09:18:40.264: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:40.265: I/UnityIAP(26850): isUnityVrEnabled = false
    07-31 09:18:40.267: I/Unity(26850): purchase({0}): offer4
    07-31 09:18:40.267: I/Unity(26850):
    07-31 09:18:40.267: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:18:40.312: I/UnityIAP(26850): Creating purchase activity
    07-31 09:18:40.312: I/UnityIAP(26850): oldSkuMetadata is null
    07-31 09:18:40.313: I/UnityIAP(26850): invoking callback
    07-31 09:18:40.313: I/UnityIAP(26850): Constructing buy intent for offer4, item type: inapp
    07-31 09:18:40.348: I/UnityIAP(26850): Launching buy intent for offer4. Request code: 999
    07-31 09:19:52.592: I/UnityIAP(26850): onActivityResult
    07-31 09:19:52.593: I/UnityIAP(26850): Purchase data: {"orderId":"GPA.3306-2252-6230-58270","packageName":"com.Idivarts.SpaceKill","productId":"offer4","purchaseTime":1564544989039,"purchaseState":0,"developerPayload":"{\"developerPayload\":\"\",\"is_free_trial\":false,\"has_introductory_price_trial\":false,\"is_updated\":false,\"accountId\":\"\"}","purchaseToken":(It displays some valid token here on logcat)}
    07-31 09:19:52.593: I/UnityIAP(26850): Data signature: (It returns some valid signature here)
    07-31 09:19:52.593: I/UnityIAP(26850): Successful resultcode from purchase activity.
    07-31 09:19:52.593: I/UnityIAP(26850): Purchase data: {"orderId":"GPA.3306-2252-6230-58270","packageName":"com.Idivarts.SpaceKill","productId":"offer4","purchaseTime":1564544989039,"purchaseState":0,"developerPayload":"{\"developerPayload\":\"\",\"is_free_trial\":false,\"has_introductory_price_trial\":false,\"is_updated\":false,\"accountId\":\"\"}","purchaseToken":(It displays some valid token here on logcat)}
    07-31 09:19:52.593: I/UnityIAP(26850): Data signature: (It returns some valid signature here)
    07-31 09:19:52.593: I/UnityIAP(26850): Extras: Bundle[{INAPP_PURCHASE_DATA={"orderId":"GPA.3306-2252-6230-58270","packageName":"com.Idivarts.SpaceKill","productId":"offer4","purchaseTime":1564544989039,"purchaseState":0,"developerPayload":"{\"developerPayload\":\"\",\"is_free_trial\":false,\"has_introductory_price_trial\":false,\"is_updated\":false,\"accountId\":\"\"}","purchaseToken":(It displays some valid token here on logcat), RESPONSE_CODE=0}]
    07-31 09:19:52.593: I/UnityIAP(26850): Expected item type: inapp
    07-31 09:19:52.593: I/UnityIAP(26850): [ 07-31 09:19:52.595 1436: 1445 E/ ]
    07-31 09:19:52.593: I/UnityIAP(26850): [ZeroHung]zrhung_get_config: Get config failed for wp[0x0008]
    07-31 09:19:52.595: I/UnityIAP(26850): onIabPurchaseFinished: true
    07-31 09:19:52.595: I/UnityIAP(26850): Success (response: 0:OK)
    07-31 09:19:52.595: I/UnityIAP(26850): Product purchased successfully!
    07-31 09:19:52.595: I/UnityIAP(26850): NotifyUnityOfPurchase
    07-31 09:19:52.854: I/Unity(26850): onPurchaseFailedEvent({0}): offer4
    07-31 09:19:52.854: I/Unity(26850):
    07-31 09:19:52.854: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:19:52.869: I/Unity(26850): OnPurchaseFailed: FAIL. Product: 'offer4', PurchaseFailureReason: ExistingPurchasePending
    07-31 09:19:52.869: I/Unity(26850):
    07-31 09:19:52.869: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:19:52.869: I/Unity(26850): Unable to confirm purchase; Product has missing or empty transactionID
    07-31 09:19:52.869: I/Unity(26850):
    07-31 09:19:52.869: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:19:52.905: I/UnityIAP(26850): Finish transaction:GPA.3306-2252-6230-58270
    07-31 09:19:52.905: I/UnityIAP(26850): Consuming offer4
    07-31 09:19:52.905: I/UnityIAP(26850): invoking callback
    07-31 09:19:52.905: I/UnityIAP(26850): Consuming sku: offer4, token: (It displays some valid token here on logcat)
    07-31 09:19:52.906: I/Unity(26850): UnityIAP: Promo interface is available for 11 items
    07-31 09:19:52.906: I/Unity(26850):
    07-31 09:19:52.906: I/Unity(26850): (Filename: ./Runtime/Export/Debug.bindings.h Line: 45)
    07-31 09:19:53.985: I/UnityIAP(26850): Successfully consumed sku: offer4
    07-31 09:19:53.985: I/UnityIAP(26850): onConsumeFinished:true
    07-31 09:19:53.985: I/UnityIAP(26850): Successful consume of sku offer4 (response: 0:OK)
    07-31 09:19:53.985: I/UnityIAP(26850): 0
    07-31 09:19:53.985: I/UnityIAP(26850): [ 07-31 09:19:53.998 610: 610 D/ ]
    07-31 09:19:53.985: I/UnityIAP(26850): Jitter happen,total Jitter:90,FPS:24






    Before when i was working, I could make purchases. After some time, this stopped happening. I have queried some item infos and added that here as well. The output is from android device monitor.

    Please help out.ProcessPurchase is not getting called even after app restart.

    I even tried out calling ConfirmPendingPurchase here but nothing seems to work. The output above is obtained via the script that i have used below. I gave some delay before initialization of purchase as well.
    Have a look at the snippet.
    Code (CSharp):
    1. void BuyProductID(string productId)
    2. {
    3. if (!IsInitialized())
    4. return;
    5. Product product = m_StoreController.products.WithID(productId);
    6. Debug.Log("Receipt ; \n"+product.receipt);
    7. Debug.Log("Transaction Id : "+product.transactionID);
    8. Debug.Log("Meta data : "+product.metadata.localizedTitle);
    9. Debug.Log("Meta data : "+product.metadata.localizedDescription);
    10. Debug.Log("Meta data : "+product.metadata.localizedPriceString);
    11. Debug.Log("Availability : "+product.availableToPurchase);
    12. Debug.Log("Has Receipt : "+product.hasReceipt);
    13. Debug.Log("Definition store Id : "+product.definition.storeSpecificId);
    14.  
    15. if (product != null)
    16. {
    17. Debug.Log("Purchasing product asychronously: "+ product.definition.id);
    18. manualPurchaseStarted=true;
    19. m_StoreController.ConfirmPendingPurchase(product);
    20. StartCoroutine(WaitAndStart(product));
    21. }
    22. else
    23. Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
    24. }
    25.  
    26. public IEnumerator WaitAndStart(Product product)
    27. {
    28. yield return new WaitForSeconds(1);
    29. m_StoreController.InitiatePurchase(product);
    30. }
     
  24. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    Please show the code for ProcessPurchase. Did you return Pending on the original purchase? Are you able to make other purchases? I might recommend that you compare your code to the Sample IAP project here, it properly receives ProcessPurchase for any product left in Pending, it was designed for this specific test in mind, with the Toggle button logic. Please publish and test this sample app, and compare to your results. https://forum.unity.com/threads/sample-iap-project.529555/
     
  25. Ritwik_Sinha

    Ritwik_Sinha

    Joined:
    Apr 30, 2018
    Posts:
    2
    Yeah it worked. I tried logcat . In my case first the OnPurchaseFailed was called and then Process Purchase as i had introduced ConfirmPendingPurchase command there and as is there in the mentioned PureRocketIAP Project as well(as u mentioned). So after the purchase was failed it was purchased again(bcuz of
    m_StoreController.ConfirmPendingPurchase(product) ). I figured out that some flag that i had introduced before was not set to true as i was unaware of the fact that the control goes to OnPurchaseFailed first.

    Yet i dont know why is this flow everytime i purchase i.e. First OnPuchaseFailed is called and then ProcessPurchase
     
  26. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    4,944
    You can't purchase a second time without the Purchase fail without confirming the first/prior purchase. This is expected.