According to Apple guidelines:
What url should I use to verify my receipt (iOS)?
Use the sandbox URL https://sandbox.itunes.apple.com/verifyReceipt while testing your application in the sandbox and while your application is in review.
Use the production URL http://buy.itunes.apple.com/verifyReceipt once your application is live in the App Store.
How should I do that? Do I send an app with the sandbox URL, and once reviewed I have to compile once again with the production one? I guess this would violate some review guideline, or would make reject the app when they realize the CRC or something isn't the same as what they tested, wouldn't it? Should I make some page in the middle???
I have the hope once validated, Apple would modify the bytecode in order to set the correct URL heh.
Where are you storing that URL?
According to the suggested setup from Apple, your server validates your receipt with iTunes after it is called from within your app. Your server then sends a receipt validation response back to your app, and optionally an upload URL for any uploads.
So the URL is located on your server, in a PHP script or similar. Once your app is approved you would change your server script to point to the iTunes production URL.
Therefore there is no need to update your app code after the review. In fact if you do, that requires the submission of a new version and a new review.
Related
Apple says in their documentation here:
Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures you don’t have to switch between URLs while your application is tested, reviewed by App Review, or live in the App Store.
And I did exactly that. Used the production url, got 21007 status code, then started using the sandbox Url, tested my purchase flow, and submitted the app for a review, got the review approved and am now ready for launch.
What doesn't make sense is that Apple says above "you don’t have to switch between URLs while your application is tested, reviewed by App Review, or live in the App Store." Does that mean that after I release my app, my servers are to continue using the sandbox url after I have released the app? That doesn't make sense. I would expect to start using the production url to validate receipts on my server.
Assuming I am correct, and you DO have to switch to the production url when the app is live - what happens in the future when I want to submit my app for review when I update the app, do I have to take care and put the sandbox url back?
You don't need to change your code after release. It should automatically switch between production and sandbox urls, based on the receipt and the response from the production endpoint.
Apple's documentation says:
Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code.
You will never receive a 21007 status code from the production endpoint when your app is live. A 21007 status means that you have a sandbox receipt in release mode. This only occurs with TestFlight and App Store Review.
You can safely leave the sandbox receipt validation code in place since the code path of checking against the sandbox url will not be used in the normal case.
When you submit a new version for review, and Apple tests it, you will once again get a 21007 response from the production endpoint and your code will attempt validation against the sandbox url.
I am about to submit my iOS app to Apple Store but there are some unclear points that I couldn't figure it out.
During the testing process I used Sandbox. I understand that a 1 month subscription's expiry date equals to 5 minutes in Sandbox. So when I purchase a product, the app sends a request to my server to validate the receipt. The server then calls the "https://sandbox.itunes.apple.com/verifyReceipt" url and the expiry date I receive like:
Purchase Date: 07/03/2020 - 16:45
Expires Date: 07/03/2020 - 16:50
I am doing the receipt validation on server as Apple suggested.
After I completed the IAP development, I have updated the url on server as "https://buy.itunes.apple.com". Then I tried to buy a product with my current Apple Id -not with a Sandbox account. This time the app returned "Cannot connect to iTunes" error. It make sense because my app isn't in Apple Store yet
My question is, when I submit my app how will Apple test my app? Should I keep the "https://sandbox.itunes.apple.com/verifyReceipt" url on the server and then once Apple approves the app replace the url with "https://buy.itunes.apple.com"? This part is confusing.
Apple states the following:
Important
Verify your receipt first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you do not have to switch between URLs while your application is tested, reviewed by App Review, or live in the App Store.
Source
So to answer your question: you use both urls. First you validate with the production url and when you receive a 21007 response you validate with the sandbox url.
I followed Ray Wenderlich's tutorial to implement receipt validation in my app. The code connects to Apple's validation server directly from my app rather than going through my own server.
After I submitted my first binary to the AppStore, I tested my app and the in-app purchasing didn't work because I had switched it over from the sandbox URL to the production URL.
Will this also fail when they AppStore reviewers test it and therefore be rejected? I've read this post but I'm still very confused about whether that applies to me if I'm not using my own server.
The solution is quite simple and it was explained on session 308 of WWDC 2012 (the video is available for registered developers). The session was related to subscriptions but you can extend it for in app purchases.
What happens is that when you develop you hard code your app to validate the receipt with the sandbox. Then you send the app to review, you clearly hard coded your app to validate the receipt with the production server.
But nothing prevents you from doing the validation in two steps:
always validate the receipt with the production server first, this will apply for 99% of your app life. If the receipt is validated, you're done.
if previous validation failed, just validate the receipt with the sandbox server. This should cover your development needs and of course fake receipts will fail validation too.
By the way, and this is officially stated in the documentation ONLY for subscriptions, if you try to validate a sandbox receipt with the production server you will get a specific status code; there is another status code that covers the case of production receipt validated with the sandbox server. In all cases the two worlds, sandbox and production, are always separated.
Don't forget also that with iOS7 added a new safer way to manage receipt validation directly from the device: consider in fact that receipt validation directly from the client (that you don't fully control, e.g. with jailbroken devices) is less secure than receipt validation done through a server you control.
Always verify your receipt first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you do not have to switch between URLs while your application is being tested or reviewed in the sandbox or is live in the App Store.
Note: The 21007 status code indicates that this receipt is a sandbox receipt, but it was sent to the production service for verification.
There is no public API to call to distinguish the production and sandbox environments so that you can decide which server to use ahead of time. If you have implemented the recommended receipt validation process, the fix can be implemented at your server which contacts the StoreKit server. If the status code for the validation attempt is 21007, then try again at the sandbox server.
It could fail. I had an app with in app purchases (but not based on my server, straight apple code) that work in development but crashed once released by Apple. It crashed because I had not done all the proper steps in iTunes Connect.
The surprising thing was that the reviewers didn't catch this, presumably since they were also working in a sandboxed environment.
I'm not sure this helps you, hope it does.
I have an iOS app with in APP purchase with server model, and ready for QA submission. According to Apple documents, my server should call "https://sandbox.itunes.apple.com/verifyReceipt" url for testing.
That means till my app is in QA I have to put this url in my server and when my app cleared the review process and ready for sale then I should change my url?
Ok, if that is the case, then how can I test my other application when the previous app is live? I have to create new urls to communicate with the server? I don't think this would be the only way.
OR
my application should tell my server whether it's a sandbox user or not? If yes, please help me how to check for that in the app.
Please help me if I am missing something.
Thanks.
I've got in-app purchases working just fine, and I'm going the server validation route. The server needs to know whether I'm in the sandbox or not, so for now I'm just sending it a "&sandbox=1" parameter. Of course when the full version of the app is out I won't be sending this parameter.
I'd rather not have this hardcoded in my app, as that will make testing difficult in the future, and it's one more (big) thing to remember to change before submitting builds to Apple.
Is there a way I can ask StoreKit if I am in the sandbox so I can then determine whether or not I need to send this parameter to my server? Alternatively, is there any other best practice for handling server validation?
Thinking about this more, should I just have the server always check the live system first, then the sandbox? If apple IDs are segregated between the live and sandbox systems then it wouldn't do any harm would it?
Thanks.
After a bit of digging I found this from Apple's Technical Note TN2259:
How do I verify my receipt (iOS)?
Always verify your receipt first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you do not have to switch between URLs while your application is being tested or reviewed in the sandbox or is live in the App Store.
So it looks like I should axe the &sandbox parameter completely and just do that. I really had to dig for this answer so I'm posting it here in hopes that someone else runs across it!
I encountered that very same problem, where my app was rejected because the "production" version of my app that I submitted was hardcoded to connect to a PHP script on my server that validates receipts with the real AppStore server (whereas my development build points to another PHP script that validates receipts with the sandbox server). However, after a few exchanges with Apple engineers, I found out that they use sandboxed user accounts to tests submitted applications, which explains why they got an error.
Instead of conditionally building my app to point to one script or the other, I will use a single script that tries the production server first and then falls back to the sandbox server if it receives the 21007 status code, as explained above!
Thanks a lot!
Always verify your receipt first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code.
Unfortunately, the technical note fails to mention this is only valid for auto-renewing subscriptions!
As the In-App Purchase Programming Guide mentions below table 7-1:
Important The non-zero status codes here apply only when recovering information about a auto-renewable subscription. Do not use these status codes when testing responses for other kinds of products.
For non-renewing subscriptions, the production server does not return a status code, but a proper receipt.
In case you are forced to use non-renewing and implement your own subscription expiring logic, a possible solution is to send your app version along to your server, and keep track of which versions are in development at the moment, as such you can redirect to the sandbox.itunes server to verify receipts where appropriate, and mimic the x-minute expiring time of a subscription (as sandbox.itunes does for auto-renewing) for development on your server.