Billing architecture
Jun 21, 2026 (4 weeks ago)11 views
This post walks through the billing system behind my first tech product — scheduled to launch within the next two weeks as of June 21, 2026. If you landed here, you will get the full picture: how payments are automated inside the software, how credits map to real AI costs, and how the pricing model stays profitable without charging outrageous subscription fees.
Table of contents
4. Billing by User ID vs. Session ID
5. The profitability principle
#Introduction
Most AI products pick one of two paths: a flat monthly subscription, or a large upfront payment that covers a long period. Neither felt right for what I was building.
I wanted something closer to buying credits — pay $30, get $30 worth of usage — while still guaranteeing margin on every dollar spent. That sounds contradictory at first: how do you stay profitable if users can spend 100% of what they paid?
The answer is the same mechanism used by Anthropic, OpenAI, Manus, and most serious AI platforms: tokenization. Every action has a measurable cost. Every cost gets a price. The gap between the two is where the business lives.
This post documents that system end to end.
#Current architecture
Below is the current payment stack — Stripe only, with no pricing logic visible on the surface. The calculation layer lives entirely behind Cloud Functions.
Stripe checkout flow — current billing architecture
What this diagram shows
The flow is intentionally linear:
- Every user starts on Free. They get access to the platform's core actions — navigation, settings, non-AI workflows — but no AI consumption.
- Paid tiers unlock AI, but activation is not a frontend toggle. A successful Stripe payment triggers a Cloud Function that verifies the charge server-side before any feature flag flips.
- Failure is the default on error. If payment fails or a subscription lapses, the backend rolls the account back to Free automatically.
The webhook
A webhook is how Stripe tells your backend that a payment actually happened. The user pays on Stripe's page — your app doesn't decide on its own whether access should unlock. Stripe sends a signed notification to a Cloud Function, which verifies it and updates the account.
User clicks "Upgrade"
↓
Stripe Checkout session created (server)
↓
User completes payment on Stripe
↓
Stripe webhook → Cloud Function
↓
Function verifies signature + payment status
↓
Firestore / backend record updated (tier + credits)
↓
Client receives updated entitlements on next auth refresh
If the payment succeeds, the backend upgrades the tier and loads credits. If it fails or a subscription lapses, the account rolls back to Free. The frontend never grants paid access on its own — the webhook is the source of truth.
#Pricing calculation
The credit model
Instead of "unlimited AI for $30/month," the offer is:
Pay $30 → receive $30 in usage credits.
Credits are not arbitrary points. They map directly to token consumption across the models integrated into the product.
How AI is metered
Every AI call consumes tokens — small chunks of text the model reads (input) and writes (output). Providers bill per million tokens, and each model has its own rate. A single flat price across all models would either overcharge users on cheap models or lose money on expensive ones.
This product routes requests across 6 models. Below are their current provider prices on the market (per 1M tokens):
| Provider | Model | Input ($/1M) | Output ($/1M) |
|---|---|---|---|
| OpenAI | GPT-4.1 nano | $0.10 | $0.40 |
| OpenAI | GPT-4o mini | $0.15 | $0.60 |
| xAI | Grok 3 Mini | $0.30 | $0.50 |
| xAI | Grok 4.1 | $0.20 | $0.50 |
| Anthropic | Claude Opus 4.7 | $5.00 | $25.00 |
| Anthropic | Claude Opus 4.8 | $5.00 | $25.00 |
The spread is wide: GPT-4.1 nano costs $0.10 per million input tokens. Claude Opus 4.8 costs $5.00 for the same amount — 50× more. That is why billing must be per-model, not flat.
The formula
In-app price = Provider cost × 1.25 (25% markup)
The 25% margin applies on top of the real provider cost for each specific model at call time.
Exact calculation example
Take a typical request: 100,000 input tokens + 25,000 output tokens (a ~4:1 ratio, common for a chat reply or short generation).
| Model | Provider cost | In-app charge (× 1.25) | Your margin |
|---|---|---|---|
| GPT-4.1 nano | $0.020 | $0.025 | $0.005 |
| GPT-4o mini | $0.030 | $0.038 | $0.008 |
| Grok 3 Mini | $0.043 | $0.053 | $0.011 |
| Grok 4.1 | $0.033 | $0.041 | $0.008 |
| Claude Opus 4.7 | $1.125 | $1.406 | $0.281 |
| Claude Opus 4.8 | $1.125 | $1.406 | $0.281 |
How each row is calculated (using GPT-4.1 nano as an example):
Input: (100,000 ÷ 1,000,000) × $0.10 = $0.010
Output: (25,000 ÷ 1,000,000) × $0.40 = $0.010
Provider cost = $0.020
In-app charge: $0.020 × 1.25 = $0.025
Your margin: $0.020 × 0.25 = $0.005
Same logic for Claude Opus 4.8:
Input: (100,000 ÷ 1,000,000) × $5.00 = $0.500
Output: (25,000 ÷ 1,000,000) × $25.00 = $0.625
Provider cost = $1.125
In-app charge: $1.125 × 1.25 = $1.406
Your margin: $1.125 × 0.25 = $0.281
With a $30 credit wallet, the number of similar calls a user can make:
| Model | Calls before $30 runs out | Cost to you (provider) | Your revenue (margin) |
|---|---|---|---|
| GPT-4.1 nano | ~1,200 | $24.00 | $6.00 |
| GPT-4o mini | ~800 | $24.00 | $6.00 |
| Grok 3 Mini | ~565 | $24.00 | $6.00 |
| Grok 4.1 | ~738 | $24.00 | $6.00 |
| Claude Opus 4.7 | ~21 | $24.00 | $6.00 |
| Claude Opus 4.8 | ~21 | $24.00 | $6.00 |
At full spend, margin is always 25% of credits consumed — here, $6.00 on a $30 plan. The difference is how many actions the user gets: ~1,200 nano calls vs. ~21 Opus calls for the same $30.
Why credits beat flat subscriptions here
| Approach | User perception | Business risk |
|---|---|---|
| Flat unlimited | Simple | One power user can erase margin |
| Annual lump sum | High commitment | Hard to align with variable AI costs |
| Credit wallet ($30 → $30 usage) | Feels fair, pay-as-you-go | Predictable ceiling; margin built into every call |
Credits align price with value: heavy users spend faster, light users subsidize themselves through unused balance.
#Billing by User ID vs. Session ID
Not every customer is an individual. The tier structure reflects that.
┌──────────────────┐
│ FREE TIER │
│ All new users │
│ No AI · Core UX │
└────────┬─────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌────────────────────┐ ┌────────────────────────┐
│ PRO (User ID) │ │ PRO ENTERPRISE │
│ │ │ (Session ID) │
│ 1 account = │ │ │
│ 1 billing entity │ │ 1 shared session = │
│ Individual credits │ │ 1 billing entity │
│ │ │ Trigger: 10+ members │
└────────────────────┘ └────────────────────────┘Three-tier billing identity modelFree
- Entry point for every account.
- Full access to base platform features (non-AI workflows).
- No AI credits allocated. No model calls permitted.
Pro — billed to User ID
- One human, one wallet.
- Credits attach to the authenticated user document.
- Ideal for freelancers, solo builders, and individual power users.
- Stripe customer maps 1:1 with Firebase Auth
uid.
Pro Enterprise — billed to Session ID
- Designed for collaborative workspaces with 10 or more members.
- Billing entity is the session (shared workspace), not each individual login.
- One subscription covers the team; credits pool at the session level.
- Prevents 10 separate Pro subscriptions when one org is really one customer.
The critical backend difference: Free → Pro is not a boolean flag in the UI. The Cloud Function must resolve who owns the billing relationship (user vs. session), attach the Stripe customer ID to the correct entity, and propagate entitlements to every member of a session when applicable.
Comparison
| Dimension | Pro (User ID) | Pro Enterprise (Session ID) |
|---|---|---|
| Billing owner | Individual user | Shared workspace |
| Credit pool | Per user | Per session |
| Activation threshold | Any paid user | Session with 10+ members |
| Stripe mapping | uid → customer_id |
session_id → customer_id |
| Use case | Solo | Teams, agencies, orgs |
#The profitability principle
Profitability in a credit system comes from three stacked mechanisms, not from inflating the sticker price.
1. Margin on every token
The 25% markup guarantees that even a user who spends 100% of their credits generates revenue:
Revenue at full utilization = Credit purchase × 25%
$30 plan → up to ~$6 gross margin at 100% spend
This is the floor, not the ceiling.
2. Unused credits are retained margin
Most users do not exhaust their balance every cycle. Any unspent portion of the $30 wallet is pure margin — you already collected the cash; the provider cost was never incurred.
Actual profit = (Margin on spent credits) + (100% of unspent credits)
A user who spends 40% of their wallet is significantly more profitable than one at 100%.
3. Model routing keeps burn rate low
The majority of integrated tools do not require flagship reasoning models. Routing routine tasks to cheaper, faster models dramatically extends how far credits go — which improves perceived value while reducing provider cost.
| Strategy | Effect |
|---|---|
| Default to efficient models for simple tasks | Lower provider cost per action |
| Reserve expensive models for complex reasoning | Cost proportional to value delivered |
| Transparent per-model pricing (25% markup each) | No cross-subsidy between model tiers |
The "infinite AI" perception
With GPT-4.1 nano — the cheapest model in the stack — a $30 credit wallet buys roughly:
- ~150 million tokens on a typical usage mix (100K input + 25K output per call, ~1,200 calls)
- ~60 million output tokens if every credit goes purely to generation
In real terms, 1 token ≈ 0.75 words in English. That translates to:
- ~22 million words generated in normal usage (output tokens only)
- ~45 million words if the entire $30 is spent on generation alone
For context: a 300-page novel is roughly 80,000–100,000 words. Even at normal usage, $30 covers the equivalent of ~220 novels worth of AI-generated text. Sustained, non-stop usage at that volume is almost impossible for a single individual in a month — which is why the product feels unlimited while remaining economically bounded.
LAYER 1: Token markup (25% on every call)
└─► Guaranteed margin on active usage
LAYER 2: Unused credit retention
└─► Paid but never consumed = 100% margin
LAYER 3: Efficient model routing
└─► Lower COGS → credits last longer → happier users
═══════════════════════════════════
RESULT: Profitable without "$99/month" pricing
═══════════════════════════════════Profit stack — how the three layers compoundWorked example
Assume a Pro user on the $30/month credit plan:
| Scenario | Credits spent | Provider cost | Your revenue | Approx. margin |
|---|---|---|---|---|
| Light user | $8 | $6.40 | $30 collected | ~$23.60 |
| Average user | $18 | $14.40 | $30 collected | ~$15.60 |
| Power user (100%) | $30 | $24.00 | $30 collected | ~$6.00 |
Every row is profitable. The model does not depend on users not using the product — it depends on pricing each unit of usage correctly.
Summary: credits feel fair to users, token metering aligns cost with value, and the 25% markup + unused balance + smart model routing make the unit economics work without aggressive subscription pricing.