1
0 Comments

Update: Smart Caching, Plan Proration & E2E Payment Testing shipped

Yesterday I shipped the Paywall Interceptor and Database Migration. Today was all about the complex monetization logic and making the app feel snappy without hammering the database.

What's shipped:

- Smart Cache Strategy - BillingPage now forces a full refresh on every mount (critical for financial data). All other pages (Dashboard, Lists, Details) use a manual refresh button with a 5-minute cache. This drastically reduces Turso read costs and prevents UI flashes.

- Plan Upgrade/Downgrade with Proration - Implemented the complex webhook logic to detect plan changes. When a user upgrades/downgrades via Stripe Customer Portal, the system automatically calculates and grants proportional credits based on the remaining days in the billing cycle.

- Turso Sync Fixes - Fixed the "stream not found" errors on writes.

- End-to-End Payment Testing - Validated 11 critical scenarios including credit purchases, subscription lifecycle, webhook idempotency (preventing double credits), and webhook security.

Key decisions:

- Manual vs Auto Refresh: Instead of auto-refreshing every page (which would spam the Turso replica sync), I added a manual refresh button for Dashboard and Lists. Billing remains auto-refreshed. This gives users control while saving API calls.

- Proration Logic: Instead of just giving full plan credits on upgrade, I calculated (days_remaining / total_days) * new_plan_credits. This is fairer and aligns with how Stripe handles monetary proration.

- Webhook Idempotency: Proved that our stripe_webhook_events table successfully prevents duplicate processing when Stripe resends events (tested via Stripe CLI resend).

What's left:

- Scenario 6 deep dive (Paywall edge cases with expired credits)

- Final frontend polish

- Production deploy (Render + Turso)

8 days to launch.

posted toAvatar for product Market Pain Intelligence
Market Pain Intelligence