Search Unity

Resolved Redeem Google Play Purchases INVALID_VERIFICATION_FAILED

Discussion in 'Economy' started by tomazsaraiva, Aug 9, 2022.

  1. tomazsaraiva

    tomazsaraiva

    Joined:
    Mar 19, 2009
    Posts:
    22
    Hey,

    I'm having a problem using RedeemGooglePlayPurchaseAsync to validation purchases. This is the code that I'm using but it always returns INVALID_VERIFICATION_FAILED.

    Am I doing anything wrong?

    Thanks for your help.

    Code (CSharp):
    1.  
    2. var receipt = product.receipt;
    3. var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);
    4.  
    5. // Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html
    6. var store = (string)wrapper["Store"];
    7. var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt
    8.  
    9. #if UNITY_ANDROID
    10. var details = (Dictionary<string, object>)MiniJson.JsonDecode(payload);
    11.  
    12. var id = product.definition.id.ToUpper();
    13. var data = MiniJson.JsonEncode(details["json"]);
    14. var signature = (string)details["signature"];
    15. var localCost = (int)(product.metadata.localizedPrice * 100);
    16. var localCurrency = product.metadata.isoCurrencyCode;
    17.  
    18. try
    19. {
    20.          var args = new RedeemGooglePlayStorePurchaseArgs(id, data, signature, localCost, localCurrency);
    21.          var result = await EconomyService.Instance.Purchases.RedeemGooglePlayPurchaseAsync(args);
    22.  
     
  2. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Are you still having problems with the validation?

    If you can log the values your are sending to the
    RedeemGooglePlayStorePurchaseArgs
    method I can manually check them and perhaps advise. Feel free to DM me the values and a link to you Unity Dashboard fot the project.
     
  3. CameronDWills

    CameronDWills

    Joined:
    Feb 26, 2021
    Posts:
    91
    I think it's because your
    Code (CSharp):
    1. var data = MiniJson.JsonEncode(details["json"]);
    Should be:
    Code (CSharp):
    1. var data = (string)details["json"];
     
  4. Laurie-Unity

    Laurie-Unity

    Unity Technologies

    Joined:
    Mar 5, 2020
    Posts:
    220
    Yes, the
    RedeemGooglePlayStorePurchaseArgs
    does expect the
    purchaseData
    as a
    string


    You may also want to look at your currency conversion to
    integer
    differently. It isn't safe to assume that all currencies have two minor currency units and multiply them by 100. Look at currencies like the Yen or Chilean Peso. There is a
    AnalyticsService.Instance.ConvertCurrencyToMinorUnits
    method in the Analytics SDK that can help you with this.

    Here are some code snippets that show a Google receipt validation with Economy, using Newtonsoft JSON library.

    Assuming that the these classes are declared
    Code (CSharp):
    1. public class GoogleReceiptPayload
    2. {
    3.     public string json;
    4.     public string signature;
    5. }
    6.  
    7. public class GoogleReceipt
    8. {
    9.     public string payload;
    10. }
    The inner part of of the receiipt validation can look like
    Code (CSharp):
    1. GoogleReceipt gr = JsonConvert.DeserializeObject<GoogleReceipt>(product.receipt);              
    2. GoogleReceiptPayload grp = JsonConvert.DeserializeObject<GoogleReceiptPayload>(gr.payload);
    3.  
    4. // Convert decimal currency value to int, to correctly handle currencies with <> 2 minor currecy units
    5. int localCurrencyInt = (int) AnalyticsService.Instance.ConvertCurrencyToMinorUnits(
    6.       product.metadata.isoCurrencyCode,
    7.       (double)product.metadata.localizedPrice);
    8.  
    9. // Redeem IAP
    10. RedeemGooglePlayStorePurchaseArgs args = new RedeemGooglePlayStorePurchaseArgs(
    11.         ecomomyRealMoneyPurchase.Id,
    12.         grp.json,
    13.         grp.signature,
    14.         localCurrencyInt,
    15.         product.metadata.isoCurrencyCode);            
    16.              
    17. RedeemGooglePlayPurchaseResult result = await EconomyService.Instance.Purchases.RedeemGooglePlayPurchaseAsync(args);
    18.  
    19. // Player's currency balance updated on server if receipt valid
    20. Debug.Log($"IAP Purchase Success :: {result.Verification.Status}");  
     
    socialtrens likes this.