Sell subscriptions via store IAP on native Capacitor builds (Google Play + Apple App Store) through RevenueCat, and keep Stripe Checkout / Customer Portal for browser (non-native) users.
One entitlement model in the app: subscription API remains source of truth for gates (RAG, quotas, upgrade CTAs). Payment provider switches by platform.
Billing history: RevenueCat webhooks must upsert local Invoice/Payment rows (same as Stripe), so Account → Billing history shows store purchases with provider/store labels — not Stripe-only empty history.
Backend scope (paired chat_backend PR)
New monetization Django app
Rename/move the existing finance app → monetization (correct spelling). This is the home for all paid-access logic:
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Sell subscriptions via store IAP on native Capacitor builds (Google Play + Apple App Store) through RevenueCat, and keep Stripe Checkout / Customer Portal for browser (non-native) users.
One entitlement model in the app: subscription API remains source of truth for gates (RAG, quotas, upgrade CTAs). Payment provider switches by platform.
Billing history: RevenueCat webhooks must upsert local Invoice/Payment rows (same as Stripe), so Account → Billing history shows store purchases with provider/store labels — not Stripe-only empty history.
Backend scope (paired
chat_backendPR)New
monetizationDjango appRename/move the existing
financeapp →monetization(correct spelling). This is the home for all paid-access logic:finance_*DB tables viaMeta.db_table+SeparateDatabaseAndState(no data loss)./api/finance/for compatibility; also mount/api/monetization/.UserSubscription.Sourcewithrevenuecat; Invoice/PaymentProviderwithrevenuecat.product_id→SubscriptionPlan(field or settings map).Frontend (this repo)
Platform split via
Capacitor.isNativePlatform():@revenuecat/purchases-capacitorpurchase/restoreBilling history UI must render RevenueCat/store rows (provider badge; no Stripe hosted URL required).
Context
ai.hesychia.chat).BillingSection→ Stripe checkout/portal.Approach
Platform split
Do not open Stripe Checkout from the native shell for paid subscriptions.
Client
@revenuecat/purchases-capacitor.logIn(appUserId)after auth (user pk string);logOuton sign-out.Ops
Acceptance
monetizationapp owns Stripe + RevenueCat services/webhooks/APIsReferences