From a6a227597ff2824c2475d77e48c137dc1c93034d Mon Sep 17 00:00:00 2001 From: songtianlun Date: Tue, 26 Aug 2025 22:30:44 +0800 Subject: [PATCH] add sub manager log --- src/app/api/subscription/portal/route.ts | 67 ++++++++++++++++++++---- src/app/subscription/page.tsx | 8 ++- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/app/api/subscription/portal/route.ts b/src/app/api/subscription/portal/route.ts index 78ddc78..7f4c110 100644 --- a/src/app/api/subscription/portal/route.ts +++ b/src/app/api/subscription/portal/route.ts @@ -4,37 +4,84 @@ import { createCustomerPortalSession } from '@/lib/stripe' export async function POST() { try { + console.log('🔗 Starting portal session creation...') + + // 检查是否是开发环境 + const isDevelopment = process.env.NODE_ENV === 'development' + if (isDevelopment) { + console.log('⚠️ Development mode: Stripe portal disabled') + return NextResponse.json( + { error: 'Stripe portal is not available in development mode. Please use production environment.' }, + { status: 400 } + ) + } + const supabase = await createServerSupabaseClient() // 获取当前用户 const { data: { user }, error: authError } = await supabase.auth.getUser() if (authError || !user) { + console.log('❌ Auth error:', authError) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } - // 获取用户的Stripe客户ID - const { data: userData, error: userError } = await supabase - .from('users') + console.log('👤 User ID:', user.id) + + // 从订阅记录中获取Stripe客户ID + const { data: subscriptionData, error: subscriptionError } = await supabase + .from('subscriptions') .select('stripeCustomerId') - .eq('id', user.id) + .eq('userId', user.id) + .eq('isActive', true) + .order('createdAt', { ascending: false }) + .limit(1) .single() - if (userError || !userData?.stripeCustomerId) { - return NextResponse.json( - { error: 'No Stripe customer found' }, - { status: 400 } + if (subscriptionError || !subscriptionData?.stripeCustomerId) { + console.log('⚠️ Subscription error or no customer ID:', subscriptionError, subscriptionData) + + // 如果没有活跃订阅,尝试从用户表获取 + const { data: userData, error: userError } = await supabase + .from('users') + .select('stripeCustomerId') + .eq('id', user.id) + .single() + + console.log('📋 User data from users table:', userData, userError) + + if (userError || !userData?.stripeCustomerId) { + console.log('❌ No Stripe customer ID found in either table') + return NextResponse.json( + { error: 'No Stripe customer found. Please create a subscription first.' }, + { status: 400 } + ) + } + + // 使用用户表中的客户ID + const returnUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/subscription` + + const portalSession = await createCustomerPortalSession( + userData.stripeCustomerId, + returnUrl ) + + return NextResponse.json({ + url: portalSession.url + }) } - // 创建客户门户会话 + // 使用订阅记录中的客户ID创建门户会话 + console.log('💳 Using customer ID from subscription:', subscriptionData.stripeCustomerId) const returnUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/subscription` const portalSession = await createCustomerPortalSession( - userData.stripeCustomerId, + subscriptionData.stripeCustomerId, returnUrl ) + console.log('✅ Portal session created successfully:', portalSession.id) + return NextResponse.json({ url: portalSession.url }) diff --git a/src/app/subscription/page.tsx b/src/app/subscription/page.tsx index 689f8b8..b9fa299 100644 --- a/src/app/subscription/page.tsx +++ b/src/app/subscription/page.tsx @@ -154,11 +154,15 @@ export default function SubscriptionPage() { // 重定向到Stripe客户门户 window.location.href = result.url } else { - throw new Error('Failed to create portal session') + const errorData = await response.json() + throw new Error(errorData.error || 'Failed to create portal session') } } catch (error) { console.error('Portal creation failed:', error) - alert('Failed to access billing portal. Please try again.') + const message = error.message.includes('development mode') + ? 'Stripe billing portal is only available in production environment.' + : 'Failed to access billing portal. Please try again.' + alert(message) } finally { setActionLoading(false) }