SkillAgentSearch skills...

IAPDemo

Implementing and testing In-App Purchases in Xcode 12 and iOS 14, including local receipt validation.

Install / Use

/learn @russell-archer/IAPDemo
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

In-App Purchases with Xcode 12 and iOS 14

Implementing and testing In-App Purchases with StoreKit1 in Xcode 12 and iOS 14.

See also StoreHelper for details on implementing and testing in-app purchases with StoreKit2 and StoreHelper in Xcode 13, Swift 5.5, iOS 15.

Disclaimer. The source code presented here is for educational purposes. You may freely reuse and amend this code for use in your own apps. However, you do so entirely at your own risk.

See on IAPHelper on GitHub for IAPHelper source.

Updated 31st December 2020

Added notes on Support for Strong Customer Authentication transactions in the European Economic Area with reference to new a Apple Support Document.


See IAPDemo on GitHub for source code. The HelloIAPWorld source is also available on GitHub.

References:


Contents


Overview

The code we write to manage in-app purchases is critically important to the success of our apps. However, if you’ve not tackled it before, implementing and testing in-app purchases is daunting, complex and seems way more involved than you’d expect!

Anybody wanting to support in-app purchases faces a similar set of challenges:

  • How do you define the set of products that can be purchased in your app?
  • Defining your in-app purchases in App Store Connect
  • Working with StoreKit to request localized product data from the App Store and initiate purchases
  • Implementing StoreKit delegate methods to process async notifications for purchase success, failure, restoring purchases, etc.
  • Handling edge-cases, like when a purchase is deferred because it requires parental permissions, or when entitlements for a user have changed and access to the specified IAPs has been revoked
  • Should you handle App Store receipt validation on-device or server-side?
  • Should you write your own receipt validation code or use a service like RevenueCat?
  • Working with OpenSSL and the arcane PKCS #7 and ASN.1 data structures found in receipts
  • Writing code to validate the receipt and read in-app purchase data
  • Creating and managing sandbox accounts used for testing

When I first implemented in-app purchases in one of my iOS apps in 2016 the two main pain-points were:

Receipt validation options

The App Store issues an encrypted receipt when in-app purchases are made or restored (when an app’s first installed, no receipt is present). This receipt contains a complete list of all in-app purchases made in the app.

There are four receipt validation approaches available:

  1. Server-side receipt validation
  2. On-device receipt validation
  3. Third-party receipt validation service
  4. No receipt validation

Server-side validation

This is probably the easiest option, but you need an app server to send requests to the App Store server. Apple specifically says you should not create direct connections to the App Store server from your app because you can’t guard against man-in-the-middle attacks.

Despite this clear warning, the web has many examples (including commercial offerings) of using direct app-to-App Store connections. The advantage of using server-side validation is that you can retrieve easily decoded JSON payloads that include all the in-app purchase data you need. We don’t cover server-side validation in this example.

On-device validation

On-device validation is somewhat tricky and requires use of the C-based OpenSSL library to decrypt and read the receipt data. Note that including the required two OpenSSL libraries adds nearly 50MB to your app.

I first started supporting in-app purchases in 2016. I fully expected StoreKit or some other Apple framework to provide ready-to-use abstractions allowing for easy access to the low-level cryptographic data structures in the receipt. However, as I looked deeper into the “where’s the receipt processing framework?” conundrum the more the answer became clear: having a ready-to-use framework creates a security risk because “hackers” wishing to access your in-app purchases for-free know in advance where and how to concentrate their attacks. Apple’s answer was (and still is): create your own custom receipt validation solution because a unique solution will be harder to hack.

Clearly a custom solution (if done correctly) will be more secure. But, as all developers know that have attempted it, writing security-critical cryptographic-related code is hard and if you get it wrong disasters will happen! In my opinion, surely it would be better for Apple to provide something that enables correct and reasonably secure receipt validation for the general app developer?

However, at present (November 2020) you have no choice if you want to validate and read receipt data on-device: you must develop your own OpenSSL-based solution. If you don’t feel confident doing this feel free to adapt (or use as-is) the code presented herein.

Third-party receipt validation service

A number of third parties provide receipt validation services, normally as part of a larger in-app purchase, subscription an

View on GitHub
GitHub Stars23
CategoryDevelopment
Updated2y ago
Forks5

Languages

Swift

Security Score

65/100

Audited on Jan 19, 2024

No findings