๐ผ Pricing Decision โ Retire Vendor Pass + All-Access (May 2026)¶
Decision date: 8 May 2026 Decided by: Sush Implemented by: Copilot CLI session
7902c86dStatus: โ Live Reversible: Yes (full rollback path documented below)
TL;DR¶
Guided's pricing went from three tiers to one. Going forward, the only product on sale is the $9 single-cert pass with 1 year of access. The $59 vendor pass and $149 all-access pass are retired.
| Was | Now |
|---|---|
| $9 single cert ยท $59 vendor pass ยท $149 all-access | $9 single cert |
Why¶
1. Zero historical sales of the multi-cert tiers¶
Across the entire payments history (verified via Stripe API on 8 May 2026), the count of completed checkout sessions where metadata.productType !== 'cert' was 0.
Every dollar Guided has ever earned came from the $9 single cert. The vendor pass and all-access existed only as a hypothesis โ and the data answered the question.
2. The story is cleaner with one number¶
The brand promise is "$9, not $79." That sentence works on YouTube, on the homepage hero, in FAQ answers, in tweet replies. The moment you say "or $59 for a vendor pass, or $149 for everything," the single sharp number gets blurry.
3. No upsell pressure to manage¶
A multi-tier product needs upsell flows: "buy one cert, then prompt them to upgrade to vendor pass". That's a UX surface, an A/B test, an email sequence, and an analytics dashboard we never have to build.
4. Lower cognitive load for the buyer¶
The fastest path from search โ study guide โ purchase is a single, obvious price. Three tiers means decision fatigue and "I'll come back later" โ which is the death of a $9 impulse buy.
5. Operational simplicity¶
One product means:
- One Stripe price to maintain
- One success URL
- One licence-key shape to debug
- No "did the vendor pass cover this?" support tickets
- No "I bought all-access for $149, can I get a refund and downgrade?" edge cases
The platform is built and run by one person on top of a day job. Every removed surface is bandwidth back.
What changed¶
Stripe (live mode)¶
| Object | ID | New state |
|---|---|---|
| Price (Vendor Pass, $59) | price_1TPtIAIXZo4phfVPI5rF0x4T |
active: false |
| Price (All-Access, $149) | price_1TPtIBIXZo4phfVPvcv01IhT |
active: false |
| Product (Vendor Pass) | prod_UOgf0LkyhFTAZR |
active: false |
| Product (All-Access) | prod_UOgf19snROsc4Y |
active: false |
| Price (Single Cert, $9) | price_1TRNTjIXZo4phfVPCLjvHSGH |
unchanged โ |
| Product (Single Cert) | prod_UOgfX7gOBynDZq |
unchanged โ |
Archived in Stripe is not deleted โ both products and prices remain in the dashboard, can be inspected, and can be reactivated with a single API call. Existing licences (none today, but the pattern is safe) keep working forever because licence verification doesn't touch the price object.
Code (commit e99fb5d on main)¶
| File | Change |
|---|---|
functions/guided/api/checkout.ts |
productType validation locked to 'cert'. Vendor and all return 400 Invalid product type โ only single cert purchases are supported. |
functions/lib/utils.ts |
STRIPE_PRICES reduced to a single key (cert). vendor and all entries removed. |
src/pages/help/index.astro |
3-card pricing grid replaced with single $9 card. |
src/pages/[vendor]/index.astro |
Three FAQ entries rewritten to drop $59/$149 references. The "How does the {vendor} vendor pass work?" FAQ removed entirely. |
src/pages/[slug]/index.astro |
"How does purchasing work?" FAQ rewritten to remove the optional $59 / $149 upsell sentence. |
.github/copilot-instructions.md |
SLA banner updated from $9/cert, $59/vendor, $149/all-access to $9/cert. Footnote points at this doc. |
Code that intentionally was NOT changed¶
The following remain unchanged on purpose, as a defensive read-path for any orphan legacy session metadata that ever surfaces (and to make rollback trivial):
| File | Why it stays |
|---|---|
functions/guided/api/verify.ts |
Type union 'cert' \| 'vendor' \| 'all' kept. Only reads metadata. |
functions/guided/api/webhook.ts |
Same. |
src/lib/access.ts |
hasAccess() still checks vendor + all-access localStorage keys defensively. Cost-free. |
src/components/interactive/PracticeQuiz.tsx |
Already calls checkout with productType: 'cert' only. No change needed. |
src/pages/index.astro |
Already on-message ($9 vs $79). No vendor/all references. (Was also being touched by another session at the time of this change โ left alone to avoid conflict.) |
Documentation¶
| Doc | Change |
|---|---|
pricing-strategy.md |
Overhauled to single-tier model. Retired tiers logged in a historical-record table. |
stripe-payments.md |
Vendor and all-access sections marked DEPRECATED with date and pointer to this doc. Active price table reduced to one row. |
cc-dashboard.md |
"Stripe products" line updated to reflect single product. |
SLA verification¶
The change touches functions/guided/api/checkout.ts and the .github/copilot-instructions.md SLA banner โ both inside the SLA scope. The protocol was followed.
| Step | Result |
|---|---|
| Pre-change smoke test (3 curls) | โ All pass |
npm run build |
โ 2,284 pages, 92s, no errors |
node test-guided-qa.cjs |
21/26 pass; the 5 failures were confirmed pre-existing (verified by stashing my changes and re-running โ same 5 failures on baseline). Both critical checkout assertions PASS. |
git push (explicit paths only โ left another session's index.astro and planets.json alone) |
โ Cloudflare Pages auto-deployed |
| Post-deploy smoke test (3 curls) | โ All pass |
Post-deploy negative test (productType: 'vendor' + 'all') |
โ
Both rejected with Invalid product type โ only single cert purchases are supported |
| Stripe archive (4 API calls) | โ
All 4 objects active: false |
| Final live product list | โ
Only Guided โ Single Cert Pass remains active |
Rollback path¶
If this decision is ever reversed:
1. Restore Stripe products + prices¶
KEY=$(cat ~/.copilot/secrets/stripe-live-secret-key)
curl -s -u "$KEY:" -X POST https://api.stripe.com/v1/prices/price_1TPtIAIXZo4phfVPI5rF0x4T -d active=true
curl -s -u "$KEY:" -X POST https://api.stripe.com/v1/prices/price_1TPtIBIXZo4phfVPvcv01IhT -d active=true
curl -s -u "$KEY:" -X POST https://api.stripe.com/v1/products/prod_UOgf0LkyhFTAZR -d active=true
curl -s -u "$KEY:" -X POST https://api.stripe.com/v1/products/prod_UOgf19snROsc4Y -d active=true
2. Revert code¶
That single revert restores all six file changes (checkout.ts validation, STRIPE_PRICES map, help page, vendor FAQ, slug FAQ, and the SLA banner). The defensive verify/webhook/access code never changed, so revived vendor/all flows just work.
3. Re-publish docs¶
Total time to fully restore the three-tier model: under 5 minutes.
What we're watching for¶
If we see any of these signals in the next 6 months, we revisit:
- Repeat purchases from the same email. If learners are buying 3+ certs each, the bundle math gets compelling and a vendor pass returns as an explicit option.
- Bulk / team enquiries. A separate "teams" SKU at a different price point (not $9 ร N) would be cleaner than reviving the all-access pass.
- Stripe data points showing customers stalling at price comparison. Watch the
cs_live_*abandonment rate.
If none of those happen, the simpler model wins on its own.
Voice note¶
This decision is on-brand. Sush's brand says "for people like us" โ meaning: the cert prep buyer who's tired of being upsold, asked for an email at every step, and locked into vendor portals. Three tiers contradicted that. One $9 number doesn't.