Search Unity

Resolved Where/how to execute redemption code?

Discussion in 'Economy' started by lambch0p, Dec 5, 2021.

  1. lambch0p

    lambch0p

    Joined:
    Oct 22, 2014
    Posts:
    62
    Hi,
    I've hooked my game up to IAP and economy. I am able to initiate a Play store purchase in my game and once the test payment is made, the purchase (from a Play store point of view) is complete.

    This all occurs in the ProcessPurchase method that is defined in IStoreListener and the PurchaseEventArgs contain all the details that are required to redeem the purchase in Economy. This method is synchronous.

    The Economy.Purchases.RedeemGooglePlayPurchaseAsync method is asynchronous.

    It seemed logical to me to include the RedeemGooglePlayPurchaseAsync call inside the ProcessPurchase method, but I can't find a nice way to call the async method from a sync method (and I don't think it's recommended).

    Is there an example of how the RedeemGooglePlayPurchaseAsync method should be called correctly? It would be so helpful to have some examples of IAP/Economy integration as the code examples for both products effectively work in isolation.

    The pertinent (and incorrect) code is on line 26

    Code (CSharp):
    1.         //Inside the Synchronous ProcessPurchase method after the purchase has been validated
    2.         if (validPurchase)
    3.         {
    4.             var receipt = e.purchasedProduct.receipt;
    5.             var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);
    6.             if(wrapper == null)
    7.             {
    8.                 throw new System.Exception();
    9.             }
    10.             // Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html
    11.             var store = (string)wrapper["Store"];
    12.             var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt
    13.  
    14.             // For GooglePlay payload contains more JSON
    15.             if (Application.platform == RuntimePlatform.Android)
    16.             {
    17.                 var details = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
    18.                 var gpJson = (string)details["json"];
    19.                 var gpSig = (string)details["signature"];
    20.                 var args = new Purchases.RedeemGooglePlayStorePurchaseArgs(e.purchasedProduct.definition.id, gpJson, gpSig, (int)(e.purchasedProduct.metadata.localizedPrice * 100), e.purchasedProduct.metadata.isoCurrencyCode);
    21.  
    22.                 /* *************************************************************
    23.                  The line below obviously won't work in a Synchronous method
    24.                  **************************************************************/
    25.  
    26.                 var redemptionResult = await Economy.Purchases.RedeemGooglePlayPurchaseAsync(args);
    27.                 if(redemptionResult.Verification.Status == GoogleVerification.StatusOptions.VALID)
    28.                 {
    29.                     Debug.Log("Redeemed successfully");
    30.                 }
    31.          
    32.             }
    33.  
    34.      
    35.         }
    36.  
    37.         return PurchaseProcessingResult.Complete;
     
    Last edited: Dec 5, 2021
  2. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Hi there,

    Looking at your code snippet, instead of doing:
    Code (CSharp):
    1. var redemptionResult = await
    2. Economy.Purchases.RedeemGooglePlayPurchaseAsync(args);
    you could do:
    Code (CSharp):
    1. var redemptionResult = Task.Run(async() => await Economy.Purchases.RedeemGooglePlayPurchaseAsync(args)).Result;
    That will cause the game to wait for the purchase to be redeemed before moving on.

    Hopefully that should get you going while we build out some examples of common use case like this one.