Plan picker design: a SaaS pricing page that helps merchants choose
How to design an in-product plan picker: which plan to recommend, anchoring, what merchants keep and lose, usage vs seat tiers, and the upgrade dialog.
In short: The plan picker inside a product knows who is looking at it, which a public pricing page never does. Use that. Recommend the cheapest plan that fits the merchant's current usage with room to grow, say why in one line, show only what changes for them between plans, and make the upgrade dialog and the downgrade screen both answer the same question: what happens to my work. Anchor on the merchant's own numbers, not on a decoy tier.
Which plan should the picker recommend, and why?
A public pricing page recommends the middle tier because it has to pick one for everybody. An in-product plan picker does not have that excuse. It knows the merchant's order volume, how many affiliates or creators they have, which features they have opened, and how close they are to a limit.
So recommend the cheapest plan that fits their current usage with headroom, and say why in one line next to the badge:
- "Recommended for you: Growth. You have 34 active affiliates and the Starter plan covers 25."
- "Recommended for you: Starter. You are sending about 60 creator invites a month and Starter covers 100."
The second example matters as much as the first. Recommending a plan below the one the merchant assumed they needed builds the trust you spend later when you ask them to go up. It also produces fewer downgrades, which is the half of net revenue retention most teams ignore.
Two rules for the recommendation logic:
- It must be explainable in one sentence using numbers the merchant can see elsewhere in the app. If you cannot write that sentence, the logic is wrong.
- It must never recommend a plan the merchant is already over the limits of. "Recommended" and "you will hit the cap in a week" cannot both be true.
When the merchant has no usage yet, say so and recommend the entry plan. "Most stores start on Starter and move up once they have more than 25 affiliates" is honest and gives them a reason to come back.
How should anchoring work without tricking anyone?
Nielsen Norman Group describes the anchoring principle as the tendency to rely on a single piece of information when making a judgement, and gives the example of showing an original price next to a discounted price so the original anchors the perception of value. Pricing pages use this constantly. The expensive tier on the left exists so the middle one looks reasonable.
I do not design plan pickers that way, for a practical reason. Merchants compare apps, read reviews and talk to each other. A decoy tier that nobody buys is noticed, and it reads as a trick. There are three anchors that work and are honest:
- The merchant's own result. "Your affiliates drove $12,400 in sales last month" above a $79 plan does the anchoring on its own.
- The annual price. Shopify's App Pricing documentation says merchants can always toggle between monthly and yearly prices on the hosted plan page, and you choose the default. Default to yearly for merchants with a track record, monthly for new installs.
- The current plan. Show it in place, marked "your plan", so every other option is read relative to something real.
If you show a struck-through price, it has to be a price someone would actually have paid. Fake strikethroughs are the pricing equivalent of a fake countdown timer, and Shopify's Built for Shopify requirements already reject visible timers and pressure language.
What should the merchant see about what they keep and lose?
Not a 40-row feature matrix. Nielsen Norman Group's guidance on comparison tables is blunt about this: the table should include attributes users actually care about, the biggest problem with most comparison tables is content rather than design, and if information is not complete for every compared option it might as well not be there. It also notes that on mobile you are unlikely to show more than two items at a time, which describes most Shopify admin sessions.
For an in-product picker the right table is "what changes for you". Compare the merchant's current plan against the one they are looking at, using their own numbers:
| Your plan (Starter) | Growth | |
|---|---|---|
| Active affiliates | 34 of 25 (over limit) | Unlimited |
| Commission tiers | 1 | Up to 5 |
| Automations | Not included | Included |
| Payout schedule | Monthly | Weekly or monthly |
| Price | $29/month | $79/month |
Five rows. The rest of the matrix lives behind a "compare all plans" link for the merchant who wants it.
Then the two sentences that most pickers leave out. What you keep: "All your affiliates, links and payout history come with you." What you lose if you go down: "Affiliates 26 to 34 will be paused, not deleted." The first sentence is why merchants upgrade without a support ticket. The second is why they downgrade instead of uninstalling.
Shopify's Built for Shopify requirements also apply here. Plan-gated features must be disabled visually and functionally and clearly indicated, and it is a rejection reason when it is not obvious which tier unlocks a specific feature. A greyed-out automation card with "Growth plan" on it is the cheapest piece of pricing page you will ever build.
How should usage-based and seat-based tiers be shown?
Differently, because the merchant is asking a different question.
With seat-based tiers the question is "how many of us need access", and the picker should show seats in use against seats included, with the names. "3 of 3 seats used: Priya, Tom, Jordan" tells the merchant why the next person could not log in.
With usage-based tiers the question is "where am I on the scale", and the picker should show the merchant's current usage as a position on the tier ladder, not just a number. Shopify App Pricing supports fixed, graduated and volume pricing through usage meters, with up to five active meters per plan and up to six pricing tiers per meter, and it notes that usage caps are not currently supported. That last point matters for design. If there is no hard cap, the picker has to make the overage rule obvious, because the merchant cannot rely on the app stopping.
The usage unit should be something the merchant is pleased to see go up. Orders tracked, affiliate revenue, creator videos posted. A tier ladder based on a unit the merchant resents (API calls, "credits") makes every upgrade feel like a penalty for success. I go deeper on choosing the unit in Shopify app pricing plans.
What should the upgrade dialog say when a limit is hit?
Four things, in this order:
- What just happened, in the merchant's terms. "Your 26th affiliate signed up. Starter covers 25."
- What is still working. "Your existing 25 affiliates are tracking and paying out as normal."
- What the next plan costs and what it changes, with the recommendation logic from above.
- What happens if they do nothing. "New affiliates will wait in a queue until you upgrade or remove one."
The dialog should not block the whole app. The merchant may have come in to approve a payout, and locking the screen until they decide on a plan turns a sales moment into a hostage situation. Put the dialog on the action that hit the limit, let them close it, and leave a card on the dashboard. The timing of this prompt, and why it should fire before the limit rather than at it, is covered in in-app upsell design.
What should a downgrade show about work in progress?
Everything that will change, by name, before the merchant confirms.
A downgrade from Growth to Starter in an affiliate app might pause nine affiliates, stop two automations, and move payouts from weekly to monthly. The screen should list those nine affiliates, those two automations, and that payout change. If the merchant gets to choose which nine are paused, let them choose. If the change takes effect at the end of the billing cycle, which is how Shopify App Pricing schedules a downgrade to a free plan, say the date.
For a creator outreach tool the list is different but the shape is the same. Which open conversations will lose automated follow-ups. Which pending sample requests are affected. Whether message history is kept.
When I ran customer success at Social Snowball I sat in the support queue and read the tickets that bad design creates. A plan change screen that does not answer "what happens to my work" is one of the designs that does. The downgrade screen is also where you learn why the merchant is leaving the tier, which is why it belongs next to the cancellation flow in your design system, with the same honesty and none of the tricks.
Where to start
- Write the one-sentence recommendation rule for your picker, using numbers the merchant can already see in the app. If you cannot, fix the data before the design.
- Replace the full feature matrix with a five-row "what changes for you" comparison between the merchant's current plan and the one they are viewing. Link to the full matrix.
- Add the two sentences: what you keep, and what pauses if you go down.
- Rewrite the limit-hit dialog so it names the event, confirms what still works, and says what happens if the merchant does nothing.
- Build the downgrade screen to list the affected affiliates, automations or conversations by name, with the effective date.
Frequently asked questions
How many pricing plans should a SaaS app show?
Three or four visible plans is enough for most e-commerce apps, and Nielsen Norman Group's guidance on comparison tables suggests adding filters once you compare more than five items. Shopify App Pricing allows up to eight public plans, but a picker that shows eight at once pushes the comparison work onto the merchant.
Should a plan picker show a recommended plan?
Yes, but the recommendation should come from the merchant's own usage, not from a fixed "most popular" badge. Recommend the cheapest plan that fits their current numbers with headroom, and state the reason next to the badge so the merchant can check it.
What should an upgrade prompt say when a user hits a plan limit?
Name the event in the merchant's terms, confirm what still works, show the next plan's price and what it changes, and say what happens if they do nothing. Do not block the whole app while they decide, and never use a countdown timer.
What should a downgrade flow show?
The exact affiliates, automations, conversations or other work that will be paused, by name, plus the effective date and a clear statement of what is kept. Merchants who can see what they lose tend to downgrade rather than uninstall, and the reasons they give on that screen are useful product feedback.