Skip to main content
FIM One enthält eine vollständige Stripe-Billing-Pipeline hinter einem Instance-Access-Modell. Private Deployments lassen es auf No subscriptions (Keine Abonnements) und zeigen nie Zahlungs-UI. Betreiber, die einen Katalog möchten, wählen Included + paid (Enthalten + bezahlt) oder Paid only (Nur bezahlt) und erhalten gehostete Checkout, Customer Portal, Webhook-gesteuerte Abonnement-Lebenszyklen und Kontingentdurchsetzung.
Die Software-Standardeinstellung ist No subscriptions (access_model = off, default_token_quota = 0 bedeutet unbegrenzt). Neue Installationen und bestehende Self-Hosts starten dort. Keine Billing-UI wird angezeigt, bis ein Admin eine Stripe-Einstellung wählt.

Was Sie erhalten

  • Drei Zugriffsmodi: keine Abos, enthalten + kostenpflichtig oder nur kostenpflichtig
  • Stripe-gehosteter Checkout — Benutzer führen ein Upgrade durch, ohne dass Ihre Code-Kartendaten berührt
  • Kundenportal — Benutzer aktualisieren Zahlungsmethoden, laden Rechnungen herunter, kündigen — alles auf der Stripe-Benutzeroberfläche
  • Webhook-gesteuerte Lebenszyklen — Abos werden automatisch bereitgestellt und erneuert; stornierte kostenpflichtige Benutzer kehren am Ende des Zeitraums zur kostenlosen Stufe zurück (oder werden in reinen Bezahlmodellen nicht berechtigt)
  • Kontingentdurchsetzung — Token-Nutzung pro Zeitraum verfolgt; Unterbrechung während des Streams mit strukturierter Upgrade-Aufforderung
  • Admin-Seiten für Plan-CRUD und Abonnementüberwachung

Voraussetzungen

  1. Stripe-Konto mit aktiviertem Live-Modus. Unternehmen mit Sitz in Singapur müssen KYC abschließen (Business UEN, Ausweis des Geschäftsführers, Bankkonto). Die Genehmigung dauert normalerweise 1–3 Tage.
  2. Stripe Live API-Schlüssel vom Typ Restricted (empfohlen gegenüber Standard sk_live_*** — einfacher zu widerrufen, begrenzte Berechtigungen).
  3. Webhook-Endpunkt öffentlich erreichbar unter <your-domain>/api/webhooks/stripe.
  4. Bankkonto für Auszahlungen. Multi-Währungs-Abrechnung (z. B. USD-Auszahlung auf ein USD-Konto) wird für Stripe-Konten ohne USD-Standard empfohlen, um 1,5–2 % Devisenverluste pro Transaktion zu vermeiden.

Einrichtung

1. Stripe Dashboard

Pro-Produkt erstellen

  1. Catalog → Products → + Add product
  2. Name: Pro, description: 5M tokens / month, priority support
  3. Pricing: Recurring, monthly, $20.00 USD (adjust to your pricing strategy)
  4. Save → copy the resulting price_*** ID (you will UPDATE the local billing_plans table with this value after activation)

Erstellen Sie einen eingeschränkten API-Schlüssel

  1. Developers → API keys → + Create restricted key
  2. Name: fim-one production
  3. Permissions (minimum):
    • Customers: Write
    • Subscriptions: Write
    • Checkout Sessions: Write
    • Customer portal: Write
    • Prices: Read
    • Products: Read
  4. Save → copy rk_live_***

Webhook-Endpunkt registrieren

  1. Developers → Webhooks → + Add endpoint
  2. URL: https://<your-domain>/api/webhooks/stripe
  3. Zu empfangende Events:
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_succeeded
    • invoice.payment_failed
  4. Nach dem Speichern auf “Reveal signing secret” klicken → whsec_*** kopieren

Multi-Währungs-Abrechnung konfigurieren (empfohlen)

Wenn sich die Standardwährung Ihres Stripe-Kontos von der Preiswahrung unterscheidet, die Sie berechnen (häufiger Fall: SGD-Konto mit USD-Abrechnung):
  1. Settings → Bank accounts and currencies → Add a settlement currency
  2. Wählen Sie die Preiswahrung (z. B. USD)
  3. Fügen Sie das entsprechende Bankkonto an (z. B. ein Aspire USD Virtual Account)
  4. Speichern — Stripe leitet USD-Gebühren direkt zu USD-Auszahlungen weiter, ohne Devisenumrechnung

2. Backend .env

Legen Sie diese drei Schlüssel in Ihrer Produktions-.env fest:
Siehe Umgebungsvariablen für die vollständige Referenz. Starten Sie das Backend nach dem Bearbeiten von .env neu, damit die Schlüssel übernommen werden:

3. In Admin aktivieren

  1. Melden Sie sich als Admin an
  2. Admin → System Settings → Access and billing
  3. Wählen Sie eine Posture aus (die Instanz befindet sich immer in genau einer):
    • No subscriptions (Software-Standard) — Stripe wird nicht verwendet. Token-Zugriff ist das Standard-Monatskontingent (0 = unbegrenzt).
    • Included + paid — Stripe erforderlich. Neue Benutzer landen auf dem Included-Tier; sie können upgraden. Stornierte bezahlte Benutzer kehren am Ende des Abrechnungszeitraums zum Included-Tier zurück.
    • Paid only — Stripe erforderlich. Kein Included-Tier. Benutzer müssen sich abonnieren, bevor sie Modelle aufrufen können. Bestehende Benutzer des Included-Tiers behalten ihr Kontingent, wenn Sie von Included + paid wechseln.
  4. Das Backend validiert, dass sowohl STRIPE_SECRET_KEY als auch STRIPE_WEBHOOK_SECRET vorhanden sind, wenn Sie eine Stripe-Posture wählen — wenn einer fehlt, wird 400 zurückgegeben
  5. Bei der ersten Aktivierung einer Stripe-Posture führt das Backend ein idempotentes Setup durch:
    • Included + paid: erstellt den Included-Plan (slug=free) + eine Pro-Vorlage mit einer leeren Price ID; setzt default_plan_id; füllt Benutzer ohne Plan auf
    • Paid only: erstellt nur die Pro-Vorlage; führt keine Auffüllung durch
    • Kopiert default_token_quota auf den Included-Plan, wenn dieser Plan erstellt wird (0 bleibt 0, unbegrenzt)
  6. Das Zurückschalten auf No subscriptions ist ein reines Flag-Flip ohne Datennebenwirkungen. Der Standard-Included-Plan kann nicht gelöscht werden, während Included + paid aktiv ist.

4. Aktualisieren Sie den Pro-Plan mit Ihrem Live-Preis

Nach der Aktivierung aktualisieren Sie den vordefinierten Pro-Plan, um auf Ihren Live-Stripe-Preis zu verweisen:
  • Admin → Billing → Plans → Pro → Edit
  • Fügen Sie Ihre price_1*** (aus Schritt 1) in Stripe Price ID ein
  • Speichern
Oder über SQL (wenn Sie direkten Datenbankzugriff bevorzugen):

5. Smoke-Test

  1. Öffnen Sie /settings?tab=billing als normaler Benutzer
  2. Klicken Sie auf Switch to Pro
  3. Stripe Checkout wird geöffnet; füllen Sie es mit einer echten Karte mit niedrigem Betrag aus (erstatten Sie danach)
  4. Webhook sollte ausgelöst werden — überprüfen Sie im Stripe Dashboard → Webhooks → aktuelle Ereignisse zeigen 2xx-Antworten
  5. Abonnementzeile erscheint in der Tabelle subscriptions; users.plan_id wechselt zu pro
  6. Die Benutzeroberfläche zeigt jetzt Pro-Plan + Schaltfläche „Manage subscription”

Abrechnung deaktivieren

Schalten Sie den Schalter Enable Stripe Billing in Admin → System Settings → Billing AUS. Wenn deaktiviert:
  • Alle /api/billing/*-Endpunkte geben 503 zurück
  • Der Webhook-Endpunkt gibt 503 zurück (Stripe wird erneut versuchen und dann im Dashboard als fehlgeschlagen angezeigt — das ist in Ordnung, Sie können den Webhook stattdessen im Stripe Dashboard deaktivieren, wenn die Abrechnung dauerhaft ausgeschaltet ist)
  • Die Registerkarte Plan & Billing für Benutzer verschwindet
  • Die Navigationsgruppe Admin → Billing ist ausgeblendet
  • Die Quota-Kette überspringt die Plan-Stufe und fällt direkt auf default_token_quota zurück
Daten werden beibehalten: Vorhandene subscriptions-, billing_plans- und users.plan_id-Zeilen bleiben unverändert. Das erneute Aktivieren wird vom gleichen Status aus fortgesetzt, ohne dass eine Migration erforderlich ist.

Berechnungsreferenz — Kontingent- und Token-Mathematik

Dies ist die autoritative Referenz für jede numerische Regel, die entscheidet, was ein Benutzer verbrauchen darf, wann sein Zähler zurückgesetzt wird und wie die Auflösungskette zusammengesetzt wird. Lesen Sie dies, bevor Sie Preise ändern, Kontingente anpassen, Nutzungs-Dashboards erstellen oder v2/v3-Arbeiten planen. Zukünftige, aber noch nicht ausgelieferte Regeln sind in ihrem reservierten Slot dokumentiert, damit Mitwirkende wissen, wo neue Logik eingebunden wird.

Glossar

Was als Token zählt

Die Token-Nutzung wird auf der LLM-Aufrufsebene erfasst, basierend auf dem usage-Objekt von LiteLLM bei jedem Completion.
  • Gezählt: Prompt-Tokens + Completion-Tokens bei jedem Modellaufruf
  • Gezählt: jeder Roundtrip in einem mehrstufigen / Tool-Use-Agent-Flow (jeder Modellaufruf ist eine separate Belastung)
  • Gezählt: Embedding-Anfragen (KB-Ingestion, Abruf-Scoring)
  • Nicht gezählt: eingegebene Daten, die nie an ein Modell gesendet werden (z. B. hochgeladene Dateien, die der Benutzer verwirft)
  • Nicht gezählt: Anfragen, die fehlschlagen, bevor sie den Provider erreichen (Authentifizierungsfehler, Rate-Limit-Vorabprüfung)
  • Zwischengespeicherte Eingabe: in v1 zum vollen Preis gezählt (kein Provider-Cache-Rabatt wird angezeigt). v2 kann zwischengespeicherte Prompt-Tokens möglicherweise separat gutschreiben.

Three-state override semantics

users.token_quota ist die administrative Überschreibung pro Benutzer. Sie hat drei Bedeutungen in einer Spalte: Die Überschreibung hat immer Vorrang vor Plan und Standard. Sie existiert, damit Admins einzelne Benutzer über oder unter ihrem Plan-Tier positionieren können, ohne Stripe zu berühren.

Quota resolution chain — v1 (current)

For any authenticated request, the cap is computed top-down — first match wins:
Step 4 is the instance-wide cap for No subscriptions. Under Paid only, a user with no plan is unentitled (chat returns 402) even if default_token_quota is 0.

Periodische Zurückstellung

  • Für bezahlte Benutzer spiegelt quota_reset_at Subscription.current_period_end wider. Der invoice.payment_succeeded Webhook-Handler setzt tokens_used_this_period = 0 und verschiebt quota_reset_at bei jeder erfolgreichen Verlängerung auf das neue Periodenende.
  • Für kostenlose Benutzer (kein Stripe-Abonnement) setzt ein stündlicher Cron tokens_used_this_period auf 0 an einer Kalendermonatsgrenze, die am Plan-Zuweisungsdatum verankert ist.
  • Planänderungen in der Mitte einer Periode setzen den Zähler nicht zurück — nur Verlängerungen tun dies. Dies verhindert Quota-Cycling-Exploits („abonnieren → Pro-Quota nutzen → kündigen → erneut abonnieren”).

Mid-stream enforcement

  • Pre-flight check at chat-call entry: cheapest path, blocks requests the user can’t afford to start.
  • During streaming, the running token count is re-evaluated on every chunk. Crossing the cap closes the stream with a structured terminator frame, not a network error.
  • The frontend interprets the terminator and surfaces <QuotaExceededDialog> with a deep link to /settings?tab=billing.
  • Non-streaming responses return HTTP 402 with body { code: "QUOTA_EXCEEDED", reset_at, upgrade_url }.

Billing-deaktiviert-Fallback

Wenn system_settings.billing_enabled = FALSE:
  • Schritt 2 der Kette wird übersprungen — die Kette reduziert sich auf override → default → unlimited.
  • /api/billing/* und /api/webhooks/stripe geben 503 zurück.
  • Die Registerkarte Plan & Billing für Benutzer und die Admin → Billing-Navigationsgruppe sind ausgeblendet.
  • Alle Abrechnungsdaten (Abonnements, Pläne, users.plan_id) bleiben erhalten — das erneute Aktivieren setzt den gleichen Status fort, ohne Migration erforderlich zu sein.

Reserviert: quota chain v2 — Team-Plätze

Noch nicht ausgeliefert. Hier dokumentiert, damit die v2-Arbeit einen bekannten Landeplatz hat.
Wenn der Team-Plan ausgeliefert wird:
  • Subscription.quantity führt die Platzanzahl (Stripe-nativ).
  • Der effektive Plan eines Benutzers wird durch Team-Mitgliedschaft aufgelöst, bevor auf seinen persönlichen Plan zurückgegriffen wird:
  • Quota ist pro Platz (jedes Team-Mitglied erhält ein vollständiges monthly_token_quota), nicht ein gemeinsamer Pool. Gemeinsame Pools führen zu First-Come-First-Served-Erschöpfung und sind kundenfeindlich.
  • Override-Semantik bleibt unverändert — Team-Administratoren können einzelne Mitglieder weiterhin hart begrenzen über users.token_quota = N, was in der Kette über dem Team-Plan liegt.

Reserved: quota chain v3 — native Org allocation (no Stripe)

Noch nicht veröffentlicht. Reserviert für On-Prem- / Enterprise-Deployments, die Kontingente intern zuweisen, ohne pro Benutzer über Stripe zu bezahlen.
  • Neue Tabelle org_quota_allocations(user_id, monthly_token_quota, org_id) verteilt ein übergeordnetes Budget auf Mitglieder.
  • Zuweisungen sind pro Benutzer, kein gemeinsamer Pool — jedes Mitglied hat ein klares individuelles SLA.
  • Aktualisierte Chain:
  • max(), nicht sum(). Ein bezahlter Pro-Benutzer erhält nie weniger als das, wofür er bezahlt hat, auch wenn sein Org-Administrator eine niedrige Zuweisung festlegt. Das über Stripe bezahlte Kontingent ist unverletzlich.

Reserviert: Pay-per-use-Gutschriftsaldo (v3 separate Dimension)

Noch nicht ausgeliefert. Eine separate Achse vom obigen Schema — Gutschriften sind eine einmalige Aufstockung, keine Abonnement-Stufe.
  • Neue Tabelle user_credits(user_id, balance_cents, currency) — finanziert über Stripe Checkout mode='payment'.
  • Verbrauchsreihenfolge: Abonnement-Kontingent zuerst, dann Gutschriftsaldo (nur nach Erschöpfung des Abonnements beginnt die Gutschrift zu sinken).
  • Gutschriftsaldo ist nicht erstattbar (Industriestandard für Prepaid).
  • UI zeigt beide Balken: Subscription quota: 4.2M / 5M used + Credits: $7.40 remaining.

Standardwerte

Standardwerte zur Bereitstellung — alle nach der Installation anpassbar, außer wo vermerkt.

Preismodell

V1 ist ein pauschales Abonnement. Free + Pro, monatliche Abrechnung, nur USD. Nicht im Umfang von v1 (absichtlich, auf die Roadmap verschoben):
  • Team-Plan (Stripe-Plätze / subscription.quantity)
  • Jährliche Abrechnung
  • Multi-Währungs-Präsentation
  • Gutscheine / Promo-Codes
  • Steuerbehandlung (Stripe Tax-Integration — erfordert separate Compliance-Überprüfung)
  • Nutzungsbasierte Messung / Überschussgebühren
  • Pay-per-Use-Guthaben (einmalige Aufstockung)
Siehe die Roadmap für die nächsten geplanten Schritte.

Fehlerbehebung

Der Aktivierungsendpunkt erfordert, dass sowohl STRIPE_SECRET_KEY als auch STRIPE_WEBHOOK_SECRET gesetzt sind. Bestätigen Sie, dass sie in .env vorhanden sind und dass das Backend nach der Bearbeitung neu gestartet wurde.
Entweder ist die Abrechnung deaktiviert (Toggle ist AUS), oder die Anfragensignaturverifizierung ist fehlgeschlagen (nicht übereinstimmender STRIPE_WEBHOOK_SECRET). Überprüfen Sie Stripe Dashboard → Webhooks → aktuelle Ereignisse auf den tatsächlichen Fehlertext.
Der checkout.session.completed-Webhook hat Ihr Backend nicht erreicht. Überprüfen Sie, dass die Endpunkt-URL im Stripe Dashboard genau mit <your-domain>/api/webhooks/stripe übereinstimmt, einschließlich des nachfolgenden Pfads. Überprüfen Sie die letzten Webhook-Zustellungen auf Fehler.
Die Seed-Migration schreibt eine Test-Modus-Preis-ID. Nach der Aktivierung der Produktionsabrechnung aktualisieren Sie den Pro-Plan, um Ihre Live-price_1*** über Admin → Abrechnung → Pläne → Pro → Bearbeiten oder über direktes SQL UPDATE zu verwenden.
Konfigurieren Sie Ihr Geschäfts-Branding im Stripe Dashboard → Einstellungen → Branding. Fügen Sie Ihr Logo, Ihren Geschäftsnamen (z. B. „FIM Labs Pte. Ltd.”) und Ihre Adresse hinzu. Stripe wendet diese auf alle automatisch generierten Quittungen und Rechnungen an.
Wenn sich die Standardwährung Ihres Stripe-Kontos von Ihrer Abrechnungswährung unterscheidet, konvertiert Stripe bei jeder Auszahlung (1,5–2% Spread). Fügen Sie eine entsprechende Abrechnungswährung unter Einstellungen → Bankkonten und Währungen hinzu, verknüpfen Sie ein Bankkonto mit derselben Währung, und Stripe leitet Zahlungen mit derselben Währung ohne Umrechnung weiter.