Skip to content

Payments return url#923

Merged
BilalG1 merged 9 commits intodevfrom
payments-redirect-url
Oct 6, 2025
Merged

Payments return url#923
BilalG1 merged 9 commits intodevfrom
payments-redirect-url

Conversation

@BilalG1
Copy link
Contributor

@BilalG1 BilalG1 commented Oct 3, 2025

High-level PR Summary

This PR adds support for an optional returnUrl parameter to the payments flow, allowing users to be redirected back to a specific URL after completing or bypassing a purchase. The feature is implemented across the full stack: the API endpoint now accepts return_url, the SDK methods (createCheckoutUrl) accept an optional returnUrl parameter for both client and server implementations, and the dashboard purchase flow propagates this URL through the checkout and return pages to perform the final redirect. The change also improves the user experience when adding dashboard admins by redirecting back to the original page after payment.

⏱️ Estimated Review Time: 15-30 minutes

💡 Review Order Suggestion
Order File Path
1 packages/template/src/lib/stack-app/customers/index.ts
2 packages/stack-shared/src/interface/client-interface.ts
3 apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
4 packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts
5 packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts
6 apps/dashboard/src/components/payments/checkout.tsx
7 apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
8 apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
9 apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
10 apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts
11 apps/e2e/tests/js/payments.test.ts
12 apps/backend/src/route-handlers/smart-response.tsx
⚠️ Inconsistent Changes Detected
File Path Warning
apps/backend/src/route-handlers/smart-response.tsx Changes the type of 'body' from 'ArrayBuffer' to 'BodyInit' which appears unrelated to adding payment redirect URL functionality

Need help? Join our Discord


Important

Add optional returnUrl parameter to payment flow, updating API, SDK, and dashboard to handle post-purchase redirects.

  • Behavior:
    • Added optional returnUrl parameter to payment flow in create-purchase-url/route.ts and validate-code/route.ts.
    • Updated CheckoutForm in checkout.tsx to handle returnUrl.
    • Dashboard redirects back to original page after payment if returnUrl is provided.
  • Refactor:
    • Centralized server-side customer logic in server-app-impl.ts.
  • Tests:
    • Added tests in create-purchase-url.test.ts and validate-code.test.ts for returnUrl handling and validation.
    • Updated payments.test.ts to verify returnUrl embedding in checkout URL.

This description was created by Ellipsis for 259529b. You can customize this summary. It will automatically update as commits are pushed.


Summary by CodeRabbit

  • New Features

    • Added optional return URL support across the checkout flow so purchase links can include a return destination and users are redirected back after purchase.
    • Dashboard checkout now opens in the same tab and preserves/propagates return URLs through purchase and return pages.
  • Refactor

    • Centralized server-side customer logic to unify checkout URL creation.
  • Tests

    • Added/updated E2E and integration tests to verify return URL embedding and redirect behavior.

@vercel
Copy link

vercel bot commented Oct 3, 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 6, 2025 9:19pm
stack-dashboard Ready Ready Preview Comment Oct 6, 2025 9:19pm
stack-demo Ready Ready Preview Comment Oct 6, 2025 9:19pm
stack-docs Ready Ready Preview Comment Oct 6, 2025 9:19pm

@BilalG1 BilalG1 changed the title Payments redirect url Checkout return url Oct 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds optional return_url handling end-to-end: backend create-purchase-url and validate-code accept/validate return_url, clients and shared APIs propagate it, dashboard/checkout flows include it in Stripe return links and in-tab navigation, tests added/updated, and server customer checkout helper centralized.

Changes

Cohort / File(s) Summary of changes
Backend: create-purchase-url
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
Add optional return_url (validated) to POST body; validate via validateRedirectUrl and append return_url query param to generated purchase URL; throw RedirectUrlNotWhitelisted on invalid.
Backend: validate-code routes
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
Add GET route that mirrors POST; accept optional return_url in query/body and validate against tenancy; POST schema now includes return_url.
Dashboard: purchase pages & CheckoutForm
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx, apps/dashboard/src/app/(main)/purchase/return/page-client.tsx, apps/dashboard/src/components/payments/checkout.tsx
Read return_url from query params; propagate returnUrl prop into CheckoutForm; include return_url in bypass/navigation and in Stripe confirmPayment return URL; adjust success messaging and flows to handle redirect when present.
Dashboard: admin navigation
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
When admin limit reached, pass returnUrl to createCheckoutUrl and use window.location.assign for same-tab navigation (replace previous window.open).
Shared client interface
packages/stack-shared/src/interface/client-interface.ts
Add optional returnUrl?: string parameter to createCheckoutUrl and include return_url in POST payload when provided.
Template app implementations
packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts, packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts
Client: accept returnUrl? in createCheckoutUrl options and forward it. Server: add protected helper _createServerCustomer(...) to centralize item access and createCheckoutUrl behavior; refactor user/team item implementations to use helper; expose Customer type import.
Customer types
packages/template/src/lib/stack-app/customers/index.ts
Extend Customer.createCheckoutUrl options to allow optional returnUrl?: string in both branches (client/server shapes).
E2E / integration tests
apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts, apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts, apps/e2e/tests/js/payments.test.ts
Add/adjust tests to assert return_url propagation and whitelisting behavior; add test for rejecting untrusted return_url.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Dashboard UI
  participant Client as Stack Client
  participant Backend as Backend API
  participant Stripe as Stripe
  participant Return as /purchase/return

  UI->>Client: createCheckoutUrl(productId, returnUrl?)
  Client->>Backend: POST /payments/purchases/create-purchase-url { productId, return_url? }
  Backend-->>Client: 200 { purchaseUrl (includes ?return_url=...) }
  Client-->>UI: purchaseUrl
  UI->>UI: window.location.assign(purchaseUrl)  %% in-tab navigation

  UI->>Stripe: confirmPayment(..., return_url: /purchase/return?code=...&return_url=...)
  Stripe-->>Return: Redirect to /purchase/return?code=...&return_url=...
  Return->>Backend: GET /payments/purchases/validate-code?full_code=...&return_url=...
  Backend-->>Return: 200 { valid: true } or 400 (REDIRECT_URL_NOT_WHITELISTED)
  alt valid & return_url trusted
    Return-->>UI: Redirect to provided return_url
  else invalid return_url
    Return-->>UI: Show error (cannot redirect)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • N2D4

Poem

A rabbit tucked a URL in tow,
From dashboard tap to Stripe we go.
One tab, one hop, the return in sight,
Codes and carrots bounce polite.
Hop on, redirect—bounce back right! 🥕🐇

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 title “Payments return url” references the core feature but lacks a verb or context to convey the action being taken, making it too terse to clearly summarize the main change at a glance. Please rephrase the title to clearly reflect the change, for example “Add optional return_url support to payments flow,” so it immediately communicates the new functionality.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed The PR description begins with the required CONTRIBUTING.md guideline comment and includes a concise high-level summary, detailed implementation notes, a review order suggestion, and test coverage, satisfying the repository’s description template requirements.
✨ 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 payments-redirect-url

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.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

This PR implements comprehensive support for custom redirect URLs in the Stack Auth payments system. The changes add an optional `returnUrl` parameter throughout the payment flow, allowing applications to specify where users should be redirected after completing a purchase. The implementation spans the entire payment lifecycle:
  1. Client Interface Extensions: Added returnUrl parameter to checkout URL creation methods in both client and server implementations, maintaining backward compatibility through optional typing.

  2. Backend API Enhancement: The /payments/purchases/create-purchase-url endpoint now accepts and validates a return_url parameter, which gets appended to the generated purchase URL as a query parameter.

  3. Payment Flow Integration: The purchase pages extract the return URL from query parameters and pass it through the payment components. The CheckoutForm component embeds the return URL in the Stripe return URL configuration.

  4. Post-Payment Redirect Logic: The payment return page now automatically redirects users to the specified return URL after successful payment or when bypassing in test mode, with appropriate user messaging.

  5. Dashboard Integration: The team upgrade flow in the dashboard now uses the new return URL functionality to redirect users back to their original location after completing checkout.

The implementation follows existing patterns in the codebase and includes comprehensive test coverage. It enhances user experience by eliminating the need for users to manually navigate back to their original context after payment completion.

PR Description Notes:

  • The PR description is empty except for the contributing guidelines comment

Important Files Changed

Changed Files
Filename Score Overview
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts 4/5 Adds optional return_url parameter validation and query parameter appending to purchase URLs
packages/stack-shared/src/interface/client-interface.ts 3/5 Adds optional returnUrl parameter to createCheckoutUrl method but may send undefined values to API
packages/template/src/lib/stack-app/customers/index.ts 5/5 Type definition changes adding optional returnUrl parameter to checkout options
packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts 5/5 Simple parameter passthrough for returnUrl in client implementation
packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts 4/5 Refactors duplicate code into shared method while adding returnUrl support
apps/dashboard/src/components/payments/checkout.tsx 4/5 Integrates returnUrl parameter into Stripe checkout configuration
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx 4/5 Extracts and passes return URL through payment flow components
apps/dashboard/src/app/(main)/purchase/return/page-client.tsx 4/5 Implements automatic redirect logic using extracted return URL
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx 4/5 Updates team upgrade flow to use return URL and current window navigation
apps/backend/src/route-handlers/smart-response.tsx 5/5 Type alignment change from ArrayBuffer to BodyInit for broader binary response support
apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts 4/5 Adds test coverage for return_url parameter in API endpoint
apps/e2e/tests/js/payments.test.ts 4/5 Adds test for checkout URL generation with return URL parameter

Confidence score: 4/5

  • This PR is generally safe to merge with well-structured changes following established patterns
  • Score reflects comprehensive implementation with good test coverage, though some minor type safety concerns exist
  • Pay close attention to packages/stack-shared/src/interface/client-interface.ts for potential undefined value handling

Sequence Diagram

sequenceDiagram
    participant User
    participant Frontend
    participant Backend
    participant Stripe
    participant Database

    User->>Frontend: "Click create checkout button"
    Frontend->>Backend: "POST /payments/purchases/create-purchase-url"
    note over Frontend,Backend: "{ customer_type, customer_id, offer_id, return_url }"
    
    Backend->>Backend: "Validate offer configuration"
    Backend->>Stripe: "Search for existing customer"
    alt Customer doesn't exist
        Backend->>Stripe: "Create new customer"
    end
    
    Backend->>Database: "Create verification code"
    Backend->>Backend: "Generate purchase URL with code"
    Backend-->>Frontend: "{ url: 'https://dashboard/purchase/{code}?return_url=...' }"
    
    Frontend->>Frontend: "Redirect to purchase URL"
    User->>Frontend: "Visit purchase page"
    Frontend->>Backend: "POST /payments/purchases/validate-code"
    Backend->>Database: "Validate purchase code"
    Backend-->>Frontend: "Offer details and Stripe account info"
    
    User->>Frontend: "Select price and quantity"
    User->>Frontend: "Click submit payment"
    Frontend->>Backend: "POST /payments/purchases/purchase-session"
    Backend->>Stripe: "Create payment session"
    Backend-->>Frontend: "{ client_secret }"
    
    Frontend->>Stripe: "Process payment with client_secret"
    Stripe-->>Frontend: "Payment result"
    Frontend->>Frontend: "Redirect to return page"
    
    alt Payment successful and return_url provided
        Frontend->>Frontend: "Redirect to return_url"
    else Payment successful, no return_url
        Frontend->>Frontend: "Show success message"
    end
Loading

12 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

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 69fb515..5d7547f

✨ No bugs found, your code is sparkling clean

✅ Files analyzed, no issues (5)

packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts
apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
apps/dashboard/src/components/payments/checkout.tsx
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx

⏭️ Files skipped (7)
  Locations  
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
apps/backend/src/route-handlers/smart-response.tsx
apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts
apps/e2e/tests/js/payments.test.ts
packages/stack-shared/src/interface/client-interface.ts
packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts
packages/template/src/lib/stack-app/customers/index.ts

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 (1)
apps/dashboard/src/app/(main)/purchase/return/page-client.tsx (1)

35-57: Harden returnUrl redirects against javascript: URIs

window.location.assign(returnUrl) is now reached on both the bypass and success paths. Because the query param is attacker-controlled, values such as javascript:alert(1) will execute immediately, yielding an XSS on the purchase return page. Please normalise and vet the value (e.g. parse with new URL(..., window.location.origin) and only honour http: / https: schemes) before using it, and skip the redirect if it fails validation.

Example fix:

-  const returnUrl = searchParams.get("return_url");
+  const rawReturnUrl = searchParams.get("return_url");
+  const safeReturnUrl = (() => {
+    if (!rawReturnUrl) return null;
+    try {
+      const parsed = new URL(rawReturnUrl, window.location.href);
+      return ["http:", "https:"].includes(parsed.protocol) ? parsed.toString() : null;
+    } catch {
+      return null;
+    }
+  })();

and then guard both window.location.assign(...) calls behind if (safeReturnUrl).

🧹 Nitpick comments (1)
packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts (1)

196-215: Recommend improving type safety for returnUrl access.

The helper successfully centralizes customer-related logic and reduces duplication. However, line 212 uses (options as any).returnUrl to access the returnUrl property, which bypasses type checking.

Consider extracting returnUrl explicitly to avoid the any cast:

-      async createCheckoutUrl(options: { offerId: string, returnUrl?: string } | { offer: InlineOffer, returnUrl?: string }) {
+      async createCheckoutUrl(options: { offerId: string, returnUrl?: string } | { offer: InlineOffer, returnUrl?: string }) {
         const offerIdOrInline = "offerId" in options ? options.offerId : options.offer;
-        return await app._interface.createCheckoutUrl(type, userIdOrTeamId, offerIdOrInline, null, (options as any).returnUrl);
+        const returnUrl = "returnUrl" in options ? options.returnUrl : undefined;
+        return await app._interface.createCheckoutUrl(type, userIdOrTeamId, offerIdOrInline, null, returnUrl);
       },

This makes the code more explicit and type-safe.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69fb515 and 5d7547f.

📒 Files selected for processing (12)
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts (2 hunks)
  • apps/backend/src/route-handlers/smart-response.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx (1 hunks)
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx (4 hunks)
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx (4 hunks)
  • apps/dashboard/src/components/payments/checkout.tsx (2 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts (2 hunks)
  • apps/e2e/tests/js/payments.test.ts (1 hunks)
  • packages/stack-shared/src/interface/client-interface.ts (2 hunks)
  • packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts (1 hunks)
  • packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts (4 hunks)
  • packages/template/src/lib/stack-app/customers/index.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
{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)/(outside-dashboard)/projects/page-client.tsx
  • apps/dashboard/src/components/payments/checkout.tsx
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Prefer ES6 Map over Record when representing key–value collections

Files:

  • apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/projects/page-client.tsx
  • apps/e2e/tests/js/payments.test.ts
  • apps/dashboard/src/components/payments/checkout.tsx
  • apps/backend/src/route-handlers/smart-response.tsx
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
  • packages/stack-shared/src/interface/client-interface.ts
  • packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
  • packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts
  • packages/template/src/lib/stack-app/customers/index.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts
{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)/(outside-dashboard)/projects/page-client.tsx
  • apps/dashboard/src/components/payments/checkout.tsx
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
**/*.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/js/payments.test.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts
packages/template/**

📄 CodeRabbit inference engine (AGENTS.md)

When modifying the SDK copies, make changes in packages/template (source of truth)

Files:

  • packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts
  • packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts
  • packages/template/src/lib/stack-app/customers/index.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/create-purchase-url/route.ts
🧬 Code graph analysis (3)
apps/e2e/tests/js/payments.test.ts (2)
apps/e2e/tests/helpers.ts (1)
  • it (11-11)
apps/e2e/tests/js/js-helpers.ts (1)
  • createApp (41-86)
packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts (2)
packages/template/src/lib/stack-app/customers/index.ts (2)
  • Customer (35-49)
  • InlineOffer (5-5)
packages/template/src/lib/stack-app/apps/implementations/common.ts (1)
  • useAsyncCache (146-191)
apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts (1)
packages/stack-shared/src/schema-fields.ts (1)
  • yupString (187-190)
⏰ 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). (10)
  • GitHub Check: sync
  • GitHub Check: Vercel Agent Review
  • GitHub Check: setup-tests
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: docker
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: Security Check
🔇 Additional comments (10)
apps/dashboard/src/components/payments/checkout.tsx (2)

24-28: LGTM!

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


43-48: Verify returnUrl is properly validated upstream
The returnUrl query parameter is appended directly to the Stripe return URL, which can enable open‐redirect attacks. Confirm that returnUrl is validated or restricted (e.g., against a whitelist of allowed origins) before being used here.

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

13-13: LGTM!

Correctly imports useSearchParams from Next.js navigation to read query parameters.


37-37: LGTM!

Correctly extracts the return_url query parameter. The value will be string | null, which is appropriately handled downstream.


144-148: Correctly propagates returnUrl to bypass flow.

The bypass URL construction correctly includes the return_url parameter when present, and the dependency array is properly updated to include returnUrl. However, ensure the same validation concerns noted in the checkout component are addressed.


290-290: LGTM!

Correctly converts null to undefined and passes returnUrl to CheckoutForm.

packages/template/src/lib/stack-app/customers/index.ts (1)

40-41: LGTM!

The type signature correctly adds the optional returnUrl parameter to both the offerId branch and the server-only InlineOffer branch, maintaining backward compatibility.

packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts (3)

27-27: LGTM!

Correctly imports Customer type to support the new helper's return type signature.


677-677: LGTM!

Successfully refactored to use the centralized _createServerCustomer helper, reducing code duplication while maintaining the same functionality.


793-793: LGTM!

Successfully refactored to use the centralized _createServerCustomer helper for team customers, consistent with the user implementation.

@zeropath-ai
Copy link

zeropath-ai bot commented Oct 3, 2025

Some new issue(s) might be present. Please use the following link(s) to view them:

Additionally, the following low severity issue(s) were found:

https://zeropath.com/app/issues/220cd9dd-def4-4d52-a5a9-91a7e5738fbd

Reply to this PR with @zeropath-ai followed by a description of what change you want and we'll auto-submit a change to this PR to implement it.

@BilalG1 BilalG1 changed the title Checkout return url Payments return url Oct 3, 2025
Copy link
Contributor

@N2D4 N2D4 left a comment

Choose a reason for hiding this comment

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

some important comments

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b22580a and 259529b.

📒 Files selected for processing (6)
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts (3 hunks)
  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts (4 hunks)
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx (6 hunks)
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx (4 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts (2 hunks)
  • apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/backend/src/app/api/latest/payments/purchases/create-purchase-url/route.ts
🧰 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/validate-code.test.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.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/validate-code.test.ts
  • apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts
  • apps/dashboard/src/app/(main)/purchase/return/page-client.tsx
  • apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
{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)/purchase/return/page-client.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.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)/purchase/return/page-client.tsx
  • apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx
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
🧬 Code graph analysis (5)
apps/e2e/tests/backend/endpoints/api/v1/payments/validate-code.test.ts (1)
apps/e2e/tests/backend/backend-helpers.ts (1)
  • niceBackendFetch (107-171)
apps/e2e/tests/backend/endpoints/api/v1/payments/create-purchase-url.test.ts (2)
apps/e2e/tests/helpers.ts (1)
  • it (11-11)
apps/e2e/tests/backend/backend-helpers.ts (1)
  • niceBackendFetch (107-171)
apps/dashboard/src/app/(main)/purchase/return/page-client.tsx (3)
apps/dashboard/src/lib/env.tsx (1)
  • getPublicEnvVar (49-59)
packages/stack-shared/src/utils/errors.tsx (1)
  • throwErr (10-19)
packages/stack-shared/src/utils/promises.tsx (1)
  • runAsynchronously (343-366)
apps/backend/src/app/api/latest/payments/purchases/validate-code/route.ts (4)
packages/stack-shared/src/schema-fields.ts (2)
  • urlSchema (334-342)
  • yupString (187-190)
apps/backend/src/lib/redirect-urls.tsx (1)
  • validateRedirectUrl (69-85)
packages/stack-shared/src/known-errors.tsx (2)
  • KnownErrors (1570-1572)
  • KnownErrors (1574-1696)
apps/backend/src/lib/tenancies.tsx (1)
  • getTenancy (68-77)
apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx (1)
packages/template/src/lib/stack-app/apps/implementations/client-app-impl.ts (1)
  • useUser (1558-1600)
⏰ 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). (10)
  • GitHub Check: Vercel Agent Review
  • GitHub Check: build (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: setup-tests
  • GitHub Check: docker
  • GitHub Check: docker
  • GitHub Check: all-good
  • GitHub Check: lint_and_build (latest)
  • GitHub Check: restart-dev-and-test
  • GitHub Check: Security Check

@BilalG1 BilalG1 merged commit 3400f32 into dev Oct 6, 2025
19 checks passed
@BilalG1 BilalG1 deleted the payments-redirect-url branch October 6, 2025 21:34
@coderabbitai coderabbitai bot mentioned this pull request Nov 5, 2025
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.

2 participants