Fix: Broken Stripe Redirect URLs in Billing Router (v1.0.24)
Fix: Broken Stripe Redirect URLs in Billing Router (v1.0.24)
What Happened
In versions prior to 1.0.24, Stripe checkout sessions and billing portal sessions could be created with broken redirect URLs — for example:
undefined/dashboard/billing?success=true
undefined/dashboard/billing?canceled=true
This caused users to land on a non-existent page after completing (or cancelling) a Stripe payment, and could also cause Stripe to reject the session entirely depending on its URL validation.
Root Cause
The billing router (src/lib/routers/billing.ts) uses process.env.NEXT_PUBLIC_APP_URL to construct three Stripe redirect URLs:
| Stripe Parameter | Used In | Expected Value Example |
|---|---|---|
success_url | Checkout session creation (~line 41) | https://your-app.vercel.app/dashboard/billing?success=true |
cancel_url | Checkout session creation (~line 44) | https://your-app.vercel.app/dashboard/billing?canceled=true |
return_url | Billing portal session creation (~line 70) | https://your-app.vercel.app/dashboard/billing |
NEXT_PUBLIC_APP_URL was not listed in .env.example, so developers setting up a new environment had no indication this variable was required. When omitted, process.env.NEXT_PUBLIC_APP_URL evaluates to undefined at runtime, and JavaScript string interpolation silently produces the literal string "undefined" as the URL prefix.
The Fix
NEXT_PUBLIC_APP_URL has been added to .env.example:
# Used for Stripe checkout redirect URLs (success_url, cancel_url, portal return_url)
# Should match NEXTAUTH_URL in all deployment environments
NEXT_PUBLIC_APP_URL=https://your-app.vercel.app
How to Resolve This in Your Environment
If your Stripe redirects are broken, follow the steps below.
1. Local Development
Add the following to your .env.local file:
NEXT_PUBLIC_APP_URL=http://localhost:3000
2. Production / Staging (Vercel)
In your Vercel project settings, add an environment variable:
Name: NEXT_PUBLIC_APP_URL
Value: https://your-app.vercel.app
Replace https://your-app.vercel.app with your actual deployment URL (e.g. a custom domain if configured).
3. Other Hosting Providers
Set the variable in whatever mechanism your provider uses for environment configuration (e.g. a .env file, a secrets manager, or a CI/CD pipeline secret).
Note:
NEXT_PUBLIC_APP_URLshould always equalNEXTAUTH_URL. They both represent the canonical public URL of your application.
Verification
After setting the variable, test the Stripe billing flow end-to-end:
- Trigger a checkout session and confirm you are redirected to
<your-app-url>/dashboard/billing?success=trueon completion. - Cancel a checkout session and confirm you land on
<your-app-url>/dashboard/billing?canceled=true. - Open the billing portal and confirm the Return to app link brings you back to
<your-app-url>/dashboard/billing.
If any URL still contains the literal string undefined, the environment variable is not being picked up — restart your development server or redeploy to ensure the new variable is loaded.
Affected Versions
| Version | Status |
|---|---|
| < 1.0.24 | ⚠️ Affected — manual env var configuration required |
| ≥ 1.0.24 | ✅ .env.example documents the required variable |