Redeem Google Play Purchases INVALID_VERIFICATION_FAILED

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.

var receipt = product.receipt;
var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);

// Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html
var store = (string)wrapper["Store"];
var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt

#if UNITY_ANDROID
var details = (Dictionary<string, object>)MiniJson.JsonDecode(payload);

var id = product.definition.id.ToUpper();
var data = MiniJson.JsonEncode(details["json"]);
var signature = (string)details["signature"];
var localCost = (int)(product.metadata.localizedPrice * 100);
var localCurrency = product.metadata.isoCurrencyCode;

try
{
         var args = new RedeemGooglePlayStorePurchaseArgs(id, data, signature, localCost, localCurrency);
         var result = await EconomyService.Instance.Purchases.RedeemGooglePlayPurchaseAsync(args);

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.

[quote=“tomazsaraiva”, post:1, topic: 890603]
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.

var receipt = product.receipt;
var wrapper = (Dictionary<string, object>)MiniJson.JsonDecode(receipt);

// Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html
var store = (string)wrapper["Store"];
var payload = (string)wrapper["Payload"]; // For Apple this will be the base64 encoded ASN.1 receipt

#if UNITY_ANDROID
var details = (Dictionary<string, object>)MiniJson.JsonDecode(payload);

var id = product.definition.id.ToUpper();
var data = MiniJson.JsonEncode(details["json"]);
var signature = (string)details["signature"];
var localCost = (int)(product.metadata.localizedPrice * 100);
var localCurrency = product.metadata.isoCurrencyCode;

try
{
         var args = new RedeemGooglePlayStorePurchaseArgs(id, data, signature, localCost, localCurrency);
         var result = await EconomyService.Instance.Purchases.RedeemGooglePlayPurchaseAsync(args);

[/quote]
I think it’s because your

var data = MiniJson.JsonEncode(details["json"]);

Should be:

var data = (string)details["json"];

Yes, the RedeemGooglePlayStorePurchaseArgs does expect the purchaseData as a string

You may also want to look at your currency conversion to integerdifferently. 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

public class GoogleReceiptPayload
{
    public string json;
    public string signature;
}

public class GoogleReceipt
{
    public string payload;
}

The inner part of of the receiipt validation can look like

GoogleReceipt gr = JsonConvert.DeserializeObject<GoogleReceipt>(product.receipt);              
GoogleReceiptPayload grp = JsonConvert.DeserializeObject<GoogleReceiptPayload>(gr.payload);

// Convert decimal currency value to int, to correctly handle currencies with <> 2 minor currecy units
int localCurrencyInt = (int) AnalyticsService.Instance.ConvertCurrencyToMinorUnits(
      product.metadata.isoCurrencyCode,
      (double)product.metadata.localizedPrice);

// Redeem IAP
RedeemGooglePlayStorePurchaseArgs args = new RedeemGooglePlayStorePurchaseArgs(
        ecomomyRealMoneyPurchase.Id,
        grp.json,
        grp.signature,
        localCurrencyInt,
        product.metadata.isoCurrencyCode);            

RedeemGooglePlayPurchaseResult result = await EconomyService.Instance.Purchases.RedeemGooglePlayPurchaseAsync(args);

// Player's currency balance updated on server if receipt valid
Debug.Log($"IAP Purchase Success :: {result.Verification.Status}");
1 Like