We finally decided to implement In-App Purchase in our applications. And what a journey ! The Apple documentation is as brief as usual …. So I gather here the posts that helped me to go through that :
- A step-by-step post by Troy here : it is not up to date but I found it really useful.
- A post pointing some tricky points by Cocoanetics.
- A complete kit to include in app : MKStoreKit with the associated blog.
- A product which is set “ in iTunes Connect will always be available in Sandbox environment : you can not test it’s availability in sandbox environment.
- For auto-renewable subscriptions, you have to write Privacy-Policy for your application. I found an example on the Apple website. And I created my own page here.
- If you work with a server side and want to verify receipt sent by Apple after a purchase : the receipt have to be encoded in 64 bytes. Don’t do it on the server in php code but encode it in the application and then send it to your server. Their is NSData+base64.h/m files in MKStoreKit which provide functions to do that.
- Test of auto-renewable subscription in Sandbox environnement :”1 month subscriptions auto-renew every 5 minutes. So far so good. They auto-renew 5 times and then they stop, so after 25 minutes you’ll get the 21006 error. However even when repurchasing the same subscription it will NOT auto-renew again on the same test account since it has already auto-renewed 5 times. So if you want to test renewal and you have been messing with these subscriptions for a while you need to create a new itunes connect test user. This is very annoying honestly and it would be a lot easier if we could just reset the entire purchase history of a test user account.”
- A point that wasn’t described nowhere : to restore purchase for user who are re-installing application :
you should provide a “Restore Purchases” button (or similar) which calls
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
Assuming you’ve added a transaction observer already, and implemented the protocol including a case to handle a restored transaction (with state
SKPaymentTransactionStateRestored) this will work.