finished sub
This commit is contained in:
parent
5b36748048
commit
64e2ad63b8
103
scripts/create-test-subscription.ts
Normal file
103
scripts/create-test-subscription.ts
Normal file
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
async function createTestSubscription() {
|
||||
try {
|
||||
console.log('🧪 Creating test subscription...')
|
||||
|
||||
// 使用真实的数据
|
||||
const subscriptionData = {
|
||||
userId: '9975b2c5-7955-48cf-9594-74b8d9beab25',
|
||||
subscriptionPlanId: 'pro',
|
||||
stripeSubscriptionId: 'sub_1Rt8nRLW0cChKPJ0Osn5UBcV',
|
||||
stripeCustomerId: 'cus_SojwymqWZ4EXlZ',
|
||||
isActive: true,
|
||||
status: 'active',
|
||||
startDate: new Date(1754492307 * 1000), // 2025-08-06T14:58:27.000Z
|
||||
endDate: new Date(1757170707 * 1000), // 2025-09-06T14:58:27.000Z
|
||||
metadata: {
|
||||
test: true,
|
||||
created_by: 'manual_script'
|
||||
}
|
||||
}
|
||||
|
||||
console.log('📊 Creating subscription with data:', subscriptionData)
|
||||
|
||||
// 检查是否已存在
|
||||
const existing = await prisma.subscription.findFirst({
|
||||
where: {
|
||||
stripeSubscriptionId: subscriptionData.stripeSubscriptionId
|
||||
}
|
||||
})
|
||||
|
||||
if (existing) {
|
||||
console.log('⚠️ Subscription already exists:', existing.id)
|
||||
console.log('🗑️ Deleting existing subscription...')
|
||||
await prisma.subscription.delete({
|
||||
where: { id: existing.id }
|
||||
})
|
||||
}
|
||||
|
||||
// 创建新订阅
|
||||
const newSubscription = await prisma.subscription.create({
|
||||
data: subscriptionData
|
||||
})
|
||||
|
||||
console.log('✅ Created subscription:', newSubscription.id)
|
||||
|
||||
// 更新用户的订阅计划
|
||||
await prisma.user.update({
|
||||
where: { id: subscriptionData.userId },
|
||||
data: {
|
||||
subscriptionPlanId: 'pro',
|
||||
subscribePlan: 'pro'
|
||||
}
|
||||
})
|
||||
|
||||
console.log('✅ Updated user subscription plan')
|
||||
|
||||
// 验证创建结果
|
||||
const createdSubscription = await prisma.subscription.findUnique({
|
||||
where: { id: newSubscription.id },
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
email: true,
|
||||
subscriptionPlanId: true,
|
||||
subscribePlan: true
|
||||
}
|
||||
},
|
||||
subscriptionPlan: {
|
||||
select: {
|
||||
name: true,
|
||||
price: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
console.log('📋 Subscription details:')
|
||||
console.log(' ID:', createdSubscription?.id)
|
||||
console.log(' User:', createdSubscription?.user.email)
|
||||
console.log(' Plan:', createdSubscription?.subscriptionPlan.name)
|
||||
console.log(' Price:', `$${createdSubscription?.subscriptionPlan.price}`)
|
||||
console.log(' Status:', createdSubscription?.status)
|
||||
console.log(' Active:', createdSubscription?.isActive)
|
||||
console.log(' Start:', createdSubscription?.startDate)
|
||||
console.log(' End:', createdSubscription?.endDate)
|
||||
console.log(' User Plan ID:', createdSubscription?.user.subscriptionPlanId)
|
||||
console.log(' User Plan:', createdSubscription?.user.subscribePlan)
|
||||
|
||||
console.log('🎉 Test subscription created successfully!')
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error creating test subscription:', error)
|
||||
} finally {
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
createTestSubscription()
|
88
scripts/test-subscription-table.ts
Normal file
88
scripts/test-subscription-table.ts
Normal file
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
async function testSubscriptionTable() {
|
||||
try {
|
||||
console.log('🔍 Testing subscription table...')
|
||||
|
||||
// 测试查询所有订阅
|
||||
const subscriptions = await prisma.subscription.findMany({
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
stripeCustomerId: true
|
||||
}
|
||||
},
|
||||
subscriptionPlan: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
price: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
console.log(`📊 Found ${subscriptions.length} subscriptions:`)
|
||||
subscriptions.forEach((sub, index) => {
|
||||
console.log(`${index + 1}. Subscription ${sub.id}:`)
|
||||
console.log(` - User: ${sub.user.email} (${sub.user.id})`)
|
||||
console.log(` - Plan: ${sub.subscriptionPlan.name} ($${sub.subscriptionPlan.price})`)
|
||||
console.log(` - Status: ${sub.status}`)
|
||||
console.log(` - Active: ${sub.isActive}`)
|
||||
console.log(` - Stripe ID: ${sub.stripeSubscriptionId}`)
|
||||
console.log(` - Start: ${sub.startDate}`)
|
||||
console.log(` - End: ${sub.endDate}`)
|
||||
console.log('')
|
||||
})
|
||||
|
||||
// 测试查询用户
|
||||
const users = await prisma.user.findMany({
|
||||
where: {
|
||||
stripeCustomerId: {
|
||||
not: null
|
||||
}
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
stripeCustomerId: true,
|
||||
subscriptionPlanId: true,
|
||||
subscribePlan: true
|
||||
}
|
||||
})
|
||||
|
||||
console.log(`👥 Found ${users.length} users with Stripe customer IDs:`)
|
||||
users.forEach((user, index) => {
|
||||
console.log(`${index + 1}. ${user.email}:`)
|
||||
console.log(` - User ID: ${user.id}`)
|
||||
console.log(` - Stripe Customer ID: ${user.stripeCustomerId}`)
|
||||
console.log(` - Subscription Plan ID: ${user.subscriptionPlanId}`)
|
||||
console.log(` - Subscribe Plan: ${user.subscribePlan}`)
|
||||
console.log('')
|
||||
})
|
||||
|
||||
// 测试查询订阅套餐
|
||||
const plans = await prisma.subscriptionPlan.findMany()
|
||||
console.log(`📦 Found ${plans.length} subscription plans:`)
|
||||
plans.forEach((plan, index) => {
|
||||
console.log(`${index + 1}. ${plan.name} (${plan.id}):`)
|
||||
console.log(` - Price: $${plan.price}`)
|
||||
console.log(` - Stripe Price ID: ${plan.stripePriceId}`)
|
||||
console.log(` - Active: ${plan.isActive}`)
|
||||
console.log('')
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error testing subscription table:', error)
|
||||
} finally {
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
testSubscriptionTable()
|
232
scripts/test-webhook-data.ts
Normal file
232
scripts/test-webhook-data.ts
Normal file
@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
// 模拟从你的日志中提取的 Stripe 订阅数据
|
||||
const mockSubscriptionData = {
|
||||
"id": "sub_1Rt8nRLW0cChKPJ0Osn5UBcV",
|
||||
"object": "subscription",
|
||||
"application": null,
|
||||
"application_fee_percent": null,
|
||||
"automatic_tax": {
|
||||
"disabled_reason": null,
|
||||
"enabled": false,
|
||||
"liability": null
|
||||
},
|
||||
"billing_cycle_anchor": 1754492307,
|
||||
"billing_cycle_anchor_config": null,
|
||||
"billing_mode": {
|
||||
"type": "classic"
|
||||
},
|
||||
"billing_thresholds": null,
|
||||
"cancel_at": null,
|
||||
"cancel_at_period_end": false,
|
||||
"canceled_at": null,
|
||||
"cancellation_details": {
|
||||
"comment": null,
|
||||
"feedback": null,
|
||||
"reason": null
|
||||
},
|
||||
"collection_method": "charge_automatically",
|
||||
"created": 1754492307,
|
||||
"currency": "usd",
|
||||
"customer": "cus_SojwymqWZ4EXlZ",
|
||||
"days_until_due": null,
|
||||
"default_payment_method": "pm_1Rt8nPLW0cChKPJ0EF0QrEyS",
|
||||
"default_source": null,
|
||||
"default_tax_rates": [],
|
||||
"description": null,
|
||||
"discounts": [],
|
||||
"ended_at": null,
|
||||
"invoice_settings": {
|
||||
"account_tax_ids": null,
|
||||
"issuer": {
|
||||
"type": "self"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
"object": "list",
|
||||
"data": [
|
||||
{
|
||||
"id": "si_SomMVRu4Bpje2r",
|
||||
"object": "subscription_item",
|
||||
"billing_thresholds": null,
|
||||
"created": 1754492308,
|
||||
"current_period_end": 1757170707,
|
||||
"current_period_start": 1754492307,
|
||||
"discounts": [],
|
||||
"metadata": {},
|
||||
"plan": {
|
||||
"id": "price_1RslfmLW0cChKPJ0VurJSg9I",
|
||||
"object": "plan",
|
||||
"active": true,
|
||||
"amount": 1999,
|
||||
"amount_decimal": "1999",
|
||||
"billing_scheme": "per_unit",
|
||||
"created": 1754403422,
|
||||
"currency": "usd",
|
||||
"interval": "month",
|
||||
"interval_count": 1,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"meter": null,
|
||||
"nickname": null,
|
||||
"product": "prod_SoOSFPRNsYcTF8",
|
||||
"tiers_mode": null,
|
||||
"transform_usage": null,
|
||||
"trial_period_days": null,
|
||||
"usage_type": "licensed"
|
||||
},
|
||||
"price": {
|
||||
"id": "price_1RslfmLW0cChKPJ0VurJSg9I",
|
||||
"object": "price",
|
||||
"active": true,
|
||||
"billing_scheme": "per_unit",
|
||||
"created": 1754403422,
|
||||
"currency": "usd",
|
||||
"custom_unit_amount": null,
|
||||
"livemode": false,
|
||||
"lookup_key": null,
|
||||
"metadata": {},
|
||||
"nickname": null,
|
||||
"product": "prod_SoOSFPRNsYcTF8",
|
||||
"recurring": {
|
||||
"interval": "month",
|
||||
"interval_count": 1,
|
||||
"meter": null,
|
||||
"trial_period_days": null,
|
||||
"usage_type": "licensed"
|
||||
},
|
||||
"tax_behavior": "inclusive",
|
||||
"tiers_mode": null,
|
||||
"transform_quantity": null,
|
||||
"type": "recurring",
|
||||
"unit_amount": 1999,
|
||||
"unit_amount_decimal": "1999"
|
||||
},
|
||||
"quantity": 1,
|
||||
"subscription": "sub_1Rt8nRLW0cChKPJ0Osn5UBcV",
|
||||
"tax_rates": []
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"total_count": 1,
|
||||
"url": "/v1/subscription_items?subscription=sub_1Rt8nRLW0cChKPJ0Osn5UBcV"
|
||||
},
|
||||
"latest_invoice": "in_1Rt8nPLW0cChKPJ0YOG0OCof",
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"next_pending_invoice_item_invoice": null,
|
||||
"on_behalf_of": null,
|
||||
"pause_collection": null,
|
||||
"payment_settings": {
|
||||
"payment_method_options": {
|
||||
"acss_debit": null,
|
||||
"bancontact": null,
|
||||
"card": {
|
||||
"network": null,
|
||||
"request_three_d_secure": "automatic"
|
||||
},
|
||||
"customer_balance": null,
|
||||
"konbini": null,
|
||||
"sepa_debit": null,
|
||||
"us_bank_account": null
|
||||
},
|
||||
"payment_method_types": [
|
||||
"card"
|
||||
],
|
||||
"save_default_payment_method": "off"
|
||||
},
|
||||
"pending_invoice_item_interval": null,
|
||||
"pending_setup_intent": null,
|
||||
"pending_update": null,
|
||||
"plan": {
|
||||
"id": "price_1RslfmLW0cChKPJ0VurJSg9I",
|
||||
"object": "plan",
|
||||
"active": true,
|
||||
"amount": 1999,
|
||||
"amount_decimal": "1999",
|
||||
"billing_scheme": "per_unit",
|
||||
"created": 1754403422,
|
||||
"currency": "usd",
|
||||
"interval": "month",
|
||||
"interval_count": 1,
|
||||
"livemode": false,
|
||||
"metadata": {},
|
||||
"meter": null,
|
||||
"nickname": null,
|
||||
"product": "prod_SoOSFPRNsYcTF8",
|
||||
"tiers_mode": null,
|
||||
"transform_usage": null,
|
||||
"trial_period_days": null,
|
||||
"usage_type": "licensed"
|
||||
},
|
||||
"quantity": 1,
|
||||
"schedule": null,
|
||||
"start_date": 1754492307,
|
||||
"status": "active",
|
||||
"test_clock": null,
|
||||
"transfer_data": null,
|
||||
"trial_end": null,
|
||||
"trial_settings": {
|
||||
"end_behavior": {
|
||||
"missing_payment_method": "create_invoice"
|
||||
}
|
||||
},
|
||||
"trial_start": null
|
||||
}
|
||||
|
||||
function testWebhookData() {
|
||||
console.log('🔍 Testing webhook data extraction...')
|
||||
|
||||
const subscription = mockSubscriptionData as any
|
||||
|
||||
console.log('📊 Subscription object keys:', Object.keys(subscription))
|
||||
|
||||
// 测试当前的提取逻辑
|
||||
const customerId = subscription.customer as string
|
||||
const status = subscription.status as string
|
||||
const stripeSubscriptionId = subscription.id as string
|
||||
const items = subscription.items as { data: Array<{ price: { id: string } }> }
|
||||
const priceId = items?.data[0]?.price?.id
|
||||
const currentPeriodStart = subscription.current_period_start as number
|
||||
const currentPeriodEnd = subscription.current_period_end as number
|
||||
|
||||
console.log('🎯 Extracted data (current logic):')
|
||||
console.log(' customerId:', customerId)
|
||||
console.log(' status:', status)
|
||||
console.log(' stripeSubscriptionId:', stripeSubscriptionId)
|
||||
console.log(' priceId:', priceId)
|
||||
console.log(' currentPeriodStart:', currentPeriodStart)
|
||||
console.log(' currentPeriodEnd:', currentPeriodEnd)
|
||||
|
||||
// 检查日期是否有效
|
||||
if (currentPeriodStart) {
|
||||
const startDate = new Date(currentPeriodStart * 1000)
|
||||
console.log(' startDate:', startDate.toISOString())
|
||||
} else {
|
||||
console.log(' ❌ currentPeriodStart is undefined/null')
|
||||
}
|
||||
|
||||
if (currentPeriodEnd) {
|
||||
const endDate = new Date(currentPeriodEnd * 1000)
|
||||
console.log(' endDate:', endDate.toISOString())
|
||||
} else {
|
||||
console.log(' ❌ currentPeriodEnd is undefined/null')
|
||||
}
|
||||
|
||||
// 检查替代的日期字段
|
||||
console.log('\n🔍 Looking for alternative date fields:')
|
||||
console.log(' start_date:', subscription.start_date)
|
||||
console.log(' created:', subscription.created)
|
||||
console.log(' billing_cycle_anchor:', subscription.billing_cycle_anchor)
|
||||
|
||||
// 检查 items 中的日期
|
||||
if (subscription.items?.data?.[0]) {
|
||||
const item = subscription.items.data[0]
|
||||
console.log(' item.current_period_start:', item.current_period_start)
|
||||
console.log(' item.current_period_end:', item.current_period_end)
|
||||
}
|
||||
|
||||
console.log('\n✅ Analysis complete!')
|
||||
}
|
||||
|
||||
testWebhookData()
|
111
scripts/test-webhook-fix.ts
Normal file
111
scripts/test-webhook-fix.ts
Normal file
@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
// 模拟修复后的 webhook 处理逻辑
|
||||
async function testWebhookFix() {
|
||||
try {
|
||||
console.log('🧪 Testing webhook fix...')
|
||||
|
||||
// 模拟 Stripe 订阅数据
|
||||
const mockSubscription = {
|
||||
id: "sub_1Rt8nRLW0cChKPJ0Osn5UBcV",
|
||||
customer: "cus_SojwymqWZ4EXlZ",
|
||||
status: "active",
|
||||
start_date: 1754492307,
|
||||
items: {
|
||||
data: [{
|
||||
price: { id: "price_1RslfmLW0cChKPJ0VurJSg9I" },
|
||||
current_period_start: 1754492307,
|
||||
current_period_end: 1757170707
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
// 提取数据(使用修复后的逻辑)
|
||||
const customerId = mockSubscription.customer
|
||||
const status = mockSubscription.status
|
||||
const stripeSubscriptionId = mockSubscription.id
|
||||
const items = mockSubscription.items
|
||||
const priceId = items?.data[0]?.price?.id
|
||||
const currentPeriodStart = items?.data[0]?.current_period_start || mockSubscription.start_date
|
||||
const currentPeriodEnd = items?.data[0]?.current_period_end || (mockSubscription.start_date + 30 * 24 * 60 * 60)
|
||||
|
||||
console.log('📊 Extracted data:')
|
||||
console.log(' customerId:', customerId)
|
||||
console.log(' status:', status)
|
||||
console.log(' stripeSubscriptionId:', stripeSubscriptionId)
|
||||
console.log(' priceId:', priceId)
|
||||
console.log(' currentPeriodStart:', currentPeriodStart)
|
||||
console.log(' currentPeriodEnd:', currentPeriodEnd)
|
||||
|
||||
// 验证日期
|
||||
if (!currentPeriodStart || !currentPeriodEnd) {
|
||||
console.error('❌ Missing period dates')
|
||||
return
|
||||
}
|
||||
|
||||
const startDate = new Date(currentPeriodStart * 1000)
|
||||
const endDate = new Date(currentPeriodEnd * 1000)
|
||||
|
||||
console.log('📅 Converted dates:')
|
||||
console.log(' startDate:', startDate.toISOString())
|
||||
console.log(' endDate:', endDate.toISOString())
|
||||
|
||||
// 检查日期是否有效
|
||||
if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
|
||||
console.error('❌ Invalid dates')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('✅ Dates are valid!')
|
||||
|
||||
// 查找用户
|
||||
const user = await prisma.user.findFirst({
|
||||
where: { stripeCustomerId: customerId }
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
console.error('❌ User not found for customer:', customerId)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('👤 Found user:', user.email)
|
||||
|
||||
// 查找套餐
|
||||
const plan = await prisma.subscriptionPlan.findFirst({
|
||||
where: { stripePriceId: priceId }
|
||||
})
|
||||
|
||||
if (!plan) {
|
||||
console.error('❌ Plan not found for price:', priceId)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('📦 Found plan:', plan.name)
|
||||
|
||||
// 模拟创建订阅记录
|
||||
console.log('🔄 Would create subscription with data:')
|
||||
console.log({
|
||||
userId: user.id,
|
||||
subscriptionPlanId: plan.id,
|
||||
stripeSubscriptionId,
|
||||
stripeCustomerId: customerId,
|
||||
isActive: true,
|
||||
status: 'active',
|
||||
startDate,
|
||||
endDate,
|
||||
})
|
||||
|
||||
console.log('✅ Webhook fix test completed successfully!')
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error testing webhook fix:', error)
|
||||
} finally {
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
testWebhookFix()
|
@ -98,20 +98,47 @@ async function handleSubscriptionCreated(subscription: Record<string, unknown>)
|
||||
const customerId = subscription.customer as string
|
||||
const status = subscription.status as string
|
||||
const stripeSubscriptionId = subscription.id as string
|
||||
const items = subscription.items as { data: Array<{ price: { id: string } }> }
|
||||
const items = subscription.items as { data: Array<{
|
||||
price: { id: string }
|
||||
current_period_start: number
|
||||
current_period_end: number
|
||||
}> }
|
||||
const priceId = items?.data[0]?.price?.id
|
||||
const currentPeriodStart = subscription.current_period_start as number
|
||||
const currentPeriodEnd = subscription.current_period_end as number
|
||||
|
||||
// 从 subscription items 中获取周期日期,如果不存在则使用 subscription 的 start_date
|
||||
const currentPeriodStart = items?.data[0]?.current_period_start || subscription.start_date as number
|
||||
const currentPeriodEnd = items?.data[0]?.current_period_end || (subscription.start_date as number + 30 * 24 * 60 * 60) // 默认30天后
|
||||
|
||||
console.log(`📊 New subscription details:`, {
|
||||
customerId,
|
||||
status,
|
||||
stripeSubscriptionId,
|
||||
priceId
|
||||
priceId,
|
||||
currentPeriodStart,
|
||||
currentPeriodEnd
|
||||
})
|
||||
|
||||
// 验证必要的字段
|
||||
if (!customerId || !stripeSubscriptionId || !priceId) {
|
||||
console.error('❌ Missing required subscription data:', {
|
||||
customerId: !!customerId,
|
||||
stripeSubscriptionId: !!stripeSubscriptionId,
|
||||
priceId: !!priceId
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证日期字段
|
||||
if (!currentPeriodStart || !currentPeriodEnd) {
|
||||
console.error('❌ Missing or invalid period dates:', {
|
||||
currentPeriodStart,
|
||||
currentPeriodEnd
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
const user = await prisma.user.findFirst({
|
||||
const user = await (prisma as any).user.findFirst({
|
||||
where: { stripeCustomerId: customerId }
|
||||
})
|
||||
|
||||
@ -126,13 +153,24 @@ async function handleSubscriptionCreated(subscription: Record<string, unknown>)
|
||||
// 根据 Stripe 价格 ID 获取套餐 ID
|
||||
const planId = await SubscriptionService.getPlanIdByStripePriceId(priceId)
|
||||
|
||||
// 创建日期对象,确保有效性
|
||||
const startDate = new Date(currentPeriodStart * 1000)
|
||||
const endDate = new Date(currentPeriodEnd * 1000)
|
||||
|
||||
console.log(`📅 Subscription dates:`, {
|
||||
currentPeriodStart,
|
||||
currentPeriodEnd,
|
||||
startDate: startDate.toISOString(),
|
||||
endDate: endDate.toISOString()
|
||||
})
|
||||
|
||||
// 创建新的订阅记录
|
||||
const newSubscription = await SubscriptionService.createRenewalSubscription(
|
||||
user.id,
|
||||
planId,
|
||||
stripeSubscriptionId,
|
||||
new Date(currentPeriodStart * 1000),
|
||||
new Date(currentPeriodEnd * 1000),
|
||||
startDate,
|
||||
endDate,
|
||||
customerId,
|
||||
subscription
|
||||
)
|
||||
@ -154,10 +192,16 @@ async function handleSubscriptionUpdate(subscription: Record<string, unknown>) {
|
||||
const customerId = subscription.customer as string
|
||||
const status = subscription.status as string
|
||||
const stripeSubscriptionId = subscription.id as string
|
||||
const items = subscription.items as { data: Array<{ price: { id: string } }> }
|
||||
const items = subscription.items as { data: Array<{
|
||||
price: { id: string }
|
||||
current_period_start: number
|
||||
current_period_end: number
|
||||
}> }
|
||||
const priceId = items?.data[0]?.price?.id
|
||||
const currentPeriodStart = subscription.current_period_start as number
|
||||
const currentPeriodEnd = subscription.current_period_end as number
|
||||
|
||||
// 从 subscription items 中获取周期日期
|
||||
const currentPeriodStart = items?.data[0]?.current_period_start || subscription.start_date as number
|
||||
const currentPeriodEnd = items?.data[0]?.current_period_end || (subscription.start_date as number + 30 * 24 * 60 * 60)
|
||||
|
||||
console.log(`📊 Subscription details:`, {
|
||||
customerId,
|
||||
@ -167,7 +211,7 @@ async function handleSubscriptionUpdate(subscription: Record<string, unknown>) {
|
||||
})
|
||||
|
||||
// 查找用户
|
||||
const user = await prisma.user.findFirst({
|
||||
const user = await (prisma as any).user.findFirst({
|
||||
where: { stripeCustomerId: customerId }
|
||||
})
|
||||
|
||||
@ -183,7 +227,7 @@ async function handleSubscriptionUpdate(subscription: Record<string, unknown>) {
|
||||
const planId = await SubscriptionService.getPlanIdByStripePriceId(priceId)
|
||||
|
||||
// 查找现有的订阅记录(通过 Stripe 订阅 ID)
|
||||
const existingSubscription = await prisma.subscription.findFirst({
|
||||
const existingSubscription = await (prisma as any).subscription.findFirst({
|
||||
where: {
|
||||
stripeSubscriptionId,
|
||||
}
|
||||
@ -191,7 +235,7 @@ async function handleSubscriptionUpdate(subscription: Record<string, unknown>) {
|
||||
|
||||
if (existingSubscription) {
|
||||
// 更新现有的订阅记录
|
||||
await prisma.subscription.update({
|
||||
await (prisma as any).subscription.update({
|
||||
where: { id: existingSubscription.id },
|
||||
data: {
|
||||
isActive: true,
|
||||
@ -227,7 +271,7 @@ async function handleSubscriptionDeleted(subscription: Record<string, unknown>)
|
||||
const customerId = subscription.customer as string
|
||||
|
||||
// 查找用户
|
||||
const user = await prisma.user.findFirst({
|
||||
const user = await (prisma as any).user.findFirst({
|
||||
where: { stripeCustomerId: customerId }
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user