StoreKit 2 subscription price increase consent: what Apple shows subscribers and what you control
When you raise an iOS subscription price, Apple runs a subscriber consent flow you cannot bypass or redesign. This guide explains every step—what Apple sends, what your StoreKit 2 code must handle, and how to recover subscribers who decline.
Raising your iOS subscription price triggers one of Apple's most consequential UX flows — the subscriber consent sequence. Get it wrong and you lose subscribers who would have stayed; ignore it and you risk large-scale forced cancellations at the billing date. StoreKit 2 changed the mechanics substantially from the original approach, and policy updates through 2025–2026 tightened the rules further. This post walks through exactly what happens, who controls what, and how to implement the consent outcome handling correctly.
What "subscriber consent" means in the StoreKit 2 era
When Apple introduced subscription price increase consent and later overhauled it under StoreKit 2, the core principle stayed the same: existing subscribers must explicitly agree to pay a higher price. What changed was the mechanism and the granularity of outcomes your app receives.
Under the original approach, Apple sent an email to the subscriber and displayed a modal inside the App Store. If the subscriber did not tap "Agree" within the consent window — typically before their next billing date — the subscription lapsed. The developer had no real-time signal of where each subscriber stood; you would only learn about lapses after the fact from your analytics or a Server Notifications webhook.
Under StoreKit 2, Apple exposes a priceConsentStatus field on Product.SubscriptionInfo.RenewalInfo, letting your app react to pending and resolved states in real time. Apple still controls the consent modal itself — you cannot redesign it or intercept it — but you now get structured, query-able state you can act on before the billing date arrives.
One nuance developers frequently miss: the consent requirement only applies to existing subscribers at the time of the price change. New subscribers after the effective date simply see and pay the new price with no consent step. If you are raising prices specifically to grow ARPU on new cohorts while grandfathering existing ones, the consent flow is irrelevant for the growth side of the equation. See Apple's grandfathering rules for subscription price changes for a full breakdown of who qualifies for which treatment.
The consent flow mechanics: what Apple shows, what you provide
When you publish a price change in App Store Connect with a future effective date, Apple begins the consent flow automatically. The table below maps each step to who controls it and what input your team provides:
| Step | Controlled by | What happens | Your input |
|---|---|---|---|
| Price change published | Developer | New price becomes visible in App Store Connect; consent window opens for each existing subscriber relative to their billing date | Effective date — Apple recommends at least 7 days ahead; many developers use 30+ days for higher-ARPU categories |
| Email notification | Apple | Apple emails the subscriber with old price, new price, and a link to manage the subscription | None — Apple generates the email copy from your app name and the price delta; you cannot customize the language |
| Push notification | Apple | A system-level push (not a local notification from your app) prompts the subscriber to review the change | None — you cannot send a competing system push about the same price change |
| In-app modal | Apple | When the subscriber opens the App Store or, in some flows, your app itself, Apple surfaces a sheet showing old vs new price with Agree / Decline options | None — you cannot suppress the sheet or alter its copy |
| Consent signal to your backend | Apple → Developer | Server Notifications v2 fires a PRICE_INCREASE event as status changes; transaction updates carry consent outcome |
Your Transaction.updates listener and Server Notifications v2 endpoint handle and record outcomes |
The underlying design philosophy is deliberate: Apple's rationale is that a trusted, system-level notification carries more credibility with the subscriber than in-app messaging that could be shaped to minimize the perceived impact of the price change. Developers who have tried to replicate the consent sheet inside their own UI — to give subscribers a "second chance" to click through — have reported App Review rejections for creating confusing or duplicative flows. Stay in your lane and handle the outcomes.
The three consent outcomes and how your code must handle each
Once the consent window opens, each existing subscriber ends in one of three states. A complete StoreKit 2 integration must handle all three explicitly.
Outcome 1: Subscriber agrees
The subscriber taps "Agree" in the Apple-managed sheet. On the next billing date, they are charged the new price. The Transaction object for that renewal carries the new amount. No special action is required from your app beyond normal transaction verification — the subscription remains active and the new price is reflected in future receipts and server notifications. Your Transaction.updates listener will receive and should finish() the transaction as it would any renewal.
Outcome 2: Subscriber declines or ignores the consent window
If the subscriber taps "Decline" or simply lets the billing date arrive without acting, Apple cancels the subscription's auto-renewal at the end of the current billing period. Your App Store Server Notifications v2 endpoint receives a DID_CHANGE_RENEWAL_STATUS event with autoRenewStatus: false. The subscriber retains access until the paid period they already hold expires, then lapses.
The most common implementation mistake here is conflating autoRenewStatus: false with immediate expiry. The subscriber still has valid access until expiresDate. An app that immediately downgrades them punishes a subscriber who paid for time they are owed — and Apple has flagged such behavior in app reviews.
This is also the state where a targeted win-back offer becomes relevant. Research from Phiture and broader industry data from RevenueCat suggests that the days immediately following subscription lapse represent a meaningful re-engagement window, particularly if your price increase was accompanied by a genuine product improvement you can reference. For implementation patterns, see iOS subscription winback campaigns: timing, promotional offers, and automation.
Outcome 3: Pending — subscriber has not yet responded
Between the time the consent notification is sent and the billing date, many subscribers will be in a pending state: they have received the notification but have not tapped either option. You can query this via Product.SubscriptionInfo.RenewalInfo; the priceConsentStatus property will be .pending.
This is the most actionable window. Your app can display contextual in-app messaging explaining the change and encouraging agreement — a short banner noting that "your subscription price is changing soon" with a link to the App Store subscription management screen. What you cannot do is build a custom Agree/Decline UI that mimics Apple's sheet, send repeated system-style pushes, or use pressure language that Apple's App Review guidelines would flag as manipulative.
Implementing the StoreKit 2 consent listener
Your app needs a persistent Transaction.updates listener, started at app launch before any UI is shown. The pattern looks like this in Swift:
// Start at app launch — persists for the app's lifetime
Task {
for await verificationResult in Transaction.updates {
guard case .verified(let transaction) = verificationResult else { continue }
// All subscription lifecycle events arrive here, including post-consent renewals
await transaction.finish()
}
}
// To proactively query pending consent status for a loaded product:
let statuses = try await product.subscription?.status ?? []
for status in statuses {
if let renewalInfo = try? status.renewalInfo.payloadValue {
// .pending = subscriber notified but not acted
// .agreed = subscriber consented, next renewal at new price
// Absent = no active price change in progress
let consentState = renewalInfo.priceConsentStatus
}
}
For server-side consent tracking — essential if you manage subscription access from a backend, or if you want to trigger win-back campaigns on lapse — rely on App Store Server Notifications v2 rather than client-side polling. The PRICE_INCREASE notification type signals when a consent flow opens and when its status changes. For the full event taxonomy, see App Store Server Notifications v2: tracking your iOS subscription lifecycle in real time.
Does publishing a price change require a new app review? No. A subscription price change is a product catalog update in App Store Connect, not a binary update. However, if the app version shipping around the same time includes in-app messaging about the price change, that messaging is subject to App Review. Keep the copy factual, match Apple's own neutral tone, and avoid framing that could be read as pressuring subscribers to accept. Review teams have historically been more sensitive here than in other copy contexts.
Testing the consent flow before your live price change
Sandbox and Xcode's StoreKit testing environment offer two complementary approaches:
StoreKit Testing in Xcode (the local .storekit configuration file) lets you simulate the priceConsentStatus state machine entirely offline — no App Store Connect account needed. This is the fastest loop for unit and integration tests of your consent-outcome handling code. You can force-set a product into the .pending state, trigger an .agreed transition, and verify your app responds correctly.
Sandbox in App Store Connect lets you publish a real price change on a sandbox product and observe it through the sandbox subscription controls (Settings → Developer on a test device). You can simulate the agree and decline flows manually. The limitation is that sandbox testers do not receive real emails or system pushes, so you cannot observe the Apple-managed notification UX end-to-end in sandbox. For that, you need a TestFlight build and a real Apple ID on a real device.
To test your Server Notifications endpoint's handling of PRICE_INCREASE events, use the sendTestNotification call in the App Store Server API — it fires a synthetic notification to your registered HTTPS endpoint so you can verify your parsing and persistence logic without waiting for a live price change cycle.
Sources and further reading
- Apple Developer Documentation: StoreKit framework reference
- Apple Developer Documentation: App Store Server Notifications v2
- App Store Connect Help: Managing prices for auto-renewable subscriptions
- RevenueCat Blog: iOS subscription engineering and growth (revenuecat.com/blog)
- Phiture Mobile Growth Stack: App Store subscription retention and growth research
- Apple: Auto-Renewable Subscriptions overview — design guidelines and best practices
Share this post
Ready to put this into practice?
AppsOps is the first App Store ops dashboard — PPP-fair pricing for 175 App Store territories, AI metadata localization in 39 languages, AI screenshot localization for 14 Apple device classes, and one-click App Store Connect API push — all from one dashboard, all for $19/month.
Try AppsOps free — no card →