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 call SKPaymentQueue.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 is 21008 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 has cancellation_date_ms it means the user got the refund.

I am available for new work
Interested? Feel free to reach