Hello, I am currently having an issue with validating receipts on iOS platforms. On Google Play, all seems to be working fine.
I was having an issue with processing transactions. The first time I purchased an item it was passing through fine. But for the second time I purchased the same item, it has prompted me "This In-App Purchase has already been bought. It will be restored for free" even though the item is a consumable. It behaves as if I have not consumed or finished the transaction. But I am completing all transactions as documented in Unity Docs "Saving purchases to the cloud". While I was looking for a possible solution, I have realized that I have forgot to install the Apple addon in PlayFab and figured it could be that causing the issue.
After that I have installed the addon with the bundle id & shared secret, now none of the transactions are passing through on iOS. I inspected the log in PlayFab and it seems that the receipt is invalid. I have not found what could be the issue here since all is working fine on Google Play. Could you please provide assistance. Thanks.
Here is the code snippet where I send the receipt data to PlayFab:
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) { ... #if UNITY_ANDROID var googleReceipt = GooglePurchase.FromJson(args.purchasedProduct.receipt); menuManager.playfabManager.AuthService.ValidateGooglePlayReceipt( args.purchasedProduct.metadata.isoCurrencyCode, (uint)(args.purchasedProduct.metadata.localizedPrice * 100), googleReceipt.PayloadData.json, googleReceipt.PayloadData.signature, args.purchasedProduct ); #elif UNITY_IPHONE || UNITY_IOS var appleReceipt = ApplePurchase.FromJson(args.purchasedProduct.receipt); menuManager.playfabManager.AuthService.ValidateIOSReceipt( args.purchasedProduct.metadata.isoCurrencyCode, (int)(args.purchasedProduct.metadata.localizedPrice * 100), appleReceipt.Payload, args.purchasedProduct ); #endif return PurchaseProcessingResult.Pending; } public class JsonData { // JSON Fields, ! Case-sensitive public string orderId; public string packageName; public string productId; public long purchaseTime; public int purchaseState; public string purchaseToken; } public class PayloadData { public JsonData JsonData; // JSON Fields, ! Case-sensitive public string signature; public string json; public static PayloadData FromJson(string json) { var payload = JsonUtility.FromJson<PayloadData>(json); payload.JsonData = JsonUtility.FromJson<JsonData>(payload.json); return payload; } } public class GooglePurchase { public PayloadData PayloadData; // JSON Fields, ! Case-sensitive public string Store; public string TransactionID; public string Payload; public static GooglePurchase FromJson(string json) { var purchase = JsonUtility.FromJson<GooglePurchase>(json); purchase.PayloadData = PayloadData.FromJson(purchase.Payload); return purchase; } } public class ApplePurchase { // JSON Fields, ! Case-sensitive public string Store; public string TransactionID; public string Payload; public static ApplePurchase FromJson(string json) { var purchase = JsonUtility.FromJson<ApplePurchase>(json); return purchase; } }
FYI. I am calling ConfirmPendingPurchase in the result callbacks of both ValidateGooglePlayPurchase & ValidateIOSReceipt.
This is the Raw Even JSON of the receipt validation:
{ "EventName": "player_receipt_validation", "PaymentProvider": "iTunes Sandbox", "PaymentType": "ReceiptValidation", "ReceiptContent": "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", "Valid": false, "Error": "Invalid receipt", "EntityId": "F49199EEDADC143C", "EventNamespace": "com.playfab", "EntityType": "player", "Source": "PlayFab", "TitleId": "ECA35", "EventId": "3e979d6bfedb42fbaf819fb8e971d938", "SourceType": "BackEnd", "Timestamp": "2021-11-28T16:43:50.9444168Z", "History": null, "CustomTags": null, "Reserved": null, "PlayFabEnvironment": { "Vertical": "master", "Cloud": "main", "Application": "mainserver", "Commit": "f4e9e95" } }