Skip to content

Wallet and Billing

Current model

Wallet logic is implemented in app/services/wallet_reservation.py and exposed through app/api/routers/wallet.py.

The branch uses a reserve-then-finalize billing pattern:

  1. reserve an estimated token amount before generation
  2. perform chat or quiz generation
  3. finalize the reservation with actual usage
  4. refund the difference when actual usage is lower

Tables involved

  • wallet
  • wallet_ledger
  • reservations
  • transactions
  • usage_logs

Chat flow

Chat billing is driven by app/agents/teacher_agent.py:

  • check_wallet reserves BASE_CHAT_COST + TOKEN_BUFFER
  • finalize computes actual cost from answer size
  • usage_logs stores the retrieval and answer summary

If the flow enters clarification instead of full answer generation, a lower fixed actual cost is used.

Quiz flow

Quiz generation in app/api/routers/quiz.py reuses the same wallet service:

  • estimate 300 tokens
  • reserve before generation
  • finalize with actual token usage returned by the quiz generator
  • mark and refund expired reservations on failure paths

Admin financial operations

Admin-only endpoints support:

  • wallet top-up
  • expense logging
  • transaction history
  • internal reserve/finalize endpoints for operational use

These endpoints require an admin JWT, not a separate billing service.

Operational caveats

  • Reservation expiry cleanup is intended to be scheduled, but the current scheduler implementation is not aligned with the wallet service API and should be treated as unverified.
  • Billing logic is tightly coupled to Supabase table updates and does not yet use database-side transactions or stored procedures for atomicity.