route.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import { NextRequest, NextResponse } from 'next/server';
  2. import { stripe } from '@/lib/stripe';
  3. import { db } from '@/lib/db';
  4. import { users, userActivities } from '@/lib/schema';
  5. import { eq, and, like } from 'drizzle-orm';
  6. export async function GET(request: NextRequest) {
  7. try {
  8. const { searchParams } = new URL(request.url);
  9. const sessionId = searchParams.get('session_id');
  10. if (!sessionId) {
  11. return NextResponse.json(
  12. { error: '缺少会话ID' },
  13. { status: 400 }
  14. );
  15. }
  16. // 获取 Stripe 会话信息
  17. const session = await stripe.checkout.sessions.retrieve(sessionId);
  18. if (!session) {
  19. return NextResponse.json(
  20. { error: '无效的会话ID' },
  21. { status: 404 }
  22. );
  23. }
  24. // 检查支付状态
  25. if (session.payment_status !== 'paid') {
  26. return NextResponse.json(
  27. { error: '支付未完成' },
  28. { status: 400 }
  29. );
  30. }
  31. const userId = session.metadata?.userId;
  32. if (!userId) {
  33. return NextResponse.json(
  34. { error: '用户ID缺失' },
  35. { status: 400 }
  36. );
  37. }
  38. // 获取用户信息
  39. const user = await db.query.users.findFirst({
  40. where: eq(users.id, userId),
  41. });
  42. if (!user) {
  43. return NextResponse.json(
  44. { error: '用户不存在' },
  45. { status: 404 }
  46. );
  47. }
  48. // 检查是否已经处理过此订阅 - 修改检查逻辑
  49. const existingActivity = await db.query.userActivities.findFirst({
  50. where: and(
  51. eq(userActivities.userId, userId),
  52. like(userActivities.metadata, `%"sessionId":"${sessionId}"%`)
  53. ),
  54. });
  55. if (!existingActivity) {
  56. const credits = parseInt(session.metadata?.credits || '800');
  57. const planType = session.metadata?.planType || 'subscription';
  58. // 检查用户是否已经有活跃的订阅
  59. if (planType === 'subscription') {
  60. const hasActiveSubscription = user.subscriptionStatus === 'active' &&
  61. user.subscriptionEndDate &&
  62. new Date(user.subscriptionEndDate) > new Date();
  63. if (hasActiveSubscription) {
  64. return NextResponse.json(
  65. { error: 'alreadySubscribed' },
  66. { status: 400 }
  67. );
  68. }
  69. }
  70. // 计算订阅到期时间(一个月后)
  71. const subscriptionStartDate = new Date();
  72. const subscriptionEndDate = new Date();
  73. subscriptionEndDate.setMonth(subscriptionEndDate.getMonth() + 1);
  74. if (planType === 'subscription') {
  75. // 处理订阅模式:将积分添加到订阅积分字段
  76. await db.update(users)
  77. .set({
  78. subscriptionCredits: credits, // 重置订阅积分
  79. subscriptionStatus: 'active',
  80. subscriptionPlan: 'pro',
  81. subscriptionStartDate: subscriptionStartDate,
  82. subscriptionEndDate: subscriptionEndDate,
  83. stripeCustomerId: typeof session.customer === 'string' ? session.customer : null,
  84. updatedAt: new Date()
  85. })
  86. .where(eq(users.id, userId));
  87. // 记录订阅积分活动 - 使用唯一标识符避免重复
  88. await db.insert(userActivities).values({
  89. userId: userId,
  90. type: 'subscription_activated',
  91. description: 'credit_description.subscription_activated',
  92. creditAmount: credits,
  93. metadata: JSON.stringify({
  94. sessionId,
  95. planType: 'subscription',
  96. planId: 'pro',
  97. subscriptionEndDate: subscriptionEndDate.toISOString(),
  98. source: 'verify-payment-api', // 标识来源
  99. timestamp: new Date().toISOString()
  100. }),
  101. createdAt: new Date(),
  102. });
  103. } else {
  104. // 处理一次性支付:添加到永久积分
  105. await db.update(users)
  106. .set({
  107. credits: user.credits + credits,
  108. updatedAt: new Date()
  109. })
  110. .where(eq(users.id, userId));
  111. // 记录积分活动
  112. await db.insert(userActivities).values({
  113. userId: userId,
  114. type: 'credit_add',
  115. description: 'credit_description.purchase_credits',
  116. creditAmount: credits,
  117. metadata: JSON.stringify({
  118. sessionId,
  119. planType: 'test_payment',
  120. planId: 'pro',
  121. source: 'verify-payment-api', // 标识来源
  122. timestamp: new Date().toISOString()
  123. }),
  124. createdAt: new Date(),
  125. });
  126. }
  127. } else {
  128. console.log(`Session ${sessionId} has already been processed, skipping duplicate processing`);
  129. }
  130. return NextResponse.json({
  131. success: true,
  132. session: {
  133. id: session.id,
  134. amount_total: session.amount_total,
  135. currency: session.currency,
  136. customer_email: session.customer_email,
  137. payment_status: session.payment_status,
  138. }
  139. });
  140. } catch (error: any) {
  141. console.error('Error verifying payment:', error);
  142. return NextResponse.json(
  143. { error: error.message || '验证支付失败' },
  144. { status: 500 }
  145. );
  146. }
  147. }