Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions apps/supercode-cli/client/app/studio/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,28 +74,9 @@ type CreditBalance = {
const CHECKOUT_BASE =
process.env.NEXT_PUBLIC_DODO_CHECKOUT_BASE ?? "https://checkout.dodopayments.com/buy"

const PRODUCT_CHECKOUT_URLS: Record<string, string> = {
// ── test mode ──
pdt_0Nk0u6EggnAdDxGtoLa1W: `${CHECKOUT_BASE}/pdt_0Nk0u6EggnAdDxGtoLa1W?quantity=1`,
pdt_0NkRjph71bwF2z3aBulCG: `${CHECKOUT_BASE}/pdt_0Nk0vwfI1kYrDaRsQzEUQ?quantity=1`,
pdt_0Nk0vS5WMtkT7u2T7P70e: `${CHECKOUT_BASE}/pdt_0Nk0vS5WMtkT7u2T7P70e?quantity=1`,
pdt_0NkRm62YJBP043k9sEDab: `${CHECKOUT_BASE}/pdt_0NkRm62YJBP043k9sEDab?quantity=1`,
pdt_0Nk0vwfI1kYrDaRsQzEUQ: `${CHECKOUT_BASE}/pdt_0Nk0vwfI1kYrDaRsQzEUQ?quantity=1`,
pdt_0NkRmfmsthQToUr41UAnd: `${CHECKOUT_BASE}/pdt_0NkRmfmsthQToUr41UAnd?quantity=1`,
pdt_0NkRmxBRNTOME3FYF9Qkg: `${CHECKOUT_BASE}/pdt_0NkRmxBRNTOME3FYF9Qkg?quantity=1`,
// ── live mode ──
pdt_0NkW4k2cUeO1f7a8yLje5: `${CHECKOUT_BASE}/pdt_0NkW4k2cUeO1f7a8yLje5?quantity=1`,
pdt_0NkW59I3J7uy2m1j0RAOF: `${CHECKOUT_BASE}/pdt_0NkW59I3J7uy2m1j0RAOF?quantity=1`,
pdt_0NkW5Vvq7Uxw55sjMlDFe: `${CHECKOUT_BASE}/pdt_0NkW5Vvq7Uxw55sjMlDFe?quantity=1`,
pdt_0NkW5s9M64jbHMoKrIpsl: `${CHECKOUT_BASE}/pdt_0NkW5s9M64jbHMoKrIpsl?quantity=1`,
pdt_0NkW6PfRqqooJXIMaX4Ci: `${CHECKOUT_BASE}/pdt_0NkW6PfRqqooJXIMaX4Ci?quantity=1`,
pdt_0NkW6cjti170KbFpeolfw: `${CHECKOUT_BASE}/pdt_0NkW6cjti170KbFpeolfw?quantity=1`,
pdt_0NkW6tnjud9Sp1iGr9TXj: `${CHECKOUT_BASE}/pdt_0NkW6tnjud9Sp1iGr9TXj?quantity=1`,
}

function getCheckoutUrl(plan: Plan): string | null {
if (!plan.dodoProductId) return null
return PRODUCT_CHECKOUT_URLS[plan.dodoProductId] ?? null
return `${CHECKOUT_BASE}/${plan.dodoProductId}?quantity=1`
}

const TIER_COLORS: Record<string, string> = {
Expand Down Expand Up @@ -314,7 +295,7 @@ function StudioPage() {
if (!confirmingPlan || !userId) return
const url = getCheckoutUrl(confirmingPlan)
if (url) {
window.location.href = url
window.open(url, "_blank", "noopener,noreferrer")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Close the checkout dialog after opening the payment link.

The new-tab path leaves confirmingPlan set. The dialog remains open in the current tab, so the user can click Pay now again and start multiple checkout attempts. Clear the state after window.open returns.

Proposed fix
       window.open(url, "_blank", "noopener,noreferrer")
+      setConfirmingPlan(null)
📝 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.

Suggested change
window.open(url, "_blank", "noopener,noreferrer")
window.open(url, "_blank", "noopener,noreferrer")
setConfirmingPlan(null)
🤖 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` at line 298, Update the
payment-link flow around window.open to clear confirmingPlan immediately after
the new tab is opened, ensuring the checkout dialog closes and duplicate Pay now
attempts cannot be initiated.

} else {
setConfirmingPlan(null)
toast.error("Checkout URL not available for this plan")
Expand Down
2 changes: 1 addition & 1 deletion apps/supercode-cli/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ FIRECRAWL_API_KEY=""
DODO_PAYMENTS_API_KEY=""
DODO_PAYMENTS_WEBHOOK_KEY=""
# ⚪ "test" to use test-mode product IDs in the seed; omit for live.
DODO_MODE="test"
DODO_MODE=""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep the example in test mode or make live mode explicit.

apps/supercode-cli/server/prisma/seed.ts:13 treats only "test" as test mode. With DODO_MODE="", a copied example configuration selects the non-test payment branch until an operator changes it. Keep "test" as the safe default, or update the consumer to require an explicit live-mode value.

🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 88-88: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 88-88: [UnorderedKey] The DODO_MODE key should go before the DODO_PAYMENTS_API_KEY key

(UnorderedKey)

🤖 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/.env.example` at line 88, Update the DODO_MODE
example configuration to use "test" as the safe default, matching the test-mode
check in the seed logic. Keep the existing consumer behavior unchanged and
ensure copied example configurations cannot select the live payment branch by
default.

# Where Dodo redirects after checkout (used by the checkout route)
# Test: set to localhost or ngrok URL
# Live: https://supercode-terminal.vercel.app/studio?success=true
Expand Down
Loading