feat(claw): prompt users to purchase credits when selecting a paid model#1324
feat(claw): prompt users to purchase credits when selecting a paid model#1324
Conversation
…del during onboarding Users without credits can select paid models during KiloClaw onboarding, but the bot won't work without a balance. This adds an inline credit purchase nudge (amount selector + Stripe checkout CTA + free model fallback) and preserves model selection across the checkout redirect via the existing payment-return-url cookie.
Replace useTransition with a plain useState boolean that stays true once set, since the form submission navigates away and never needs to reset.
Show a success toast and immediately start provisioning when the user returns from Stripe checkout, so they don't have to manually click Get Started again.
Replace the hand-rolled Set of free model IDs with a direct call to the existing isFreeModel() helper, which already covers all free model detection cases (kilo free models, :free suffix, stealth models, etc.).
| ); | ||
| } | ||
|
|
||
| const needsCredits = !hasCredits && selectedModel !== '' && !isFreeModel(selectedModel); |
There was a problem hiding this comment.
WARNING: Trial-eligible users are blocked from paid-model onboarding
ensureProvisionAccess() already auto-creates a trial for first-time users, but this condition only checks hasCredits. A brand-new trialEligible user who picks Frontier/Balanced will now see the credit nudge instead of the Get Started CTA, so they can no longer start the 7-day trial from this flow.
| const needsCredits = !hasCredits && selectedModel !== '' && !isFreeModel(selectedModel); | |
| const needsCredits = !canStartTrial && !hasCredits && selectedModel !== '' && !isFreeModel(selectedModel); |
There was a problem hiding this comment.
@jeanduplessis is this true? Am I missing something in the logic?
There was a problem hiding this comment.
I'm thinking the bot is confused, but let me triple check this.
There was a problem hiding this comment.
@RSO confirmed, this is a false positive:
The bot's review comment conflates two separate concerns:
- Trial = KiloClaw instance access (the kiloclaw_subscriptions row with status: 'trialing')
- Credits = payment for model inference (total_microdollars_acquired)
These are orthogonal. A trial-eligible user who picks a frontier model genuinely needs credits because every inference call goes through OpenRouter and costs money. An instance provisioned with a paid model but zero credits is useless.
The flow the current code produces is completely correct:
- Trial-eligible user picks Frontier → sees CreditsNudge → buys $10 via Stripe
- Stripe redirects back to /claw?model=...&payment=success
- hasCredits is now true → needsCredits is false → the auto-provision effect fires (lines 102–131)
- ensureProvisionAccess() runs server-side, sees no subscription row, auto-creates a trial
- User ends up with both a trial subscription and credits for inference
Buying credits doesn't bypass or prevent the trial — ensureProvisionAccess doesn't check credits at all, it only
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Overview
Fix these issues in Kilo Cloud Issue Details (click to expand)WARNING
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (4 files)
Reviewed by gpt-5.4-20260305 · 217,692 tokens |
Add an optional cancel-path query param to the /payments/topup route, validated with isValidReturnUrl to prevent open redirects. The claw CreditsNudge now passes cancel-path=/claw so users return to the onboarding page instead of /profile when they cancel checkout.
Summary
/clawwith their model selection preserved via the existingpayment-return-urlcookie mechanism, a success toast is shown, and provisioning starts automatically.isFreeModel()helper, so selecting any free model (not just Kilo Auto: Free) from the 500+ dropdown also hides the nudge.Verification
pnpm typecheck— passes across all packagespnpm format:check(oxfmt) — passespnpm lint— passes (oxlint + eslint)Visual Changes
credit-purchase.mp4
Reviewer Notes
/profile(hardcoded ingetStripeTopUpCheckoutUrl). A follow-up could pass a custom cancel URL so users return to/clawon cancellation too.useRefguard (hasAutoProvisioned) to prevent double-firing in React strict mode or on re-renders.