Hey, doing Redeem/Consume purchasing stuff and was curious what other people have been doing. My current approach is to call both PlayFab's RedeemGooglePlayPurchase and Google's ConsumeProduct in an AzureFunction to validate purchases, but wasn't 100% sure if this was the right approach. What is the recommended flow? I'm assuming that the validation is unsafe to call on the client side but I am not sure. There is a lot of outdated information online so I decided to ask here.
#Recommended IAP redemption/consumption flow
16 messages · Page 1 of 1 (latest)
(From the chat thread)
Per the Google Redemption tutorial, you will need to call consume after calling Redeem. We've talked about adding it to the backend (and may still at some point), but both Unity and Unreal will run this step for you so in the general it would be redundant.
Also, it's safe to call both RedeemGooglePlayInventoryItems and consume from the client.
Cool, I had no idea that Unity calls consume for us already
So all I have to do is call Redeem?
It does it in a specific way and I don't believe the sample we ship is correct (somebody is currently updating it).
Just make sure the Redeem call for the purchase returns a success result asynchronously -before- returning status Complete.
This bit is handling unity async callbacks incorrectly.
RedeemGooglePlayInventoryItemsResponse redeemResponse = new(); PlayFabEconomyAPI.RedeemGooglePlayInventoryItems(request, result => { redeemResponse = result; Debug.Log("Processed receipt validation."); }, error => Debug.Log("Validation failed: " + error.GenerateErrorReport())); if (redeemResponse?.Failed.Count > 0) { Debug.Log("Validation failed for " + redeemResponse.Failed.Count + " receipts."); Debug.Log(redeemResponse.Failed.Serialize().ToSafeString()); return PurchaseProcessingResult.Pending; } else { Debug.Log("Validation succeeded!"); } return PurchaseProcessingResult.Complete;
Thank you, it makes sense now that I know Unity consumes it automativally
I'm a bit surprised that redeem and consume can be called client side. When something is fully client side I just assume that it is hackable by the client
All the Redeem APIs are designed to be callable by the client (that's the primary use case). We have protections in the system design that make them safe.
What I meant is that calling Redeem and then telling Google that it isnt consumed yet
So not a PlayFab exploit but more of a Google one
But if its a widely used workflow I'll trust it
If you don't consume an entitlement, we do 2 things:
- Check whether we've already seen the receipt. If not, grant. If so, dedupe.
- Tell you what we did.
There are lots of response options based on the input, but it's always safe.
For anyone looking at this in the future: Should be like
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) {
GooglePurchase googlePurchase = GooglePurchase.FromJson(e.purchasedProduct.receipt);
string productId = googlePurchase.PayloadData.JsonData.productId;
string token = googlePurchase.PayloadData.JsonData.purchaseToken;
RedeemGooglePlayInventoryItemsRequest request = new RedeemGooglePlayInventoryItemsRequest() {
Entity = , //EntityKeyHere
Purchases = new List<GooglePlayProductPurchase>() {
new GooglePlayProductPurchase() {
ProductId = productId,
Token = token
}
}
};
PlayFabEconomyAPI.RedeemGooglePlayInventoryItems(request,
result => {
_storeController.ConfirmPendingPurchase(e.purchasedProduct);
},
error => {
Debug.LogError($"Failed to redeem purchase. {error.GenerateErrorReport()}");
});
return PurchaseProcessingResult.Pending;
}