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" } }
Answer by Sarah Zhang · Nov 29, 2021 at 08:48 AM
You can check the answer of this thread - Validation problems with iTunes receipts - Playfab Community to learn about how to troubleshoot the iOS receipt issues. As the above thread said, the “invalid receipt” error means some part of your receipt data is incorrect. For your case, if you can confirm the receipt you obtained from Apple is correct, you may need to print the original receipt JSON to check if the “receipt content” you sent is the same as the “Payload” of the original receipt JSON returned by Apple.
iOS Reciept Validation Failed - Request Timeout 16 Answers
Unity Mirror and Playfab GameServers 1 Answer
UpdateCharacterData problem and characterID . 2 Answers
Store with random items 1 Answer