StoreKit 2 is Apple's Swift framework for in-app purchases and subscriptions, built on async/await and introduced at WWDC21. It runs on iOS 15 and later, the App Store signs every transaction in JWS format, and the ready-made StoreView and SubscriptionStoreView screens arrived in iOS 17.
What it is and how it differs from the original
StoreKit connects your app to the App Store. It shows the system payment sheet, processes the payment and tells the app about the purchase. Apple introduced the second version in 2021 at WWDC21 in Meet StoreKit 2, rebuilt from the ground up on Swift concurrency. Products load and purchases run with async/await, with no payment queue observers like in the first version.
Verification changed too. The app used to parse one shared receipt, and now every transaction arrives as its own object signed by the App Store in JSON Web Signature format. StoreKit checks the signature itself. The original classes, SKPaymentQueue and SKProduct, are deprecated as of iOS 18, and the SKProduct page points you to Product.
Where it lives in Xcode
There is nothing to install, StoreKit 2 ships with the SDK. Add import StoreKit and set Minimum Deployments to iOS 15 or later.
To test without the App Store you need a StoreKit configuration file. Create it from File › New, type storekit in the filter and pick StoreKit Configuration File. Turn it on in the scheme under Edit Scheme › Run › Options › StoreKit Configuration.
Versions and numbers from Apple
| What | Available from |
|---|---|
| Product, Transaction, Transaction.currentEntitlements | iOS 15, macOS 12, tvOS 15, watchOS 8 |
| Intro offer eligibility, isEligibleForIntroOffer | iOS 15 |
| StoreView, ProductView, SubscriptionStoreView | iOS 17, macOS 14, watchOS 10 |
| Configuration file synced with App Store Connect | Xcode 14 |
| Win-back offer type | iOS 18 |
| SKPaymentQueue and SKProduct from the first version | deprecated in iOS 18 |
| Monthly billing for an annual plan with a 12-month commitment | iOS 26.5 |
Per the StoreKit documentation and WWDC26, checked October 16, 2026.
A purchase, step by step
- At launch, start a task that listens to Transaction.updates. Renewals and purchases made outside the app arrive there.
- Load products with Product.products(for:) using the product IDs from App Store Connect.
- On tap, call product.purchase() and the system shows its confirmation sheet.
- Check the result. Unlock only for verified, unverified means the signature failed the check.
- Deliver the content and call transaction.finish().
- On every launch walk through Transaction.currentEntitlements. A Restore Purchases button calls AppStore.sync().
Ready-made purchase screens
Since iOS 17 you don't have to draw the purchase screen yourself. StoreView lists purchases, ProductView shows one, and SubscriptionStoreView shows the plans of one subscription group. Apple says one line of code is enough, and the name, price and period come from App Store Connect.
SubscriptionStoreView adds a close button and links to the terms and privacy policy from App Store Connect, and storeButton(_:for:) adds a restore button. For monthly billing of an annual plan, new in iOS 26.5, Apple showed the preferredSubscriptionPricingTerms modifier at WWDC26 in 2026. What a custom purchase screen needs is covered on the paywall page.
How to test before the App Store
A local configuration file works without App Store servers. Its prices are placeholders not tied to price points, but they show in the currency of the chosen storefront. It's a good place to try failed payments and promotional offer eligibility. A synced file, from Xcode 14, pulls purchases from App Store Connect but can't be edited in Xcode.
The next level is the App Store sandbox with test accounts. On an iPhone with iOS 16 or later, turn on Developer Mode to run from Xcode.
The agent in Appto writes the app in SwiftUI as a regular Xcode project and walks through every screen in the simulator itself, and you can try a purchase by hand on your iPhone or through TestFlight (app code in Appto).
Common mistakes
- Listening to Transaction.updates too late. Offer code redemptions, win-back offers and renewals arrive there, and without a listener from the first launch they are easy to miss.
- Unlocking on unverified. That transaction failed the signature check, so paid content must stay locked.
- Skipping finish(). An unfinished transaction stays in Transaction.unfinished and comes back for handling on the next launch.
- Looking for consumables in currentEntitlements. They aren't there, and neither are refunded or revoked purchases.
Questions
What is the minimum iOS version for StoreKit 2?
iOS 15, macOS 12, tvOS 15 and watchOS 8. The ready-made StoreView, ProductView and SubscriptionStoreView need iOS 17 or macOS 14 (Apple's documentation, checked October 16, 2026).
Should I migrate from the original StoreKit?
SKPaymentQueue and SKProduct are deprecated as of iOS 18, and the documentation points to Product in StoreKit 2. Apple presents its 2026 additions, like monthly billing for annual plans in iOS 26.5, on StoreKit 2.
What is JWS in StoreKit 2?
JSON Web Signature, a signing format. The App Store signs each transaction, StoreKit checks the signature and returns verified or unverified, and you can verify the jwsRepresentation string on your own server as well.
How do I restore purchases in StoreKit 2?
On launch walk through Transaction.currentEntitlements, which holds all non-consumables and active subscriptions. A Restore Purchases button calls AppStore.sync().
Build your own app in Appto
Appto checks the niche on fresh App Store data, designs the screens, writes the code, builds the App Store page and submits to Apple from your account or shows you what to press in App Store Connect. Runs on your own Claude Code or Codex.
Download for Mac