refactor: streamline Dodo Payments integration and error handling: - #256
Conversation
- Removed hardcoded checkout URL logic and replaced it with a fetch request to the billing API for session creation. - Enhanced error handling for checkout session failures, providing clearer feedback on Dodo product issues. - Consolidated Dodo SDK client initialization into a shared utility function to improve code maintainability.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
WalkthroughThe PR centralizes Dodo Payments client creation, updates billing routes to use the shared helper, adds invalid-product error handling, and changes studio plan confirmation to create and follow server-generated checkout sessions. ChangesDodo billing integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant StudioPage
participant CheckoutRoute
participant DodoPayments
Client->>StudioPage: Confirm selected plan
StudioPage->>CheckoutRoute: POST user ID and plan ID
CheckoutRoute->>DodoPayments: Create checkout session
DodoPayments-->>CheckoutRoute: Return checkout URL
CheckoutRoute-->>StudioPage: Return checkout URL
StudioPage->>Client: Redirect current window
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/supercode-cli/server/src/api/billing/checkout.ts (1)
3-3: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the configured absolute import alias for shared server modules.
apps/supercode-cli/server/src/api/billing/checkout.ts#L3-L3: Replace../../lib/dodowith the@/lib/dodoalias.apps/supercode-cli/server/src/api/billing/refund.ts#L3-L3: Replace../../lib/dodowith the@/lib/dodoalias.apps/supercode-cli/server/src/api/billing/status.ts#L3-L3: Replace../../lib/dodowith the@/lib/dodoalias.apps/supercode-cli/server/src/api/billing/webhook.ts#L3-L3: Replace../../lib/dodowith the@/lib/dodoalias.As per coding guidelines, use absolute imports with
@/path aliases for web-app imports and workspace imports.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/supercode-cli/server/src/api/billing/checkout.ts` at line 3, Replace the relative Dodo imports with the configured `@/lib/dodo` alias in apps/supercode-cli/server/src/api/billing/checkout.ts:3-3, refund.ts:3-3, status.ts:3-3, and webhook.ts:3-3, preserving the existing getDodo and getDodoEnvironment imports.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/supercode-cli/client/app/studio/page.tsx`:
- Around line 294-297: Protect the checkout flow around the POST request to
/api/billing/checkout by resolving the authenticated request user before any
User query or checkout-session creation, then reject the request when its
authenticated identity does not match req.body.userId. Ensure downstream billing
logic uses only the validated authenticated user identity.
In `@apps/supercode-cli/server/src/lib/dodo.ts`:
- Around line 5-7: Update getDodoEnvironment to accept only the explicit
DODO_MODE values "test" and "live"; map them to "test_mode" and "live_mode"
respectively, and fail closed for unset or any other value instead of defaulting
to live_mode.
---
Nitpick comments:
In `@apps/supercode-cli/server/src/api/billing/checkout.ts`:
- Line 3: Replace the relative Dodo imports with the configured `@/lib/dodo` alias
in apps/supercode-cli/server/src/api/billing/checkout.ts:3-3, refund.ts:3-3,
status.ts:3-3, and webhook.ts:3-3, preserving the existing getDodo and
getDodoEnvironment imports.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: feccf712-1245-4d6e-8395-f3e59d8e7809
📒 Files selected for processing (7)
apps/supercode-cli/client/app/studio/page.tsxapps/supercode-cli/server/package.jsonapps/supercode-cli/server/src/api/billing/checkout.tsapps/supercode-cli/server/src/api/billing/refund.tsapps/supercode-cli/server/src/api/billing/status.tsapps/supercode-cli/server/src/api/billing/webhook.tsapps/supercode-cli/server/src/lib/dodo.ts
| const res = await fetch("/api/billing/checkout", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ userId, planId: confirmingPlan.id }), |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ast-grep outline apps/supercode-cli/server/src/api/billing/checkout.ts --items all
rg -n -C 10 \
'router\.(post|use)|req\.body|userId|planId|session|auth|unauthorized|forbidden' \
apps/supercode-cli/server/src/api/billing/checkout.tsRepository: yashdev9274/supercli
Length of output: 3782
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== client checkout request context =="
sed -n '270,310p' apps/supercode-cli/client/app/studio/page.tsx
echo
echo "== server api/billing checkout complete =="
cat -n apps/supercode-cli/server/src/api/billing/checkout.ts
echo
echo "== auth/session/ownership patterns in server routes =="
rg -n -C 4 "req\\.user|\\.session|session|auth|authorize|forbidden|unauthorized|middleware|Router\\.use|beforeEach|withAuth|getServerSession|getSession" apps/supercode-cli/server/src/api apps/supercode-cli/server/src | head -n 240Repository: yashdev9274/supercli
Length of output: 25788
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== server app auth usage =="
sed -n '1,220p' apps/supercode-cli/server/src/index.ts
echo
echo "== auth definition outline and relevant auth usages =="
sed -n '1,260p' apps/supercode-cli/server/src/lib/auth.ts
echo
echo "== server-side auth/session helpers =="
rg -n -C 3 "\.sign\s*\(|\.verify\s*\(|getSession|getServerSession|middleware|router\.use|express-session|cookie-session|better-auth" apps/supercode-cli/server/srcRepository: yashdev9274/supercli
Length of output: 13442
Reject checkout requests where userId does not match the authenticated user.
/api/billing/checkout accepts userId directly from the request body and creates the Dodo checkout using that value. Add middleware that resolves the request user, then compare it with req.body.userId before querying User or creating the checkout session.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/client/app/studio/page.tsx` around lines 294 - 297,
Protect the checkout flow around the POST request to /api/billing/checkout by
resolving the authenticated request user before any User query or
checkout-session creation, then reject the request when its authenticated
identity does not match req.body.userId. Ensure downstream billing logic uses
only the validated authenticated user identity.
| export function getDodoEnvironment(): DodoEnvironment { | ||
| return process.env.DODO_MODE === "test" ? "test_mode" : "live_mode" | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject unknown DODO_MODE values.
An unset or invalid value, such as "testing", selects "live_mode". This can make a non-production deployment call live Dodo endpoints. Accept only "test" and "live", then fail closed for other values.
Proposed fix
export function getDodoEnvironment(): DodoEnvironment {
- return process.env.DODO_MODE === "test" ? "test_mode" : "live_mode"
+ if (process.env.DODO_MODE === "test") return "test_mode"
+ if (process.env.DODO_MODE === "live") return "live_mode"
+
+ throw new Error('DODO_MODE must be "test" or "live"')
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function getDodoEnvironment(): DodoEnvironment { | |
| return process.env.DODO_MODE === "test" ? "test_mode" : "live_mode" | |
| } | |
| export function getDodoEnvironment(): DodoEnvironment { | |
| if (process.env.DODO_MODE === "test") return "test_mode" | |
| if (process.env.DODO_MODE === "live") return "live_mode" | |
| throw new Error('DODO_MODE must be "test" or "live"') | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/supercode-cli/server/src/lib/dodo.ts` around lines 5 - 7, Update
getDodoEnvironment to accept only the explicit DODO_MODE values "test" and
"live"; map them to "test_mode" and "live_mode" respectively, and fail closed
for unset or any other value instead of defaulting to live_mode.
Description
Type of change
How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
bun testpassesbun run typecheckpassesbun run lintpasses (if applicable)Checklist:
Summary by CodeRabbit
New Features
Bug Fixes
Chores