Files
chat_web_app/llm-fe/MONETIZATION.md
T
westfarn c938995380
Unit Tests / test (pull_request) Successful in 13s
Buy on StoreKit and Play Billing, then confirm with the backend (#78).
Native purchases replace RevenueCat. The app sends the signed transaction or Play token to /monetization/store/confirm/ so access is granted only after the store check.
2026-10-19 06:14:29 -05:00

1.5 KiB

Monetization (web Stripe + native store billing)

Channels

Runtime Checkout / manage Ledger
Web (!isNativePlatform) Stripe Checkout + Customer Portal via /monetization/... Stripe webhooks
Native Capacitor StoreKit (iOS) and Play Billing (Android) POST /monetization/store/confirm/ verifies the store transaction and writes the same invoice/payment tables

There is no App Store, Play, or RevenueCat webhook. After the store sheet succeeds, the app sends the signed StoreKit transaction or the Play purchase token. The backend checks it before granting access. Renewals and restores send the current store entitlement again. Access ends when the verified period end passes.

FE displays whatever /monetization/invoices/ (and subscription) returns after refresh. Provider badge uses provider (app_store, play_store, or legacy revenuecat) plus revenuecat_store.

Store account token

GET /monetization/subscription/ returns store_account_token. The native purchase passes that value as StoreKit appAccountToken and Play Billing obfuscatedAccountId. The backend rejects a token that belongs to a different user, and rejects a transaction already linked to another account.

Plan rows expose store_product_id (the store product identifier). Configure it on SubscriptionPlan.revenuecat_product_id, or set REVENUECAT_PRODUCT_PLAN_MAP so a product id maps to a plan slug.