Skip to content

complete payments setup warning#960

Merged
BilalG1 merged 1 commit intodevfrom
test-mode-improvements
Oct 17, 2025
Merged

complete payments setup warning#960
BilalG1 merged 1 commit intodevfrom
test-mode-improvements

Conversation

@BilalG1
Copy link
Collaborator

@BilalG1 BilalG1 commented Oct 17, 2025

High-level PR Summary

This PR adds a warning mechanism for incomplete Stripe payments setup by checking if charges_enabled is true on the connected Stripe account. The backend now retrieves and passes the charges_enabled status through the purchase flow, and the frontend checkout form displays an error message when payments are not fully enabled, preventing users from attempting purchases on misconfigured accounts. Additionally, minor cleanup was performed including removing unused test mode toggle state management and fixing a description typo.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
2 apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
3 apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
4 apps/dashboard/src/components/payments/checkout.tsx
5 apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
6 apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts
7 apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts
8 apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx
9 apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
⚠️ Inconsistent Changes Detected
File Path Warning
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx Removes error handling and loading state management for test mode toggle, which seems unrelated to the charges_enabled warning feature
apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx Changes description from 'Stripe price ID' to 'Stack auth price ID' which is a documentation change unrelated to the charges_enabled warning

Need help? Join our Discord

Analyze latest changes

Summary by CodeRabbit

  • New Features

    • Checkout interface now displays a "Payments not enabled" message with guidance when charges are not enabled on the payment account.
  • Documentation

    • Clarified price ID field description in payment session documentation.
  • Tests

    • Updated payment validation endpoint test expectations to reflect new response fields.

@vercel
Copy link

vercel bot commented Oct 17, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
stack-backend Ready Ready Preview Comment Oct 17, 2025 0:34am
stack-dashboard Ready Ready Preview Comment Oct 17, 2025 0:34am
stack-demo Ready Ready Preview Comment Oct 17, 2025 0:34am
stack-docs Ready Ready Preview Comment Oct 17, 2025 0:34am

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 17, 2025

Walkthrough

This PR adds a charges_enabled capability check throughout the payment purchase flow. The backend now retrieves the Stripe connected account's charges_enabled status and propagates it through verification code handlers to the frontend, where the checkout form displays a warning and disables submission if charges are not enabled on the Stripe account.

Changes

Cohort / File(s) Summary
Backend Stripe Integration Refactor
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
Switches from per-account Stripe client to stack-wide Stripe instance, retrieves connected account via stripeAccountId from tenancy project, and passes both stripeAccountId and chargesEnabled status through verification code handler
Verification Code Schema Extension
apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx, apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
Adds chargesEnabled boolean field to verification data schema with yup validation and includes charges_enabled in validate-code endpoint response
Frontend Product Data & Props
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx, apps/dashboard/src/components/payments/checkout.tsx
Adds charges_enabled boolean to ProductData type and wires it as chargesEnabled prop through CheckoutForm for UI logic
Checkout UI Protection
apps/dashboard/src/components/payments/checkout.tsx
Adds early guard displaying "Payments not enabled" message when chargesEnabled is false and updates submit button disabled logic to include chargesEnabled check
Documentation & Test Updates
apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx, apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts, apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts
Updates OpenAPI field description and test expectations to include charges_enabled field
Test Mode UI Simplification
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
Removes loading state (isUpdatingTestMode) from test mode toggle, simplifying control flow to direct async invocation without blocking UI

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Dashboard as Frontend
    participant Backend as Backend API
    participant Stripe as Stripe API
    
    User->>Dashboard: Open purchase link
    Dashboard->>Backend: GET /validate-code?code=xxx
    Backend->>Stripe: Get connected account details
    Stripe-->>Backend: Return account with charges_enabled status
    Backend-->>Dashboard: Return ProductData with charges_enabled
    
    alt charges_enabled = true
        Dashboard->>Dashboard: Show checkout form
        User->>Dashboard: Submit payment
    else charges_enabled = false
        Dashboard->>Dashboard: Show "Payments not enabled" warning
        Dashboard->>Dashboard: Disable checkout submit button
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

The changes span multiple files with mixed complexity: backend Stripe integration refactoring requires careful validation of the account retrieval logic; frontend adds a new prop surface and UI guard logic that are straightforward; test updates are repetitive snapshot corrections; and the test mode toggle simplification is low-risk but deserves verification that error handling removal is intentional.

Possibly related PRs

  • Payments return url #923 — Also modifies create-purchase-url/route.ts to add return_url handling; potential merge conflict with Stripe integration refactoring in this PR.
  • payment test mode fixes #957 — Modifies CheckoutForm component props and how page-client.tsx passes props; overlapping frontend payment flow changes.
  • move save btn down, fix editable inputs #928 — Modifies the same page-client-catalogs-view.tsx file, specifically the test-mode toggle state and handler; potential conflict with isUpdatingTestMode removal.

Poem

🐰 A bunny hops through payment streams,
Where Stripe accounts fulfill our dreams,
Charges enabled, the check is true,
Guards the checkout with its clue,
No more loading—swift and lean! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The PR title "complete payments setup warning" references an aspect of the changeset—the warning mechanism for incomplete Stripe payments setup—but the term "complete" is ambiguous and does not clearly convey the primary action. A developer scanning the PR history would not immediately understand that this PR adds charges_enabled validation or displays a checkout warning when payments are not fully enabled. While the title relates to the main feature, it lacks sufficient clarity and specificity to unambiguously communicate what the PR accomplishes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed The pull request description includes the required template element—the CONTRIBUTING.md guidelines reminder comment—and substantially exceeds the minimal template requirements by providing a comprehensive high-level summary of the changes, an estimated review time, a suggested review order with file paths, and even proactive identification of inconsistent changes that may warrant reviewer attention. The description clearly explains the main feature (adding a charges_enabled warning mechanism) and acknowledges secondary cleanup changes, demonstrating that the author has provided sufficient context for reviewers to understand both the scope and intent of the changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test-mode-improvements

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Oct 17, 2025

Greptile encountered an error while reviewing this PR. Please reach out to support@greptile.com for assistance.

Copy link

@recurseml recurseml bot left a comment

Choose a reason for hiding this comment

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

Review by RecurseML

🔍 Review performed on b6a2ab5..998aaf5

  Severity     Location     Issue     Delete  
Medium apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx:1592 Unhandled promise rejection
✅ Files analyzed, no issues (8)

apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
apps/dashboard/src/components/payments/checkout.tsx
apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts
apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts

checked={paymentsConfig.testMode === true}
disabled={isUpdatingTestMode}
onCheckedChange={(checked) => void handleToggleTestMode(checked)}
onCheckedChange={(checked) => handleToggleTestMode(checked)}
Copy link

Choose a reason for hiding this comment

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

Unhandled promise rejection vulnerability. The async function handleToggleTestMode is called directly in the event handler without error handling. Previously (lines 1571-1579 in the old code), this was wrapped in a try-catch block. If project.updateConfig() throws an error, it will result in an unhandled promise rejection, causing the application to potentially crash or behave unpredictably in production. The error handling was intentionally removed, making this a regression that will lead to poor user experience when the API call fails (e.g., network issues, validation errors).


React with 👍 to tell me that this comment was useful, or 👎 if not (and I'll stop posting more comments like this in the future)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts (1)

96-103: Guard against legacy codes missing chargesEnabled.

Older verification codes won’t have chargesEnabled, so this will yield undefined and violate the response schema (and likely throw before replying). Default to false when the field is absent so previously issued links keep working.

-        charges_enabled: verificationCode.data.chargesEnabled,
+        charges_enabled: verificationCode.data.chargesEnabled ?? false,
apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx (1)

52-192: Add charges_enabled validation to prevent payment operations when charges are disabled.

The data.chargesEnabled field is available from the verification code but is never checked before creating payment intents (line 128) or subscriptions (lines 79, 155). Add a validation check near the start of the handler:

if (!data.chargesEnabled) {
  throw new StatusError(400, "Charges are not enabled for this Stripe account");
}

This should occur after validating the tenancy but before any Stripe API operations to ensure disabled accounts cannot initiate payments.

🧹 Nitpick comments (3)
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx (1)

1569-1572: Consider adding loading state for better UX.

The removal of the loading state creates two concerns:

  1. Users lack visual feedback during the update operation
  2. Multiple rapid clicks could trigger concurrent update requests

Consider restoring the loading state:

+const [isUpdatingTestMode, setIsUpdatingTestMode] = useState(false);
+
 const handleToggleTestMode = async (enabled: boolean) => {
+  if (isUpdatingTestMode) return;
+  setIsUpdatingTestMode(true);
   try {
     await project.updateConfig({ "payments.testMode": enabled });
     toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
   } catch (error) {
     toast({ 
       title: "Failed to update test mode", 
       description: error instanceof Error ? error.message : "An error occurred",
       variant: "destructive" 
     });
+  } finally {
+    setIsUpdatingTestMode(false);
   }
 };

Then update the Switch component:

 <Switch
   id={testModeSwitchId}
   checked={paymentsConfig.testMode === true}
   onCheckedChange={(checked) => handleToggleTestMode(checked)}
+  disabled={isUpdatingTestMode}
 />
apps/dashboard/src/components/payments/checkout.tsx (2)

101-112: Consider using Alert component for blocking error states.

The guard UI correctly prevents checkout when charges are disabled, but per the coding guidelines for this directory pattern, blocking alerts and errors should use Alert components rather than Typography with variant styling.

As per coding guidelines.

Apply this diff to use the Alert component:

+import { Alert, AlertDescription, AlertTitle, Button, Typography } from "@stackframe/stack-ui";
-import { Button, Typography } from "@stackframe/stack-ui";
   if (!chargesEnabled) {
     return (
       <div className="flex flex-col gap-4 max-w-md w-full p-6 rounded-md bg-background">
-        <div className="space-y-1">
-          <Typography type="h3" variant="destructive">Payments not enabled</Typography>
-          <p className="text-sm text-muted-foreground">
-            This project does not have payments enabled yet. Please contact the app developer to finish setting up payments.
-          </p>
-        </div>
+        <Alert variant="destructive">
+          <AlertTitle>Payments not enabled</AlertTitle>
+          <AlertDescription>
+            This project does not have payments enabled yet. Please contact the app developer to finish setting up payments.
+          </AlertDescription>
+        </Alert>
       </div>
     );
   }

118-118: Remove redundant disabled condition.

The !chargesEnabled check in the Submit button's disabled condition is unreachable because of the early return guard at lines 101-112. When !chargesEnabled is true, the component returns early and never renders this button.

Apply this diff to remove the redundant check:

       <Button
-        disabled={!stripe || !elements || disabled || !chargesEnabled}
+        disabled={!stripe || !elements || disabled}
         onClick={handleSubmit}
       >
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6a2ab5 and 998aaf5.

📒 Files selected for processing (9)
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts (3 hunks)
  • apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx (1 hunks)
  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts (2 hunks)
  • apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx (2 hunks)
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx (2 hunks)
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx (2 hunks)
  • apps/dashboard/src/components/payments/checkout.tsx (3 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts (2 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

In tests, prefer .toMatchInlineSnapshot where possible; refer to snapshot-serializer.ts for snapshot formatting and handling of non-deterministic values

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer ES6 Map over Record when representing key–value collections

Files:

  • apps/e2e/tests/backend/endpoints/api/v1/payments/before-offer-to-product-rename/outdated--validate-code.test.ts
  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts
  • apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx
  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
  • apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
  • apps/dashboard/src/components/payments/checkout.tsx
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
apps/backend/src/app/api/latest/**

📄 CodeRabbit inference engine (AGENTS.md)

apps/backend/src/app/api/latest/**: Organize backend API routes by resource under /api/latest (e.g., auth at /api/latest/auth/, users at /api/latest/users/, teams at /api/latest/teams/, oauth providers at /api/latest/oauth-providers/)
Use the custom route handler system in the backend to ensure consistent API responses

Files:

  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
  • apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx
  • apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

For blocking alerts and errors in UI, do not use toast notifications; use alerts instead

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
  • apps/dashboard/src/components/payments/checkout.tsx
{apps/dashboard,apps/dev-launchpad,packages/stack-ui,packages/react}/**/*.{tsx,jsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Keep hover/click animations snappy; avoid pre-transition delays on hover and apply transitions after the action (e.g., fade-out on hover end)

Files:

  • apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
  • apps/dashboard/src/components/payments/checkout.tsx
🧬 Code graph analysis (3)
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts (1)
packages/stack-shared/src/schema-fields.ts (1)
  • yupBoolean (195-198)
apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx (1)
packages/stack-shared/src/schema-fields.ts (1)
  • yupBoolean (195-198)
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts (2)
packages/stack-shared/src/utils/errors.tsx (1)
  • throwErr (10-19)
apps/backend/src/lib/stripe.tsx (1)
  • getStackStripe (18-23)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: build (22.x)
  • GitHub Check: all-good
  • GitHub Check: docker
  • GitHub Check: setup-tests
  • GitHub Check: build (22.x)
  • GitHub Check: check_prisma_migrations (22.x)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: docker
  • GitHub Check: Security Check
🔇 Additional comments (4)
apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx (1)

28-28: LGTM! Documentation clarification.

The updated description accurately reflects that this is a Stack auth price ID rather than a direct Stripe price ID.

apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx (2)

22-22: LGTM! Type definition is clean.

The charges_enabled field addition follows the existing snake_case convention and integrates cleanly with the ProductData type.


286-286: Backend validation endpoint always returns charges_enabled—no issues found.

Verification confirms the field is guaranteed in all successful responses:

  • Response schema (line 47 of validate-code/route.ts) requires charges_enabled: yupBoolean().defined()
  • Verification code data schema requires chargesEnabled: yupBoolean().defined()
  • Value always sourced from Stripe's accounts.retrieve() API, which always includes this field
  • All test snapshots confirm presence in 200 responses
  • No code paths omit the field

The prop wiring is correct and safe.

apps/dashboard/src/components/payments/checkout.tsx (1)

27-27: LGTM! Prop addition is consistent.

The chargesEnabled prop is correctly typed and integrated into the component signature.

Also applies to: 37-37

Comment on lines +15 to 16
chargesEnabled: yupBoolean().defined(),
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep verification-code data backward compatible.

Marking chargesEnabled as .defined() will reject every existing verification code created before this deploy, because those documents never had the field. We need to coerce missing values (default false) so legacy codes still validate until they expire.

-    chargesEnabled: yupBoolean().defined(),
+    chargesEnabled: yupBoolean()
+      .transform((value) => value ?? false)
+      .defined(),
📝 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
chargesEnabled: yupBoolean().defined(),
}),
chargesEnabled: yupBoolean()
.transform((value) => value ?? false)
.defined(),
}),
🤖 Prompt for AI Agents
In
apps/backend/src/app/api/latest/payments/purchases/verification-code-handler.tsx
around lines 15-16, the schema marks chargesEnabled as .defined() which will
reject existing verification code documents that lack that field; replace the
.defined() with a coercion/default so missing values validate as false (e.g. use
yup.boolean().default(false) or yup.boolean().transform((v) => (v === undefined
? false : v)).default(false)), and ensure validation/casting is applied (use
schema.validate or schema.cast as appropriate) so legacy documents without
chargesEnabled are treated as false.

Comment on lines 1569 to 1572
const handleToggleTestMode = async (enabled: boolean) => {
setIsUpdatingTestMode(true);
try {
await project.updateConfig({ "payments.testMode": enabled });
toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
} catch (_error) {
toast({ title: "Failed to update test mode", variant: "destructive" });
} finally {
setIsUpdatingTestMode(false);
}
await project.updateConfig({ "payments.testMode": enabled });
toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling to prevent unhandled promise rejections.

The removal of try/catch error handling means failures in project.updateConfig will result in unhandled promise rejections with no user feedback. Additionally, the toggle's visual state may become inconsistent with the actual server state if the update fails.

Apply this diff to restore error handling:

 const handleToggleTestMode = async (enabled: boolean) => {
+  try {
     await project.updateConfig({ "payments.testMode": enabled });
     toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
+  } catch (error) {
+    toast({ 
+      title: "Failed to update test mode", 
+      description: error instanceof Error ? error.message : "An error occurred",
+      variant: "destructive" 
+    });
+  }
 };
📝 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
const handleToggleTestMode = async (enabled: boolean) => {
setIsUpdatingTestMode(true);
try {
await project.updateConfig({ "payments.testMode": enabled });
toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
} catch (_error) {
toast({ title: "Failed to update test mode", variant: "destructive" });
} finally {
setIsUpdatingTestMode(false);
}
await project.updateConfig({ "payments.testMode": enabled });
toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
};
const handleToggleTestMode = async (enabled: boolean) => {
try {
await project.updateConfig({ "payments.testMode": enabled });
toast({ title: enabled ? "Test mode enabled" : "Test mode disabled" });
} catch (error) {
toast({
title: "Failed to update test mode",
description: error instanceof Error ? error.message : "An error occurred",
variant: "destructive"
});
}
};
🤖 Prompt for AI Agents
In
apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/products/page-client-catalogs-view.tsx
around lines 1569 to 1572, wrap the async updateConfig call in a try/catch so
failures don't produce unhandled promise rejections: call await
project.updateConfig(...) inside try, on success show the existing success
toast, and in catch show an error toast with the error message; also ensure the
toggle's visual state is reverted when the update fails (e.g., update any local
state or call the setter to restore the previous value) so the UI remains
consistent with the server.

@BilalG1 BilalG1 merged commit 1751ea4 into dev Oct 17, 2025
27 checks passed
@BilalG1 BilalG1 deleted the test-mode-improvements branch October 17, 2025 02:38
@coderabbitai coderabbitai bot mentioned this pull request Oct 17, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 4, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant