We're replacing Townie's temporary daily usage limits with a credit-based payment system. Users purchase credits via Stripe and usage is deducted with a 50% markup on AI costs.
Goal: Replace limit checking with credit checking
Database Changes:
-
Added credit_additions table with indexes for performance
-
Removed old limit functions (overLimit, last24Hours, daily limits, hardcoded user exceptions)
New Functions in /backend/database/queries.tsx:
-
getCreditBalance(userId) - calculates balance with 50% markup on usage
-
hasInsufficientCredits(bearerToken) - checks if user can afford estimated cost
-
addCredits(userId, amount, note, stripePaymentIntentId) - adds credits to account
Updated /backend/routes/send-message.ts:
-
Replaced overLimit() with hasInsufficientCredits()
-
New error message: "Insufficient credits to continue"
Verified Working:
-
Credit addition and balance calculation
-
50% markup applied correctly (e.g., $0.50 AI cost → $0.75 deduction)
-
Users with $0 credits are blocked with new error message
Goal: Enable credit purchases via Stripe
New Backend Routes:
-
/api/stripe-webhook - Handles payment success, adds credits with signature verification
-
/api/purchase-credits - Creates payment intents ($1-$100 validation)
-
/api/credit-balance - Returns user's current balance
New Frontend Components:
-
PurchaseCreditsRoute.tsx - Full purchase page with amount selection
-
CreditBalance.tsx - Reusable balance display with low-balance warnings
Enhanced Error Handling:
-
Structured error responses with purchase URLs
-
Proper webhook signature verification with retry-friendly error throwing
-
All users are on the credit system (old limits completely removed)
-
50% markup applied at usage calculation time
-
Credit ledger system tracks all additions and usage
-
Stripe integration ready (needs environment variables)
Environment Variables Needed:
Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML STRIPE_SECRET_KEY=sk_test_... STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_WEBHOOK_SECRET=whsec_...
Stripe Dashboard Setup:
-
Create payment links for common amounts ($5, $10, $25, $50)
-
Configure webhook endpoint: https://your-domain.com/api/stripe-webhook
-
Set success URL to redirect back to Townie
Frontend Integration:
-
Add /purchase-credits route to router
-
Add component to header/nav
-
Update purchase page to use actual Stripe payment links
Goal: Clean migration messaging and remove any remaining old system references
Changes Needed:
-
Migration Message: "The free beta period of Townie has ended. Purchase credits to continue using it."
-
Pricing Explanation Page: Link explaining transparent 50% markup
-
Usage History Integration: Show credit costs in existing usage dashboard
-
Settings Page Updates: Add credit management section
Goal: Better UX and usage visibility
Features to Add:
-
Credit purchase history page
-
Enhanced usage history showing credit costs
-
Better error handling and user guidance
-
Settings page consolidation
Database Schema:
Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML credit_additions ( id, user_id, created_at, stripe_payment_intent_id, amount, note ) -- Indexes on user_id for both credit_additions and townie_usage
Balance Calculation:
Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML SELECT COALESCE(additions.total, 0) - COALESCE(usage.total, 0) as balance FROM (SELECT SUM(amount) FROM credit_additions WHERE user_id = ?) additions, (SELECT SUM(price * 1.5) FROM townie_usage WHERE user_id = ? AND our_api_token = 1) usage
Business Rules:
-
50% markup on AI costs (price * 1.5)
-
$1 minimum, $100 maximum purchase amounts
-
Credits stored as precise dollar amounts
-
Event-driven ledger (no balance table)
Backend:
-
backend/database/schema.tsx - Added credit_additions table
-
backend/database/queries.tsx - New credit functions, removed old limits
-
backend/routes/send-message.ts - Updated to use credit checking
-
backend/routes/stripe-webhook.ts - NEW: Payment processing
-
backend/routes/purchase-credits.ts - NEW: Payment intent creation
-
backend/routes/credit-balance.ts - NEW: Balance API
-
backend/index.ts - Added new routes
Frontend:
-
frontend/components/PurchaseCreditsRoute.tsx - NEW: Purchase page
-
frontend/components/CreditBalance.tsx - NEW: Balance display
-
✅ Credit addition/deduction working
-
✅ 50% markup calculation correct
-
✅ Insufficient credits blocking works
-
⏳ Stripe integration needs environment variables
-
⏳ End-to-end purchase flow needs testing
-
Set up Stripe environment variables and test webhook
-
Create actual Stripe payment links
-
Test complete purchase flow
-
Add credit balance to UI header
-
Begin Phase 3 migration messaging