Search Unity

[Solved] DuplicateTransaction error on relaunching app

Discussion in 'Unity IAP' started by ColinAmuzo, Jan 5, 2018.

Thread Status:
Not open for further replies.
  1. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    Hi

    I'm using Unity 5.5.2.
    My issue is present on Android and iOS.
    I'm using UnityIAP StandardPurchasingModule Version: 1.15.0.
    I have one Non-consumable product configured.
    I can successfully purchase the product and the purchase is successfully restored on *reinstalling* the app.

    However, on simply *relaunching* the app, I get a DuplicateTransaction error in the IStoreListener.OnPurchaseFailed callback.

    I was initially expecting IStoreListener.ProcessPurchase to be called on relaunching, but then on further investigation, there was nothing implying that this should happen. But, why is IStoreListener.OnPurchaseFailed getting called? I expected that that would be called only if an actual purchase process failed.

    If IStoreListener.ProcessPurchase is not supposed to be called on relaunching the app, should I be caching the purchased state myself, or using another Unity IAP API to detemine what has been purchased?

    Full Android log is attached.

    Thanks.

    Colin
     

    Attached Files:

  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Kennai likes this.
  3. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    Thanks Jeff. I'll try that but I don't think it will work. The issue seems to be 100% repeatable on multiple devices. The same account was used on the multiple devices, but if the issue would be solved by clearing data/cache, then it would be an issue related to the device, not the account.

    What "purchasing logic" would you need to see? The implementations of the IStoreListener interface?
     
  4. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    ...no, it didn't work.

    I cleared Google Play Store and Google Play Services data and cache.
    Launch the app...no change.
    Cleared Google Play Store and Google Play Services data and cache again, and force stopped Google Play Store (force stopping Google Play Services was not an option).
    Launch the app...Unity IAP initialised OK, but the game played like the purchase had not been made.
    I checked the purchase history in the Google Play Store app, and the IAP showed there as having been purchased.
    Restarted the phone.
    Relaunched the app...DuplicateTransaction issue was present again.

    Here's our IStoreListener interface implementation:
    Code (CSharp):
    1.     void IStoreListener.OnInitialized( IStoreController controller, IExtensionProvider extensions )
    2.     {
    3. #if DEBUG_PurchaseManager
    4.         Debug.Log( LOG_TAG + "Unity IAP initialized" );
    5. #endif
    6.  
    7.         _storeController = controller;
    8.         _extensionProvider = extensions;
    9.         _isInitialised = true;
    10.  
    11.         if ( _onInitialised != null )
    12.         {
    13.             System.Action    cached = _onInitialised;
    14.             _onInitialised = null;
    15.             cached();
    16.         }
    17.     }
    18.  
    19.     void IStoreListener.OnInitializeFailed( InitializationFailureReason error )
    20.     {
    21.         Debug.LogError( LOG_TAG + "Unity IAP init failed: " + error.ToString() );
    22.  
    23.         _isInitialised = false;
    24.  
    25.         if ( _onInitialised != null )
    26.         {
    27.             System.Action    cached = _onInitialised;
    28.             _onInitialised = null;
    29.             cached();
    30.         }
    31.     }
    32.  
    33.     PurchaseProcessingResult IStoreListener.ProcessPurchase( PurchaseEventArgs e )
    34.     {
    35.         if ( _isPurchasing && _purchasingProductId == e.purchasedProduct.definition.id )
    36.         {
    37. #if DEBUG_PurchaseManager
    38.             Debug.Log( LOG_TAG + "Unity IAP purchase complete: " + e.purchasedProduct.metadata.localizedTitle );
    39. #endif
    40.  
    41.             EndPurchasing( EPurchaseResult.SUCCESS );
    42.         }
    43.         else
    44.         {
    45. #if DEBUG_PurchaseManager
    46.             Debug.Log( LOG_TAG + "Unity IAP purchase restored: " + e.purchasedProduct.metadata.localizedTitle );
    47. #endif
    48.  
    49.             if ( _onPurchaseRestored != null )
    50.             {
    51.                 _onPurchaseRestored( e.purchasedProduct.definition.id );
    52.             }
    53.         }
    54.  
    55.         return PurchaseProcessingResult.Complete;
    56.     }
    57.  
    58.     void IStoreListener.OnPurchaseFailed( Product i, PurchaseFailureReason p )
    59.     {
    60.         Debug.LogError( LOG_TAG + "Unity IAP purchase failed: " + p.ToString() );
    61.  
    62.         if ( !_isPurchasing )
    63.         {
    64.             Debug.LogError( LOG_TAG + "OnPurchaseFailed called when not purchasing!" );
    65.             return;
    66.         }
    67.  
    68.         if ( _purchasingProductId != i.definition.id )
    69.         {
    70.             Debug.LogError( LOG_TAG + "OnPurchaseFailed product id '" + i.definition.id + "' does not match the product id being purchased '" + _purchasingProductId + "'!" );
    71.             return;
    72.         }
    73.  
    74.         EPurchaseResult    result = EPurchaseResult.FAIL_GENERAL;
    75.  
    76.         if ( _sFailedPurchaseResultDict.ContainsKey( p ) )
    77.         {
    78.             result = _sFailedPurchaseResultDict[ p ];
    79.         }
    80.  
    81.         EndPurchasing( result );
    82.     }
    83.  
     
    BreynartStudios likes this.
  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sorry, I meant your purchase script
     
  6. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    As in the script from which I call IStoreController.InitiatePurchase?
     
  7. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Yes, generally this is stored in a single script, like purchase.cs. Specifically where you call ProcessPurchase, this is where any possible duplicate purchases may be occurring. To be clear, this is not something we are aware of, nor heard reports of from other users. So it would likely be occurring in your code, and this is what I want to look at.
     
  8. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    In particular, I've seen this behavior when the developer added an explicit On_Click method to a Codeless IAP button, which would call purchase twice. So I wanted to look at your overall logic.
     
  9. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    Ok, I've attached our "PurchaseManager.cs" script. The PurchaseManager is instantiated elsewhere.

    I'm not calling ProcessPurchase at all. I assumed that was only intended to be called by the underlying Unity IAP system.

    I'm not using Codeless IAP.
     

    Attached Files:

  10. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
  11. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    Thanks Jeff. I'll make a support ticket tomorrrow.
     
  12. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Sounds good. Also, what is AmuzoEngine?
     
  13. ColinAmuzo

    ColinAmuzo

    Joined:
    Mar 20, 2013
    Posts:
    46
    AmuzoEngine is the namespace for our internal tech (our company is called Amuzo). It was inspired by the UnityEngine namespace :)
     
  14. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
Thread Status:
Not open for further replies.