Overview
TalkifAI uses a credit-based billing system. Organizations purchase credits via Lemon Squeezy, which are consumed as voice sessions run. The billing system is a separate FastAPI microservice running on Google Cloud Run. Key features:- Pay-as-you-go credit system (1 credit = $1 = ~1 minute of voice conversation)
- BYOC (Bring Your Own Carrier) — no telephony markup
- Grace period of 5)
- Redis caching for fast quota checks (30s TTL)
- Automatic cost calculation via background worker
- Low balance email notifications
Architecture
Credit System
How Credits Work
Credits are:
- Purchased via Lemon Squeezy (payment processor)
- Stored per organization in the database
- Consumed at session end (not during the call)
- Cached in Redis (30-second TTL) for fast quota checks
Credit Flow
Grace Period Logic
TalkifAI uses a grace period system to prevent sudden service interruption:
Purpose: The $5 grace period prevents sudden service interruption due to timing issues or unexpected usage spikes.
Pricing Model
BYOC Architecture (Bring Your Own Carrier)
Customers provide their own SIP credentials (Twilio, Telnyx, etc.) and pay carriers directly. Platform only charges for:- Base platform fee (infrastructure)
- AI usage (STT/TTS/LLM if using platform keys)
Cost Breakdown
The total cost of a session is calculated as:Example Rates (via PricingRule table)
Example Calculation:
Actual rates are stored in the
PricingRule database table and can be updated dynamically without code changes.Payment Processing
TalkifAI uses Lemon Squeezy for payment processing:Purchase Flow
Supported Events
Webhook payload includes:
custom_data.organization_id— Links payment to orgcustom_data.user_id— User who made purchasedata.attributes.total— Amount in cents ($19.99 = 1999)
Credit Packages
Credits are purchased as one-time payments (no subscriptions):Credits never expire and remain in the organization’s balance indefinitely.
Session Tracking
Start Session
End Session
Costs are calculated asynchronously by the background worker (usually within 10-20 seconds).
Concurrency Safety
Optimistic Locking
To prevent race conditions when multiple calls end simultaneously:Redis Caching
Cache Flow
Cache Invalidation
Cache is invalidated when:- Credits are consumed (session ends)
- Credits are added (payment successful)
- Manual balance refresh requested
- Without cache: 100 requests = 100 DB queries
- With cache: 100 requests = ~3-4 DB queries (96% reduction)
Notifications
The billing service sends email notifications for:
Notifications are sent to the organization owner’s email address.
API Reference
Check Credit Quota
Consume Credits
Get Balance
Get Transaction History
Troubleshooting
Call rejected due to insufficient credits
Call rejected due to insufficient credits
Check:
- Current balance:
GET /billing/credits/balance/{org_id} - Grace period status (balance may be negative but still allowed)
- Recent transactions for unexpected charges
Credits not added after payment
Credits not added after payment
Check:
- Lemon Squeezy order status (check email receipt)
- Webhook logs:
GET /lemon-squeezy/webhook-events LemonSqueezyWebhookEvent.processedflag in database
Balance seems incorrect
Balance seems incorrect
Check:
- Transaction history for all debits/credits
- Recent session costs (may still be calculating)
- Redis cache staleness (wait 30s or force refresh)
DELETE /billing/credits/cache/{org_id}Cost calculation delayed
Cost calculation delayed
Expected behavior: Costs are calculated within 10-20 seconds by the background worker.Check:
- Worker logs for errors
BillingSession.sessionStatus= “completed”BillingSession.costsCalculatedAttimestamp
Related Documentation
- Billing & Credits — Manage your credit balance
- Organization Management — Managing org billing settings
- Analytics — View usage metrics and costs