Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refreshing iOS app receipt: How to determine if user will need to sign in for app store?

I am implemeting Apple's "Grand unified receipt" on iOS 7, which allows the app to check an app's purchase receipt locally without having to contact Apple's servers for validation & verification. This works great if the user has a receipt stored in the app. Iin the case that the app is missing the receipt, the best practice is to request the app to refresh its receipt, as such:

SKReceiptRefreshRequest *request = [[SKReceiptRefreshRequest alloc] init]; [request setDelegate:self]; [request start]; 

The issue is that calling this code will ask the user to log in with his or her Apple ID. I am not 100% sure if this happens all of the time, or only if the user's app store login has timed out. I don't want to display the Apple ID login screen to users unless it is really necessary - I don't want people to be concerned that they will be charged incorrectly. I would like to show a display telling the user why they will be asked for their Apple ID password, but only if they will actually be required to enter their password. If they don't need to enter their password I want it to be a seamless and hidden process. What's the best way to proceed? I think the best way would be to check if the user will need to sign in for the app store, but I'm not sure if that is possible.

like image 250
Jason Avatar asked Nov 25 '13 09:11

Jason


People also ask

What is receipt validation in-app purchase?

The Receipt Verification Service (RVS) enables validation of purchases made by your app's users.

How do I validate my apple receipt?

Use the production URL https://buy.itunes.apple.com/verifyReceipt when your app is live in the App Store. For more information on these endpoints, see verifyReceipt. Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code.

How do you validate in-app purchases?

When a user makes an in-app purchase, cache the details (token, order id, and product id) locally on the client (i.e the app) then send it to your API. Your API should then send the purchaseToken to the Google Play Developer API for validation.


1 Answers

It is being very complicated to deal with this, so this answer may not be completely satisfactory (and I'm late - I'm aware of that), but still, hopefully this will help you a bit with this particular problem.

There's a chance I'm not doing this right either, but so far everything works and makes sense to me, but please if I'm "talking BS" here, feel free to correct me.

But anyway, you cannot really prevent the authentication alert from showing up, but there are a few ways you can minimize how many times it shows up.

You don't need to re-download a receipt that you know doesn't exist. If the user didn't buy or hasn't restored the receipt, you can avoid attempting to redownload a receipt and avoid the alert view altogether. This is something I have done:

if([[NSFileManager defaultManager] fileExistsAtPath:[[[NSBundle mainBundle] appStoreReceiptURL] path]] != YES) {     SKReceiptRefreshRequest *refresh = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];     [refresh start]; } 

I put this on my main.m file, before the main application loop, as my app has many "pro" features that get unlocked with IAP, but you can really put this where you find it relevant.

The main idea is that the receipt is an actual file stored in your app's directory. So everything we are doing here is checking if the receipt actually exists. If it doesn't, we save us the trouble of re-freshing it and therefore saving the trouble of showing the auth screen to the user.

If you want, you can put this code anywhere where the user might use a "pro" feature of your app. SKReceiptRefreshRequest inherits from SKRequest and because of that it will call the SKRequestDelegate methods. So the moment a user navigates to a screen with a pro feature, you can refresh the receipt, and then enable the feature when the delegate methods get called (and after doing the extra work of checking the receipt's contents).

The big downside with this approach is that it does require an internet connection. If your app works offline, the user will expect all its IAPs to work offline as well, so redownloading the receipt will be a problem under certain scenarios.

like image 165
Andy Ibanez Avatar answered Sep 22 '22 14:09

Andy Ibanez