Designing a paywall as a single screen is the most common way to leave subscription revenue on the table. In reality a paywall is a flow: when you greet the user, how you frame the price, how you structure the trial, and what you show at cancellation — all part of one conversion funnel. In this article I lay out nine concrete decisions about paywall design and subscription conversion, grounded in Apple's and Google Play's own official rules.
💡 Pro Tip: Start designing the paywall not with "which button, which color" but with "at what moment does the user see this screen" — timing comes before copy.
Table of Contents
- Think of the paywall as a flow, not a screen
- Timing: onboarding, value moment, limit moment
- Price presentation and the anchoring effect
- Trial period, win-back, and the cancellation flow
- The boundaries drawn by store rules
- Measurement: conversion, churn, and correct cohorting
- Checklist for the nine decisions
- FAQ
- How can I increase paywall conversion?
- Should I use a hard paywall or a soft paywall?
- How does trial length affect conversion?
- Does the win-back offer appear automatically, or do I need to write code?
- Is the subscription management interface the same on iOS and Android?
- Which metric should I prioritize when A/B testing my paywall?
- Conclusion
- Sources
Think of the paywall as a flow, not a screen
When people think of paywall design, what usually comes to mind is a single "sales screen": a headline, three bullets, a button. But App Store's subscription rules define the paywall as a sign-up flow with its own mandatory components. Per Apple's developer documentation, a subscription sign-up screen must clearly show three things: the name and duration of the subscription (and the content/service offered during the period), the full renewal price shown clearly, prominently, and localized in an available currency, and a way for existing subscribers to sign in and restore purchases. Apple also requires, as a separate rule, that your app and App Store metadata include links to the Terms of Use and privacy policy — this belongs to the app/store page, not the sign-up screen itself.
These three items aren't a "checklist" — they're the skeleton of the flow. When the user lands on the paywall, they should first see what they're buying, then how much they'll pay, then the path back (restore) — this ordering reduces confusion and, as a result, drop-off.
Timing: onboarding, value moment, limit moment
When you show the paywall is the most important decision in the flow. In Apple's own terminology, one option is a "metered paywall": "A metered paywall allows access to a finite amount of content for a specified duration before needing to make a purchase."
You can break this into three timing points:
- Onboarding moment: The paywall shown the moment the user creates an account. The upside is simplicity; the downside is that the user hasn't yet seen the product's value.
- Value moment: Shown after the user has experienced the product's core benefit once (e.g., after generating the first report, completing the first project).
- Limit moment: Following metered-paywall logic, shown when the free usage quota runs out — the user has already used the product and now has to pay to continue.
None of the three violate App Store rules; the choice depends on how long the product takes to reach its "value moment." If that moment arrives in seconds, position the paywall close to onboarding; if it takes longer, the limit moment creates less friction because the user has already gotten value before seeing the payment request.
My own simple test: if the user can see the product's core benefit within three interactions (an instant "before/after" in a photo editing app), I place the paywall right after that moment, value-moment style. If the benefit only emerges after several days (a "7-day streak" in a habit tracker), an early hard paywall loses the user before they get there — there, a limit moment or a longer metered window fits better. It isn't a formula, it's a read of the product's own value curve.
Price presentation and the anchoring effect
How you display the price isn't an optional design detail on the App Store — it's a rule. Per Apple's documentation: "the amount that will be billed must be the most prominent pricing element in the layout" — e.g., the annual total must outrank the weekly or monthly equivalent, which has to sit in a subordinate position.
To me, this overlaps with the classic anchoring effect: the user sees the large number first, then may perceive the weekly/monthly equivalent as "actually small" — that's my own interpretation; Apple's rule doesn't give a rationale for it. The rule itself is mandatory: you design around it, it isn't a matter of preference.
Apple also distinguishes three discount types: "Free trial... Pay as you go... Pay up front." These three create different risk perceptions:
Discount type | When billing starts | User perception |
|---|---|---|
Free trial | After the trial ends | Lowest friction, highest "forgot and got billed" risk |
Pay as you go | Day one, at a discounted price | Medium friction, low sense of commitment |
Pay up front | Day one, paid in full | High friction, strongest intent signal |
Which discount type you make the primary CTA on the paywall changes both the conversion rate and the first-month cancellation rate — before choosing one, you need to decide which metric you're optimizing for: sign-up count, or number of paying users.
My own preference, when showing multiple plans, is to make the annual plan the default selection and leave monthly as a secondary choice — this also aligns with Apple's anchoring rule, since the annual total is already required to be most prominent. But I don't hide the weekly/monthly equivalent; I just place it second in the visual hierarchy, so the user still sees both numbers, just in a different order.
Trial period, win-back, and the cancellation flow
When a subscription ends due to a cancellation or billing issue, the count of paid service days stops — in Apple's words: "If a subscription expires due to a cancellation or billing issue, the days of paid service stop accumulating." If it renews within 60 days, the duration continues from where it left off; this means you need to treat a user who returns in that window not as a brand-new subscriber but as one continuing from where they stopped.
Apple groups offer types under four headings along the acquisition/retention/win-back axis: Introductory offers, Promotional offers, Win-back offers, Offer codes. On win-back specifically, the developer's job isn't to write code: "A win-back offer sheet automatically appears to eligible customers within your app or game, with no additional work required." You only define the group and the offer in App Store Connect.
On cancellation, leaving control inside the app is a practice Apple recommends; I prefer it too since it simplifies the experience. With showManageSubscriptions(in:), the user reaches the management screen without leaving the app — "You can use the showManageSubscriptions(in:) method to let them manage their subscription within your app."
1// iOS 15+: show the in-app subscription management screen2import StoreKit3import UIKit4 5func openSubscriptionManagement(in windowScene: UIWindowScene) async {6 do {7 try await AppStore.showManageSubscriptions(in: windowScene)8 } catch {9 // User dismissed the screen or a system error occurred — swallow silently,10 // optionally fall back to a separate "Settings > Subscriptions" link.11 }12}On the Google Play side, the counterpart isn't an SDK method but a direct deep link: play.google.com/store/account/subscriptions — for product-level routing, the parameters ?sku=your-sub-product-id&package=your-app-package are appended. This is a point of divergence from Apple's in-app management screen: on Android you route the user to the Play Store, there's no management surface that stays inside the app.
1// Android: deep link to the subscription management screen2fun openSubscriptionManagement(context: Context, sku: String, packageName: String) {3 val uri = Uri.parse(4 "https://play.google.com/store/account/subscriptions" +5 "?sku=$sku&package=$packageName"6 )7 context.startActivity(Intent(Intent.ACTION_VIEW, uri))8}The boundaries drawn by store rules
Paywall design isn't just a visual exercise — it's intertwined with the store's revenue model. On Apple's side, commission changes with subscription age: "During a subscriber's first year of service, you receive 70%... After a subscriber accumulates one year of paid service, your net revenue increases to 85%." The Small Business Program has no such threshold — "you receive 85% of the subscription price at each billing cycle... regardless of whether or not the subscription has accumulated one year of paid service." The threshold is identical for monthly and annual plans; the difference isn't speed — in my view, a monthly subscriber is more likely to churn before reaching that point. Free trials and renewal extensions don't count toward it: "Free trials and renewal extensions are excluded from days of paid service."
Apple also offers a flexibility called "Renewal Date Extension": you can extend the renewal date up to twice per calendar year, each up to 90 days — but these days don't count toward the 85% threshold: "move the renewal date...twice per calendar year, each up to 90 days...won't count toward the one year of paid service."
On Google Play, the constraint affecting the paywall is the Billing Library (PBL) version requirement. Starting August 31, 2026, new apps and updates must use Billing Library v8 or later; the extension window for stragglers closes November 1, 2026. Per Google's official deprecation table:
PBL version | New app / update deadline | Extension ends |
|---|---|---|
v5 | August 31, 2024 | November 1, 2024 |
v6 | August 31, 2025 | November 1, 2025 |
v7 | August 31, 2026 | November 1, 2026 |
v8 | August 31, 2027 | November 1, 2027 |
v9 | August 31, 2028 | November 1, 2028 |
Starting November 1, 2026, the minimum floor will be v8; once v7's extension window closes on that date, it will no longer be accepted. In practice the library itself is already well ahead: Play Billing Library 9.0.0 was released on May 19, 2026, and 9.1.0, with Billing Choice APIs, followed on June 18, 2026. So if you're setting up your paywall from scratch, it's more accurate to start directly with 9.x and treat v8 not as "minimum compliance" but as "an already-outdated floor."
Another detail on the Play side affecting paywall design: prepaid plans don't auto-renew. "Prepaid plans do not automatically renew upon expiration." There's also a separate rule for the top-up flow: "Prepaid plan top-ups always use the CHARGE_FULL_PRICE replacement mode, and you don't need to set this mode explicitly." So if you're offering a prepaid plan, you need to design the top-up (balance recharge) flow as part of the paywall before the period expires — the system doesn't do this for you automatically. Prepaid confirmation timing also depends on the plan length: plans of a week or longer must be confirmed within 3 days, and plans shorter than a week within half the plan duration.
Measurement: conversion, churn, and correct cohorting
The biggest mistake when measuring a paywall is looking at a single "conversion rate" number. Apple and Google don't publish a concrete numerical benchmark for conversion/LTV — Apple's advice is qualitative: test paywall variants and measure the effect. So focus on the measurement setup instead.
On Apple's side, the "Get All Subscription Statuses" API lets you determine a subscription's status in a single call: "determine in one simple check whether a subscription is active, expired, in billing retry, or in grace period." These four states are critical for correctly cohorting the post-paywall funnel — if you lump an "active subscriber" together with a "subscriber pending in billing retry," you'll compute the conversion rate incorrectly.
On the Google Play side, the counterpart is subscriptionsv2.get — this endpoint is the "source of truth" for status: "considered the source of truth for subscription management." The purchase token remains valid until 60 days after the subscription ends — this is the window during which you can query status via the Play Developer API (don't confuse this with Apple's 60-day paid-service-continuation rule).
1# Google Play: query subscription status from the source-of-truth endpoint2curl -s -X GET \3 "https://androidpublisher.googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/purchases/subscriptionsv2/tokens/$PURCHASE_TOKEN" \4 -H "Authorization: Bearer $ACCESS_TOKEN"When a new purchase comes in, the acknowledgementState field arrives as ACKNOWLEDGEMENT_STATE_PENDING; this pending-acknowledgement state means that in your conversion measurement, you need to keep purchases that are "technically bought but not yet acknowledged" in a separate bucket — otherwise you'll overstate the last step of the funnel.
Also, for an installment subscription, when the user requests cancellation during a period where committed payments are still outstanding, the SUBSCRIPTION_CANCELLATION_SCHEDULED notification is sent when the cancellation request is received. Treating "cancellation request" and "actual end of period" as the same event scatters your churn date into the wrong cohorts.
Checklist for the nine decisions
I'm collapsing the findings above into a single actionable list — each decision follows from the previous section, in the order you'll encounter them while designing:
- Flow skeleton: The sign-up screen should always show name+duration, full renewal price, and a restore link; ToU/Privacy links should be present in your app and in App Store metadata.
- Timing choice: Based on how long the value moment takes, deliberately pick among onboarding/value-moment/limit-moment (metered) — don't just copy a default.
- Anchor price: Make the amount to be billed (e.g., the annual total) the most prominent element in the layout; show the weekly/monthly equivalent in a subordinate position.
- Discount type clarity: Decide which of free trial / pay as you go / pay up front is the primary CTA based on which metric you're optimizing.
- Win-back design: The system automatically shows an offer sheet to eligible users — design the experience around that; a user who returns within 60 days after a cancellation/billing issue continues their paid service from where they left off.
- In-app management:
showManageSubscriptions(in:)on iOS, a Play Store deep link on Android — reflect the platform difference in your interface. - Commission awareness: Factor the 70%→85% threshold, or the Small Business Program, into your pricing strategy.
- PBL version floor: Know v8 as the minimum floor (the v7 window closes November 1, 2026), but don't stay behind 9.x in practice; design the prepaid top-up flow separately.
- Cohort accuracy: Measure active/expired/billing-retry/grace-period states, and pending-acknowledgement purchases, in separate buckets.
GOLDEN TIP
The most valuable insight in this article
This tip holds the article's most important takeaway.
Easter Egg
You found a hidden gem!
There's a hidden detail in this section. Want to uncover it?
Reader Reward
I've distilled the nine decisions in this article into a single pre-launch checklist; check off the items below one by one before taking your paywall live.
FAQ
How can I increase paywall conversion?
Apple and Google don't publish a universal numerical target for conversion; Apple's own recommendation is to test paywall variants and measure them. In practice, an increase comes not from a single "magic variable" but from the whole flow: correct timing, rule-compliant price anchoring, and the right discount-type choice working together. Test these three separately and measure what works for your own user base.
Should I use a hard paywall or a soft paywall?
Apple's documentation defines the concept of a "metered paywall" — requesting a purchase after a limited duration/amount of access. The hard/soft distinction isn't an official store term, it's a product strategy decision: a hard paywall routes the user to payment before they've seen any value, a soft/metered paywall offers a limited experience first. Which one is right depends on how quickly your product reaches its value moment.
How does trial length affect conversion?
Apple's official documentation doesn't publish a numerical relationship between trial length and conversion; it only defines the "free trial" discount type alongside "pay as you go" and "pay up front." If you want to measure the effect of trial length, run an A/B test on your own user base — there's no single universal "best trial length."
Does the win-back offer appear automatically, or do I need to write code?
On the App Store, win-back offers are automatic: an eligible user is shown an offer sheet with no additional development work. Your job is to define the group and the offer in App Store Connect; the system manages the presentation flow.
Is the subscription management interface the same on iOS and Android?
No. On iOS, you can open an in-app management screen with showManageSubscriptions(in:) that keeps the user inside your app. On Android, the counterpart isn't an SDK screen but a deep link to the Play Store (play.google.com/store/account/subscriptions) — the user leaves the app and is routed to the Play Store.
Which metric should I prioritize when A/B testing my paywall?
This is a product strategy decision; Apple only recommends testing and measuring, it doesn't tell you which metric to prioritize. A practical approach: pick a single primary metric first (e.g., number of paying users, first-30-day revenue, or net cancellation rate), and track secondary metrics (like trial-start rate) only for context. Otherwise every variant will look "good on one metric, bad on another" and you won't be able to decide.
Conclusion
Paywall design is the sum of nine decisions: flow skeleton, timing, price anchoring, discount type, the win-back window, the platform-specific management interface, commission awareness, the store's version floor, and correct cohorting. None of these decisions are isolated — changing one affects another (e.g., your discount-type choice changes the primary metric you measure).
If you want to set up a modern IAP flow with StoreKit 2 on the technical side, see Modern In-App Purchase with StoreKit 2; for a production-grade IAP architecture with async/await, see the StoreKit 2 Production Guide. I covered how to set up offer codes, family sharing, and win-back offers in App Store Connect in App Store Connect Subscriptions. On the Android side, you can check the Google Play Billing Library v7 guide, which now describes an older version floor (starting August 31, 2026 the minimum floor is v8; this article covers that transition period), or the RevenueCat Cross-Platform Subscription article for managing both iOS and Android with a single SDK. On the revenue side, I Made $1M: Real Strategy and Numbers is a case study with real numbers that complements this article.
Sources
- Apple Developer — App Store Subscriptions — official definitions of sign-up screen rules, commission rates, offer types, win-back, and Renewal Date Extension.
- Android Developers — Play Billing Deprecation FAQ — PBL version requirement timeline (v6/v7/v8/v9 deadline table).
- Android Developers — Play Billing Release Notes — PBL 8.x/9.x release dates and new APIs.
- Android Developers — Google Play Billing Subscriptions — prepaid plan behavior, installment subscriptions, management deep link, cancellation notifications.
- Android Developers — Subscriptions Lifecycle —
subscriptionsv2.getsource-of-truth definition and purchase token validity period.
Tags
iOS Development News
Weekly Swift tips, SwiftUI tricks and iOS best practices. No spam, only valuable content.
Your subscription starts when you open the link in the confirmation email and press “Confirm my subscription”. The newsletter keeps open/click statistics; you can unsubscribe anytime with one click. Privacy
