Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

Resolved Where/how to execute redemption code?

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

  1. lambch0p


    Oct 22, 2014
    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
    11.             var store = (string)wrapper["Store"];
    12.             var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt
    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(, gpJson, gpSig, (int)(e.purchasedProduct.metadata.localizedPrice * 100), e.purchasedProduct.metadata.isoCurrencyCode);
    22.                 /* *************************************************************
    23.                  The line below obviously won't work in a Synchronous method
    24.                  **************************************************************/
    26.                 var redemptionResult = await Economy.Purchases.RedeemGooglePlayPurchaseAsync(args);
    27.                 if(redemptionResult.Verification.Status == GoogleVerification.StatusOptions.VALID)
    28.                 {
    29.                     Debug.Log("Redeemed successfully");
    30.                 }
    32.             }
    35.         }
    37.         return PurchaseProcessingResult.Complete;
    Last edited: Dec 5, 2021
  2. Laurie-Unity


    Unity Technologies

    Mar 5, 2020
    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.