Skip to content

feat(billing): Stripe tier provisioning script (Pay-per-Use / Pro / Scale)#74

Merged
MoltyCel merged 1 commit into
mainfrom
feat/stripe-tiers-setup-script
May 25, 2026
Merged

feat(billing): Stripe tier provisioning script (Pay-per-Use / Pro / Scale)#74
MoltyCel merged 1 commit into
mainfrom
feat/stripe-tiers-setup-script

Conversation

@MoltyCel
Copy link
Copy Markdown
Owner

Summary

  • Adds scripts/stripe_setup_tiers.py — single source of truth for the four MolTrust billing tiers in Stripe.
  • Dry-run by default. Re-runs are safe (every Price has a lookup_key; the script looks up before creating). Nothing in Stripe changes until --live is passed.

Tier catalogue

Tier Stripe shape Pricing
Free None — enforced in API Max 5 agents, validity ≤ 30 days, score capped at 60
Pay-per-Use 1 product, 4 metered CHF prices Renewal CHF 0.20 · Issuance CHF 0.30 · On-chain anchor CHF 0.50 · Compliance export CHF 19
Professional 1 product, 1 recurring price CHF 99/mo · unlimited renewals + anchoring · quarterly export · 99% SLA · validity ≤ 90 days
Scale 1 product, 1 recurring price CHF 299/mo · monthly export · anomaly alerts · 7-year retention · validity ≤ 365 days

Usage

set -a && source ~/.moltrust_secrets && set +a

# Show what would happen — touches nothing in Stripe
python3 scripts/stripe_setup_tiers.py

# Apply for real (idempotent — safe to re-run)
python3 scripts/stripe_setup_tiers.py --live

Verified

  • Compile check (py_compile) — clean
  • Dry-run against production STRIPE_SECRET_KEY on the server — emits the full JSON catalogue with action: would-create for every resource, does not call any mutating Stripe endpoint
  • --live run is intentionally deferred — Lars to execute and verify the resulting Price IDs in the Stripe Dashboard, then paste them into ~/.moltrust_secrets / DB config

Out of scope (intentional)

  • Free tier: enforced in API (app/billing.py rate-limit + validity-cap), no Stripe entity to create.
  • API-layer wiring to bill against these tiers (Customer linkage, metered-usage reporting) — separate PR once Price IDs are minted and pasted into secrets.

Dry-run sample output

{
  "mode": "dry-run",
  "tier_free": "no_stripe_entity_enforced_in_api",
  "tiers": {
    "pay_per_use":   { "product": { "action": "would-create" }, "prices": [ ...4 prices... ] },
    "professional":  { "product": { "action": "would-create" }, "prices": [ ...1 price... ] },
    "scale":         { "product": { "action": "would-create" }, "prices": [ ...1 price... ] }
  }
}

🤖 Generated with Claude Code

…cale)

Adds scripts/stripe_setup_tiers.py — the single source of truth for the
four MolTrust billing tiers in Stripe. Dry-run by default so a re-run
shows exactly what would change without touching Stripe state.

Tier catalogue:
- Free            — no Stripe entity, enforced in the API layer (max 5 agents,
                    30-day validity, score capped at 60)
- Pay-per-Use     — 1 product, 4 metered CHF prices:
                    renewal CHF 0.20, issuance CHF 0.30,
                    on-chain anchor CHF 0.50, compliance export CHF 19
- Professional    — CHF 99/mo recurring, unlimited renewals + anchoring,
                    quarterly compliance export, 99% SLA, validity ≤ 90d
- Scale           — CHF 299/mo recurring, monthly export, anomaly alerts,
                    7-year retention, validity ≤ 365d

Idempotency: every Stripe Price gets a `lookup_key` (mt_*) and the script
looks the key up before creating — re-runs are safe and don't duplicate
Stripe resources.

Usage:
    set -a && source ~/.moltrust_secrets && set +a
    python3 scripts/stripe_setup_tiers.py             # dry-run
    python3 scripts/stripe_setup_tiers.py --live      # apply

Verified dry-run works against the production STRIPE_SECRET_KEY without
touching any Stripe state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@MoltyCel MoltyCel merged commit 78f698b into main May 25, 2026
12 checks passed
@MoltyCel MoltyCel deleted the feat/stripe-tiers-setup-script branch May 25, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant