All Docs
FeaturesSidekickUpdated March 11, 2026

Fixing the Billing Redirect 404 in v1.0.27

Fixing the Billing Redirect 404 in v1.0.27

Release: v1.0.27

What Happened

When a user completed or cancelled a Stripe Checkout session, Stripe would redirect them back to Sidekick — but the destination URL (/dashboard/billing) didn't exist as a rendered page in the application. The result was a 404 error immediately after payment, leaving users with no confirmation that their subscription had been activated or that their checkout had been cancelled.

The Root Cause

The Stripe redirect URLs are configured in src/lib/routers/billing.ts inside the createCheckoutSession tRPC mutation:

// src/lib/routers/billing.ts (lines 60 and 76)
success_url: `${baseUrl}/dashboard/billing?success=true`,
cancel_url:  `${baseUrl}/dashboard/billing?canceled=true`,

Both URLs point to /dashboard/billing. However, while the settings page at src/app/dashboard/settings/page.tsx (lines 28–37) renders a "Manage Billing" section with a portal link, no page component existed at the /dashboard/billing path — so Next.js served a 404 for every Stripe redirect.

The Fix

A new page was created at src/app/dashboard/billing/page.tsx to serve as the landing target for Stripe post-payment redirects. It handles two query parameter states:

Query parameterMeaning
?success=trueCheckout completed successfully; subscription is active
?canceled=trueUser cancelled the Stripe Checkout flow

The page reads these parameters and renders the appropriate UI — a success confirmation or a cancellation notice — so users always receive clear feedback after interacting with Stripe.

Impact

  • Before: Every Stripe Checkout completion or cancellation landed on a 404 page.
  • After: Users are redirected to /dashboard/billing and see a contextual confirmation screen matching the outcome of their checkout session.

No Action Required

This fix is applied automatically. Existing billing configurations and Stripe webhook integrations are unaffected. The success_url and cancel_url values in the billing router remain unchanged — the missing page now simply exists to receive them.