I have implemented receipt validation locally on the device using OpenSSL and the asn1c compiler with help from Apple's Receipt Validation Programming Guide. My app only supports iOS 7 and up.
As recommended by Apple I call, [[NSBundle mainBundle] appStoreReceiptURL]
to get the app store receipt. I also do this when the app is 'first' launched before displaying any UI. This first launch call is needed as Apple recommends refreshing the receipt if its not there on first try. As a result of this call (SKReceiptRefreshRequest
) the app asks the user to enter their iTunes log in information.
Now the problem is Apple keeps rejecting the app saying I am making calls to their production servers instead of the sandbox servers. But that according to what I understand from the Receipt Validation Programming Guide is only valid if you use the second approach of validation and send data to Apple via your own secure server. I am however doing everything locally and am very confused about how to differentiate between the production and sandbox environments so that my app may pass review.
Any pointers or suggestions would be very helpful.
Alright so here is what worked for me, Apple approved the app last night after multiple rounds of review appeals and re-submissions spanning almost a month.
Do NOT try and refresh the receipt when the app launches and do not block the UI. What I was doing was not showing any UI on launch until a receipt was found, so when prompted for the iTunes password on launch pressing cancel would show the limited version of the app, entering a correct password would try and download a new receipt and act according to whether one was found.
So on launch if you find a receipt thats fine, if not do not try and refresh it.
DO however refresh it when the user presses the Restore Purchases option.
Hope this helps.