-
-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: No verification with remote server of local receipt on iOS when calling GetPurchasesAsync. #28
Comments
How would you normally do this in iOS? Do you have apple docs on this? |
Well, I'm not sure the apple docs are very clear. And if the restore is the right place for this. Let's say I validate purchases remotely.
What I see missing, it's a step after 6 to Validate the receipt with the remote server. As you can see, a new device doing In my specific case-scenario, I give the client an access token if the receipt is valid, so when it goes to another device and call restore purchases. I have no instance to exchange the access token with the receipt. Also (not this issue, but somehow related), in my specific case, if the client doesn't have a valid token anymore (this may happen for several reasons) I need to validate the receipt with my server again. This means I don't need a restore process, only a way to revalidate the current receipt again. To solve both this issues, I forked the project and made this adjustments to the
Hope this makes sense. If you see that I'm thinking/doing this wrong or need more information please let me know. I'm doing iOS first and will implement Android and UWP in the following days. sidenote: I can spot another issue with the auto renewal process on this library but I will open a new issue when i have sorted it out. |
So, I think I would need to do this: public async Task<IEnumerable<InAppBillingPurchase>> GetPurchasesAsync(ItemType itemType, IInAppBillingVerifyPurchase verifyPurchase = null)
{
var purchases = await RestoreAsync();
var converted = purchases.Where(p => p != null).Select(p => p.ToIABPurchase());
var items = new List<InAppBillingPurchase>();
foreach (var purchase in converted)
{
var validated = await ValidateReceipt(verifyPurchase, purchase.ProductId, purchase.Id);
if (validated)
items.Add(purchase);
}
return items;
} As you would need to validate each purchase... I would assume |
I don't think there's a way to validate the receipt for each individual purchase separately. There's only one receipt with all transactions that can be validated remotely as far as I know, (i might be wrong here!) so I think the code should be more like what I shown: When you have N purchases, validate the only receipt you have and if it's valid, all purchases are valid, else treat all as not valid. |
ahhh got it... so does it need the transaction id and the product id? I was reading through http://jonathanpeppers.com/Blog/securing-in-app-purchases-for-xamarin-with-azure-functions maybe @jonathanpeppers has an idea? |
Nope, no transactionId nor productId are required beside the receipt. Everything is contained inside the receipt. I don't know why @jonathanpeppers is doing all the checks after this line
at that point you are dealing with your server and apple's. Unless you don't trust the connection between your server and apple, the success from them should be more than enough, but that is server validation not related to this particular library. Now I see where you got the receipt processing for only user initiated purchases. His method have the same issue. |
Hi @Bartmax This code was ported from a real app, so there is some stuff in there that could be removed for the simplest case. I would recommend verifying the app bundle id, purchase id, and that the transaction id is unique so that:
A simple way to do this is to just hardcode accepted bundle ids/purchase ids on your server. But if you are just trying to make it a little harder to hack, you can only use the receipt data and simplify my example a bit. |
I am now propagating up the ids of transaction and product id so that will help perhaps and then bundle id the dev can grab in their source code |
Bug
When calling
GetPurchasesAsync
the receipt from the local device is not verified against the remote server.https://github.com/jamesmontemagno/InAppBillingPlugin/blob/master/src/Plugin.InAppBilling.iOS/InAppBillingImplementation.cs#L85
Version Number of Plugin:
Device Tested On:
Simulator Tested On:
Expected Behavior
Call to
VerifyPurchase
Actual Behavior
No call to
VerifyPurchase
Steps to reproduce the Behavior
The text was updated successfully, but these errors were encountered: