Extend Pricing
Pricing in Fast Unicorn has two layers:
- marketing presentation
- billing logic
This guide explains how to update pricing safely so your marketing copy, Stripe price IDs, and billing behavior stay aligned instead of drifting apart.
Before extending pricing
Review Configure Stripe first. Pricing changes are usually safe only when the marketing layer and the Stripe billing layer are updated together.
What this guide covers
Marketing pricing
How pricing cards, copy, plan names, and CTA labels are presented on the public site.
Stripe tier mapping
How internal billing tiers stay connected to the real Stripe price IDs defined in the environment.
Tier expansion
What extra code changes are required when adding a brand-new plan instead of only editing existing pricing.
Main files and folders
- content/landing/*.json: Public pricing content and plan presentation (in the
pricingsection of each locale file). - src/content/schemas.ts: Zod schemas that validate pricing content structure.
- src/server/services/billing/webhook-sync.ts: Billing tier mapping from Stripe webhook events.
- src/env.js: Environment schema for Stripe price IDs.
- src/server/services/billing/checkout.ts: Checkout session creation tied to pricing logic.
Recommended sequence
Use this order when changing pricing.
Update the public pricing presentation
Start with the marketing config so the visible plan names, descriptions, and CTA labels reflect the pricing you want to sell.
Align the Stripe price IDs
Make sure the billing layer points to the actual Stripe prices that match the public plans you just updated.
Review tier mapping
Confirm the tier mapping still applies to the right plans and checkout modes.
Test checkout and synchronization
Run through the billing flow and verify webhook synchronization before considering the new pricing complete.
Marketing pricing
The landing page pricing cards are defined in content/landing/*.json in the pricing section of each locale file.
This is where you edit:
- plan names
- descriptions
- displayed prices
- feature lists
- CTA labels
The structure is validated by Zod schemas in src/content/schemas.ts. This layer controls what users see before they enter a billing flow.
Stripe pricing
The actual billing tier mapping is handled in the webhook handler src/server/services/billing/webhook-sync.ts and depends on Stripe price IDs defined in src/env.js.
This layer controls what users are actually charged and how the app interprets their billing state.
Keep both layers aligned
If you change plan names, amounts, or tiers:
- update the pricing section in
content/landing/*.json - update the Stripe price IDs in
src/env.js - verify the tier mapping in
src/server/services/billing/webhook-sync.ts - test checkout and webhook sync
Do not update only the marketing layer
If the landing page and the Stripe tier mapping stop matching, users can see one thing and be charged for another. Always update both sides together.
If you add a new tier
Adding a completely new tier requires code changes beyond copy updates.
You will need to update:
- marketing plan definitions
- env schema
- price-to-tier mapping
- tier-to-price mapping
- any UI that assumes the current tier set
- any dashboard or entitlement logic tied to subscription values
Small change vs structural change
Editing copy or swapping existing price IDs is usually a lightweight pricing update. Adding a brand-new tier is a structural billing change and should be treated like a feature expansion.