Search Unity

[Solved] What do I do in my code to Consume a product

Discussion in 'Unity IAP' started by TGKG, Jun 22, 2017.

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

    TGKG

    Joined:
    Dec 31, 2014
    Posts:
    180
    I see in the Android developer console that under managed products. In order for a consumable product to be purchased for a second time, the first purchase must be "consumed".

    How do I consume a product in my code??
     
  2. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
  3. TGKG

    TGKG

    Joined:
    Dec 31, 2014
    Posts:
    180
    So, not to be nit picking. When you state "Unity IAP finishes the transaction immediately." What you are saying is that

    Code (CSharp):
    1. /// <summary>
    2.     /// Called when a purchase completes.
    3.     ///
    4.     /// May be called at any time after OnInitialized().
    5.     /// </summary>
    6.     public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
    7.     {
    8.         return PurchaseProcessingResult.Complete;
    9.     }
    when the statement "return PurchaseProcessingResult.Complete;" is executed then the Unity IAP internal code sends a "this product has been consumed" response back to the Android Store immediately upon getting the "PurchaseSuccessful" response from the Android store.


    Next follow up question then.

    Where is the best place to put my code that awards the player with the consumable product.
    If I put it in this function, what check (ie if statement) do I make prior to the "return PurchaseProcessingResult.Complete;" statement?

    Also How do I know if the purchase is not pending rather than complete.?
     
    Last edited: Jun 22, 2017
  4. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    You would put that within the ProcessPurchase method. That is called after the user confirms the purchase with the app store.

    You can put whatever checks you think are necessary. If you would like to use Receipt Validation, then this would be a valid place for it:
    https://docs.unity3d.com/Manual/UnityIAPValidatingReceipts.html

    The purchase is pending until you mark it as complete. You mark it as complete by returning PurchaseProcessingResult.Complete.

    If you are saving your purchases to a server, then you can return PurchaseProcessingResult.Pending. Then after your server has the data saved, you can call ConfirmPendingPurchase().
     
  5. TGKG

    TGKG

    Joined:
    Dec 31, 2014
    Posts:
    180
    So if I put my code in this function. This function seems to get called when the purchase is either successful or pending.

    Therefore my code could process the addition of the consumable (ie player gets 100 or 500 coins, etc.), but the PurchaseProcessingResult could have been "pending".

    Is this okay? to write my code that way or am I potentially going to get into trouble? or am I not understanding this process fully? or do I not need to worry about the "pending" issue I have described.?

    here is my code:

    Code (CSharp):
    1.  //Checks to see if a product purchase was successful and logs the result to the console.
    2.     public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    3.     {
    4.         // A consumable product has been purchased by this user.
    5.  
    6.  
    7.         if (String.Equals(args.purchasedProduct.definition.id, Product_100_coin, StringComparison.Ordinal))
    8.         {
    9.             Debug.Log(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    10.             displayFooterText(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    11.  
    12.             Debug.Log("You got 100 coins");
    13.            
    14.             numOfCoins = numOfCoins + 100;
    15.             displayCoinText(numOfCoins);
    16.             // The consumable item has been successfully purchased, add 100 coins to the player's in-game score.              
    17.         }
    18.  
    19.         else if (String.Equals(args.purchasedProduct.definition.id, Product_500_coin, StringComparison.Ordinal))
    20.         {
    21.             Debug.Log(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    22.             displayFooterText(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    23.  
    24.             Debug.Log("You got 500 coins");
    25.  
    26.             numOfCoins = numOfCoins + 500;
    27.             displayCoinText(numOfCoins);
    28.         }
    29.                        
    30.         else if (String.Equals(args.purchasedProduct.definition.id, Product_1000_coin, StringComparison.Ordinal))
    31.         {
    32.             Debug.Log(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    33.             displayFooterText(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    34.  
    35.             Debug.Log("You got 1000 coins");
    36.  
    37.             numOfCoins = numOfCoins + 1000;
    38.             displayCoinText(numOfCoins);
    39.         }
    40.  
    41.         else if (String.Equals(args.purchasedProduct.definition.id, Product_10_scatter, StringComparison.Ordinal))
    42.         {
    43.             Debug.Log(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    44.             displayFooterText(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    45.  
    46.             Debug.Log("You got 10 scatter bombs");
    47.  
    48.             numOfScatterBombs = numOfScatterBombs + 10;
    49.             displayBombText("Scatter", numOfScatterBombs);
    50.         }
    51.  
    52.         else if (String.Equals(args.purchasedProduct.definition.id, Product_5_splash, StringComparison.Ordinal))
    53.         {
    54.             Debug.Log(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    55.             displayFooterText(string.Format("ProcessPurchase: Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    56.  
    57.             Debug.Log("You got 5 splash bombs");
    58.  
    59.             numOfSplashBombs = numOfSplashBombs + 5;
    60.             displayBombText("splash", numOfSplashBombs);
    61.         }
    62.  
    63.         else if (String.Equals(args.purchasedProduct.definition.id, Product_plane_jumbo, StringComparison.Ordinal))
    64.         {
    65.             Debug.Log(string.Format("ProcessPurchase: NON-Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    66.             displayFooterText(string.Format("ProcessPurchase: NON-Consumable PASS. Product: '{0}'", args.purchasedProduct.definition.id));
    67.  
    68.             Debug.Log("You got yourself a JUMBO JET");
    69.         }
    70.  
    71.         // Or ... an unknown product has been purchased by this user. Fill in additional products here....
    72.         else
    73.         {
    74.             Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
    75.             displayFooterText(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
    76.         }
    77.  
    78.         // Return a flag indicating whether this product has completely been received, or if the application needs
    79.         // to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when still
    80.         // saving purchased products to the cloud, and when that save is delayed.
    81.         return PurchaseProcessingResult.Complete;
    82.     }
    83.  
     
  6. ap-unity

    ap-unity

    Unity Technologies

    Joined:
    Aug 3, 2016
    Posts:
    1,519
    Yes, that is correct. ProcessPurchase is called after a successful purchase. But if the transaction is never marked as complete then it will be called the next time the app starts.

    There are two situations when this would happen:
    1. If you deliberately mark the transaction as Pending. This is only necessary if you are sending the transactions to a server. (And you can complete the transaction with ConfirmPendingPurchase.)
    2. If a user closes the app before ProcessPurchase finishes running. In this case, you don't need to do anything extra, because ProcessPurchase will process the transaction as if it just happened.
    And the code you provided looks good.
     
  7. TGKG

    TGKG

    Joined:
    Dec 31, 2014
    Posts:
    180
    Yes, I am understanding this much better.

    Are you saying that the ProcessPurchase function is ONLY called when the purchase is successful.

    Thank you for the answers.
     
  8. ap-unity

    ap-unity

    Unity Technologies

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