William Gadoua-Billette

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

1. Introduction

2. Current architecture

3. Pricing calculation

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 architectureStripe checkout flow — current billing architecture

What this diagram shows

The flow is intentionally linear:

  1. Every user starts on Free. They get access to the platform's core actions — navigation, settings, non-AI workflows — but no AI consumption.
  2. 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.
  3. 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 model

Free

Pro — billed to User ID

Pro Enterprise — billed to Session ID

⚙️

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 uidcustomer_id session_idcustomer_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:

In real terms, 1 token ≈ 0.75 words in English. That translates to:

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 compound

Worked 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.