storekit
Implement, review, or improve in-app purchases and subscriptions using StoreKit 2. Use when building paywalls with SubscriptionStoreView or ProductView, processing transactions with Product and Transaction APIs, verifying entitlements, handling purchase flows (consumable, non-consumable, auto-renewa
By dpearson2699 · 3,522 installs
npx skills add dpearson2699/swift-ios-skills --skill storekit
Source repository · Upstream listing
StoreKit 2 In App Purchases and Subscriptions
Implement in app purchases, subscriptions, paywalls, and StoreKit testing using
StoreKit 2. Use the modern Swift based Product , Transaction ,
PurchaseAction , StoreView , and SubscriptionStoreView APIs. Avoid original
In App Purchase APIs ( SKProduct , SKPaymentQueue ) unless legacy OS support
requires them.
StoreKit views initiate purchases automatically. For custom controls, use
PurchaseAction in SwiftUI, purchase(confirmIn:options:) in UIKit/AppKit, and
product.purchase(options:) on watchOS.
Contents
[Product Types]( product types)
[Loading Products]( loading products)
[Purchase Flow]( purchase flow)
[Transaction.updates Listener]( transactionupdates listener)
[Entitlement Checking]( entitlement checking)
[SubscriptionStoreView (iOS 17+)]( subscriptionstoreview ios 17)
[StoreView (iOS 17+)]( storeview ios 17)
[Subscription Status Checking]( subscription status checking)
[Restore Purchases]( restore purchases)
[App Transaction (App Purchase Verification)]( app transaction app purchase verification)
[Purchase Options]( purchase options)
[SwiftUI Purchase Callbacks]( swiftui purchase callbacks)
[Common Mistakes]( common mistakes)
[Review Checklist]( review checklist)
[References]( references)
Product Types
Type Enum Case Behavior
Consumable .consumable Used once, can be repurchased (gems, coins)
Non consumable .nonConsumable Purchased once permanently (premium unlock)
Auto renewable .autoRenewable Recurring billing with automatic renewal
Non renewing .nonRenewing Time limited access without automatic renewal
Loading Products
Define product IDs as constants. Fetch products with Product.products(for:) .
Purchase Flow
Prefer StoreKit views for standard paywalls because they initiate purchases,
restore purchases, and display policy controls. For custom SwiftUI purchase
buttons, prefer PurchaseAction from the environment. Use direct
product.purchase(options:) for watchOS, and use purchase(confirmIn:options:)
for UIKit or AppKit confirmation. Always handle every PurchaseResult , verify
before access, deliver durably, then finish.
Transaction.updates Listener
Start at app launch, not when a paywall appears. Catches purchases from other
devices, Family Sharing changes, renewals, Ask to Buy approvals, refunds,
revocations, and unfinished transactions Apple emits once immediately after
launch. Keep the task retained for the app lifetime.
Entitlement Checking
Transaction.currentEntitlements emits non consumables, active or grace period
auto renewable subscriptions, and the latest non renewing subscription
transaction—including finished ones. It excludes consumables and refunded or
revoked products. Track consumable fulfillment separately, and apply the app's
expiration policy to non renewing subscriptions before granting access.
SwiftUI .currentEntitlementTask Modifier
SubscriptionStoreView (iOS 17+)
Built in SwiftUI view for subscription paywalls. Handles product loading,
purchase UI, and restore purchases automatically.
Custom Marketing Content
Use the container background and header patterns in
[SubscriptionStoreView Control Styles](references/storekit advanced.md subscriptionstoreview control styles).
Hierarchical Layout
Use SubscriptionOptionGroup , SubscriptionOptionSection , or
SubscriptionPeriodGroupSet to organize iOS 18+ options; see
[Subscription Group Management](references/storekit advanced.md subscription group management).
StoreView (iOS 17+)
Merchandises multiple products with localized names, prices, and purchase buttons.
ProductView for Individual Products
Subscription Status Checking
Renewal States
State Meaning
.subscribed Active subscription
.expired Subscription has expired
.inBillingRetryPeriod Payment failed, Apple is retrying
.inGracePeriod Payment failed but access continues during grace period
.revoked Apple refunded or revoked the subscription
Restore Purchases
StoreKit 2 handles restoration via Transaction.currentEntitlements . Add a
restore button or call AppStore.sync() explicitly.
On store views: .storeButton(.visible, for: .restorePurchases)
App Transaction (App Purchase Verification)
Verify the legitimacy of the app installation. Use for business model changes
or detecting tampered installations (iOS 16+).
Purchase Options
SwiftUI Purchase Callbacks
Common Mistakes
1. Not starting Transaction.updates at app launch
2. Forgetting transaction.finish()
3. Ignoring verification result
4. Using original In App Purchase APIs in new StoreKit 2 code
5. Not checking revocationDate
6. Hardcoding prices
7. Not handling .pending purchase result
8. Checking entitlements only once at launch
9. Missing restore purchases button
10. Subscription views without policy links
Review Checklist
[ ] Transaction.updates listener starts at app launch in App init
[ ] All transactions verified before granting access
[ ] transaction.finish() called only after durable content delivery
[ ] Revoked/refunded transactions excluded and entitlement state updated
[ ] .pending result shows Ask to Buy/deferred approval feedback
[ ] Restore purchases button visible on paywall and store views
[ ] Terms of Service and Privacy Policy links on subscription views
[ ] Prices shown using product.displayPrice , never hardcoded
[ ] Subscription terms (price, duration, renewal) clearly displayed
[ ] Free trial states post trial pricing clearly
[ ] No original In App Purchase APIs ( SKProduct , SKPaymentQueue ) unless legacy OS support requires them
[ ] Product IDs defined as constants, not scattered strings
[ ] StoreKit tests cover promotional offers, win back, offer codes, Ask to Buy, renewals, refunds, and revocations
[ ] Entitlements re checked on Transaction.updates and app foreground
[ ] Server side validation uses jwsRepresentation if applicable
[ ] Consumables delivered and finished promptly
[ ] Transaction observer types and product model types are Sendable when shared across concurrency boundaries
References
See [references/app review guidelines.md](references/app review guidelines.md) for IAP rules (Guideline 3.1.1), subscription display requirements, and rejection prevention.
See [references/storekit advanced.md](references/storekit advanced.md) for subscription control styles, offer management, testing patterns, and advanced subscription handling.
For submission, privacy, metadata, screenshots, and rejection risk audits use app store review .
For keyword, screenshot caption, ranking, and conversion strategy use app store optimization .
Official Apple docs: [Choosing a StoreKit API](https://sosumi.ai/documentation/storekit/choosing a storekit api for in app purchases), [Transaction.updates](https://sosumi.ai/documentation/storekit/transaction/updates), [Transaction.currentEntitlements](https://sosumi.ai/documentation/storekit/transaction/currententitlements),
[SubscriptionStoreView](https://sosumi.ai/documentation/storekit/subscriptionstoreview), and [PurchaseAction](https://sosumi.ai/documentation/storekit/purchaseaction).