Get started with StoreKit 2 for iOS
Learn how to implement in-app purchases and subscriptions with StoreKit 2.
02 Oct 2023 · 4 min read
At WWDC21, Apple introduced a new version of StoreKit - StoreKit 2. The new in-app purchases API offers new features and improvements over the previous version, including async/await adaptation, more flexible payment options, improved testing and debugging tools.
In this article, we'll go though the StoreKit 2 API and learn how to use it to request in-app purchase products, how to purchase and validate them, how to restore in-app purchases, how to check user's entitlements and more.

Configuring products
The first step of offering in-app purchases in an iOS app is to create products we'd like to offer.
We can do that through App Store Connect or through a local StoreKit configuration file for testing. To get up and running quickly, we can just use a local StoreKit configuration file for now.

Checkout this article on StoreKit testing in Xcode to get more details on how to setup a StoreKit configuration file.
Requesting products
After setting up the file, we can load the configured products to show them to the user.
To load available products, StoreKit 2 provides the following method:
let productIdentifiers = ["com.example.budget", "com.example.standard", " com.example.solidary"]let products = try await Product.products(for: productIdentifiers)
Each Product has properties like displayName, description or displayPrice and more that we can directly use to show to the user.
If the product is an auto-renewable subscription, we can use the status and renewalInfo on the subscription property to provide users with appropriate informations about their subscription status.
Purchasing a product
If a user decides to purchase one of our products, we can call the purchase method on the selected product:
let result = try await product.purchase()
This method brings up a system confirmation sheet. The user can then confirm the purchase or cancel it.
The value of the purchase result represents the state of the purchase:
switch result {case .success(let result):switch verificationResult {case .verified(let transaction):// Give the user access to purchased content.// Complete the transaction with transaction.finish()case .unverified(let transaction, let verificationError):// The purchase failed verification for the provided reason.}case .pending:// The purchase is waiting for some user action.// Purchase may succeed in the future,// the resulting Transaction will be delivered via Transaction.updatescase .userCancelled:// The user cancelled the purchase.default:break}
Transactions & current entitlements
When offering paid content or features, we need to know which ones were already bought by a user to unlock them.
For that, StoreKit 2 provides access to current entitlements which lists all products the user is entitled to:
func refreshPurchasedProducts() async {for await result in Transaction.currentEntitlements {guard case .verified(let transaction) = result else { continue }if transaction.revocationDate == nil {self.purchasedProductIDs.insert(transaction.productID)} else {self.purchasedProductIDs.remove(transaction.productID)}}}
Restoring in-app purchases
When users reinstall an iOS app or download it on a new device, we as developers need to make sure that all in-app purchases the user previously made are restored.
When it comes to restoring in-app purchases, Apple recommends doing it proactively, without the user taking any actions. This can be done by using the current entitlements described above.
Additionally, we can offer a restore in-app purchases button which calls AppStore.sync() to enforce the synchronisation of transaction information.
Check out this article to learn more on how to restore in-app purchases with StoreKit 2 .

Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips