11 Jul 2011 Lessons Learnt with iOS In-App Purchasing
Recently we released an iPhone app to the iTunes appstore which contains consumable products that can be purchased by a user. I want to share with you some of the pain we encountered when the app went live, and what errors we came across when configuring our server from sandbox to production.
1. Our application was “Cleared for Sale” but our products were not.
Unfortunately for us we don’t control the iTunes account and therefore have no control as to when our client wishes to approve an application for sale. In this instance the app was cleared for sale and able to be downloaded from the app store, but users were unable to buy any products as nothing was being returned in their ‘buy products’ screen.
It turned out the products that we assumed would be approved when the application was cleared for sale were not themselves cleared for sale – they were still waiting for us to clear them.
After we cleared them for sale it took about an hour and a half before they appeared in our application!
2. Attempting to purchase one of the products kept resulting in SKPaymentTransactionStateFailed error messages.
Even though our products were now appearing in our application, whenever we tried to purchase a product we were faced with the same transaction error.
After continually trying to buy products for 1 hour and coming close to pulling the plug… low and behold it magically started working … and we didn’t change a thing.
This seems to be a bit of a flaw with the whole in-app products approval process, because at the end of the day, to a user it looks as if your app is failing – when in fact it is an error on Apple’s side and not the client. I would argue that a product should not appear in your list of products-to-purchase if Apple have not done whatever magic is necessary at their end.
3. But wait: Our server is failing to verify the iTunes receipt!
We were almost in the clear and then encountered yet another error. This time it was on our server, which is responsible for receiving the receipt from our application and then verifying it against Apples’ https://itunes.apple.com/verifyReceipt service.
Sandbox Vs. Production
At no time did we encounter any issues when testing in staging against the https://sandbox.itunes.apple.com/verifyReceipt endpoint. For fun you can even put this URL into Firefox and you will get a result like this:
However we wrongly assumed that we could simply strip the word ‘sandbox’ off the iTunes URL and this would then become production…which works to some extent, but if you try it in Firefox https://itunes.apple.com/verifyReceipt you might receive a response you weren’t expecting.
This Connection is Untrusted
You have asked Firefox to connect securely to itunes.apple.com, but we can’t confirm that your connection is secure.
Normally, when you try to connect securely, sites will present trusted identification to prove that you are going to the right place. However, this site’s identity can’t be verified.
itunes.apple.com uses an invalid security certificate.
The certificate is only valid for the following names:
a248.e.akamai.net , *.akamaihd.net
(Error code: ssl_error_bad_cert_domain)
This was the same error our webapp was encountering, so after double checking the In app Purchase Programming Guide / Verifying a Receipt with the App Store.
Hidden in plain sight at step number 3 is the production App Store verify URL, which is https://buy.itunes.apple.com/verifyReceipt. Use this and it gives you no certificate exceptions and works exactly how you would expect.
Is it wrong for me to have expected that little detail to be highlighted just a tad bit better in the Apple documentation? Or were we the only ones who had assumed that you could simply strip off sandbox and believe that you would be pointing to production?