Search Unity

Question Help with RedeemGooglePlayPurchaseAsync

Discussion in 'Economy' started by stu_dious, Mar 2, 2022.

  1. stu_dious

    stu_dious

    Joined:
    Feb 19, 2013
    Posts:
    32
    Hi, I'm using Economy Beta but regarding IAPs, have been relying on the Sample code provided (4.1.3) I've not seen anything regarding Economy integration though e.g. RedeemGooglePlayPurchaseAsync. Prior to trying this I've been processing purchases rewards manually e.g. awarding currency.

    I've tried following another resolved thread regarding the redemption of purchases but am having problems the solution provided. Any insight would be great, thanks. Trying it as suggested within 'ProcessPurchase' I get the error 'get_cloudProjectId can only be called from the main thread.'

    To add to this, the Unity docs suggested 'json' and 'signature' keys link to deprecated ''Google Play Billing AIDL' docs:
    https://developer.android.com/google/play/billing/billing_reference#purchase-data-table

    Code (CSharp):
    1. public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    2.         {
    3.             _purchaseInProgress = false;
    4.             var iapReturnCode = IAPReturnCode.OK;
    5.  
    6.             var id = args.purchasedProduct.definition.id.Trim();
    7.             var msg = string.Format("[StorePurchasesHelper] process purchase: PASS. Product: {0}{1}",
    8.                 args.purchasedProduct.definition.id, Environment.NewLine);
    9.             Helper.Log(msg);
    10.  
    11.             //if (validPurchase)
    12.             try
    13.             {
    14.                 var receipt = args.purchasedProduct.receipt;
    15.                 var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);
    16.                 if (wrapper == null)
    17.                 {
    18.                     throw new Exception();
    19.                 }
    20.  
    21.                 // Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html
    22.                 var store = (string)wrapper["Store"];
    23.                 var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt
    24.  
    25.                 // For GooglePlay payload contains more JSON
    26.                 if (_isGooglePlayStoreSelected)
    27.                 {
    28.                     var details = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
    29.                     var gpJson = (string)details["json"];
    30.                     var gpSig = (string)details["signature"];
    31.  
    32.                     var redeemArgs = new Purchases.RedeemGooglePlayStorePurchaseArgs(
    33.                         args.purchasedProduct.definition.id,
    34.                         gpJson,
    35.                         gpSig,
    36.                         (int)(args.purchasedProduct.metadata.localizedPrice * 100),
    37.                         args.purchasedProduct.metadata.isoCurrencyCode);
    38.  
    39.                     var redeemResult = Task.Run(async () => await Economy.Purchases.RedeemGooglePlayPurchaseAsync(redeemArgs)).Result;
    40.  
    41.                     if (redeemResult.Verification.Status == GoogleVerification.StatusOptions.VALID)
    42.                     {
    43.                         Helper.Log(string.Format("{0} redeemed successfully.{1}",
    44.                             args.purchasedProduct.definition.id, Environment.NewLine));
    45.                     }
    46.                     else
    47.                     {
    48.                         Helper.Log(string.Format("{0} verification failed with status:{1}.{2}",
    49.                             args.purchasedProduct.definition.id,
    50.                             redeemResult.Verification.Status.ToString(),
    51.                             Environment.NewLine), true, Helper.LogType.Warning);
    52.  
    53.                         iapReturnCode = IAPReturnCode.FAILED;
    54.                     }
    55.                 }
    56.                 else
    57.                 {
    58.                     // ToDo .....
    59.  
    60.                     //var redeemArgs = new Purchases.RedeemAppleAppStorePurchaseArgs("PURCHASE_ID", "RECEIPT_FROM_APP_STORE", 0, "USD");
    61.                     //var redeemResult = Task.Run(async () => await Economy.Purchases.RedeemAppleAppStorePurchaseAsync(redeemArgs)).Result;
    62.                 }
    63.             }
    64.             catch (Exception e)
    65.             {
    66.                 Helper.LogException(e);
    67.  
    68.                 iapReturnCode = IAPReturnCode.FAILED;
    69.             }
    70.  
    71.             PurchaseCompleteEvent?.Invoke(id, iapReturnCode, PurchaseFailureReason.Unknown);
    72.  
    73.             return PurchaseProcessingResult.Complete;
    74.         }
     

    Attached Files:

    Last edited: Mar 2, 2022
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Does IAP work as expected when you don't implement the redeem logic, are you able to make a purchase by just returning PurchaseProcessingResult.Complete with no other code? Also, what Unity docs are you referring to? You pointed to android.com
     
  3. stu_dious

    stu_dious

    Joined:
    Feb 19, 2013
    Posts:
    32
    Hi @JeffDUnity3D, yeah, the actual purchases appear to be fine.

    Prior to adding the try-catch RedeemGooglePlayPurchaseAsync code I just used the store Identifier to source the matching RealMoneyPurchaseDefinition then awarded the currency manually (Economy.PlayerBalances.IncrementBalanceAsync). Reading docs again though, I thought I was supposed to actually be using RedeemGooglePlayPurchaseAsync.

    Regarding the GooglePlay payload:
    https://docs.unity3d.com/Packages/com.unity.purchasing@4.1/manual/GoogleReceipt.html

    INAPP_PURCHASE_DATA & INAPP_DATA_SIGNATURE links.

    Cheers, s
     
  4. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Can you confirm that you received the system purchase popup on your Android device? Is your user account configured as a tester? If so, they the dialog should say your credit card won't be charged. Unity IAP is indeed using Google Play Billing v3, so the documentation needs to be updated.
     
  5. stu_dious

    stu_dious

    Joined:
    Feb 19, 2013
    Posts:
    32
    Yeah, I'd see Google's purchase popups and the error would be thrown after that.

    Yeah, I'm registered as a tester and correct, no charge to my card.

    Cheers
     
    JeffDUnity3D likes this.
  6. tomazsaraiva

    tomazsaraiva

    Joined:
    Mar 19, 2009
    Posts:
    22
    @stu_dious did you got this working? I was always receiving the INVALID_RECEIPT error but I changed to your code and now it's stuck in the RedeemGooglePlayPurchaseAsync call.
     
  7. stu_dious_

    stu_dious_

    Joined:
    Apr 18, 2022
    Posts:
    4
    Sorry Tomaz, it's not something I've had the opportunity to go back to. Think we just used Unity's CrossPlatformValidator to check a purchase receipt was returned then handled the purchase reward locally or in CloudCode.
     
    tomazsaraiva likes this.