Why In-App Purchases
In-App purchases (IAP) are one of the best ways to monetize your mobile application. However, setting up IAP and dealing with its perks can be tricky. In this post, I will try to share what I have learned.
Getting Started
I am not going to talk about how to set up in-app purchases on App Store Connect. You can check the following Tutorial for the whole process. When you’re testing IAP, keep following points in mind;
- Test your IAP with the Sandbox account. Create some sandbox users and only test your in-app purchases with those accounts. When creating accounts, use
user1+myemail@mydomain.com
pattern to create multiple users. - Start your In-app purchase manager immediately. Possibly in your
AppDelegate
. This is very important. The user’s receipt can change and you have to react to those changes. Never start your IAP manager only in some portions of your app. It must be started as early as possible. - Don’t forget to complete transactions when the purchase is successful. If you don’t call
SKPaymentQueue.default().finishTransaction(transaction)
, your delegate will be called constantly. It is also very important that you callSKPaymentQueue.default().finishTransaction(transaction)
after you deliver the goods. - Verify the receipts. Different hacks allow users to fake receipts on Jailbroken devices. You can verify the receipt locally or by using a remote server. However, using a remote server is always a better idea. Since you will have full control over receipt validation can also keep records of your customers.
Perks of Online Verification
During verification, you must be aware of the following issues.
- Store
receipt
in your database. This is very important. Because if the user doesn’t send receipt data, you can use the old receipt to verify the current status. This is crucial to extend your subscription to other platforms in which AppStore Receipt is not available. - Send TestFlight receipt to sandbox endpoint and production receipt to production endpoint. If the status code is
21007
it means this receipt is for the TestFlight environment but send to the production server and if the status code is21008
then this receipt is for the production environment but send to TestFlight environment. Switch the server URL if you get one of those codes. - Compare status codes to the official status Code of the backend. Please check Status Codes for possible codes. If the server is not available or status code is
21005
, you should retry it later on - When you send the receipt to App Store backend, the result only shows whether the receipt is cryptographically correct or not. It is your responsibility to check the structure of receipt to validate it. If JSON
status
field is 0 it doesn’t mean that user bought the goods. - Check
receipt.bundle_id
matches your Bundle ID -
Check the
receipt.in_app
array and be sure that- It is not empty
product_id
matches your product- If you have a subscription, check
expires_date
is not later than today’s date. - If
in_app
entry hascancellation_date_ms
it means the user got the refund.