Using SKReceiptRefreshRequest in background task

Hi,

I am planning to use SKReceiptRefreshRequest inside a BGAppRefreshTaskRequest in iOS13, to check whether a subscription has auto-renewed or not. I haven't seen it documented anywhere whether this is supported or not. I've tried it using the sandbox, and sometimes it works, sometimes it asks me to login to the Sandbox account again while the app is running in the background, and sometimes it doesn't work at all.


I am calling the _simulateLaunchForTaskWithIdentifier call to simulate a background App Refresh. I do this while the app is in the background, and it sometimes gets stuck. It works better if the app is in the foreground and I call the same private API to simulate the App Refresh.


I'm just wondering how reliable this would be in production. Would it keep bothering the user to login to their account? Is it expected that the StoreKit APIs be called from the background APIs (even to refresh a reciept), or is there some limitation that I'm not aware of? Just wanted to do the due-diligence before sending an update to production users.

Replies

You should not call SKReceiptRefreshRequest without warning the user that they may be asked to log into their App Store account because often they will have to do that. Therefore it should not be called from a background API.


You only need to check the subscription when the user wants to use the subscription. At that time, if the receipt does not indicate a renewed subscription, tell the user that you need to check their subscription and ask them to affirm that is ok. Then do the receipt refresh or a restoreCompeletedTransactions.


When an autorenewable subscription renews it sends out a transaction to all devices that have done a restoreCompletedTransaction and that have added a transaction observer. That results in a refreshed receipt and a call to updatedTransactions. Therefore, it may not ever be necessary to refresh the receipt.


And if you are doing this from a remote server, you can always send an outdated receipt to the Apple servers and get back a latest_receipt_info field that is 'refreshed'.

Thanks for the response. I want to figure out a way where I can process a autorenewing subscription in the background, since some of my features aren't in the app itself but work though Shortcuts and Share Extensions. The user can go days without opening my app, so the subscription might have expired in the meantime. I figure that with BGAppRefreshTaskRequest there is some possibility of being able to refresh the receipt. From what little I've read, it seems that for production accounts, the receipt is always present (or at least if one transaction has been processed), so SKReceiptRefreshRequest wouldn't need to prompt the user to login to their App Store account. Is that information incorrect? Are there particular circumstances when a user is prompted to login to the App Store, or is it random / unknowable?

>SKReceiptRefreshRequest wouldn't need to prompt the user to login to their App Store account. Is that information incorrect? Are there particular circumstances when a user is prompted to login to the App Store, or is it random / unknowable?


That information is incorrect. The system doesn't know if the person who is using the app is the App Store user who made a purchase. So the system needs to confirm that you are, in fact, that person. There is a setting that can be set by the user as to whether the App Store should check each time or only after a set number of minutes (I believe 15) since the last log in. So a log in will usually be required.


You can send any receipt to the Apple servers and get them to respond with "latest_receipt_info" so there is no need to refresh the receipt.