()
| 10 | import { logger } from '@/util/logger' |
| 11 | |
| 12 | export async function POST() { |
| 13 | const session = await getServerSession(authOptions) |
| 14 | if (!session?.user?.id) { |
| 15 | return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) |
| 16 | } |
| 17 | |
| 18 | const userId = session.user.id |
| 19 | |
| 20 | const subscription = await getActiveSubscription({ userId, logger }) |
| 21 | if (!subscription) { |
| 22 | return NextResponse.json( |
| 23 | { error: 'No active subscription found.' }, |
| 24 | { status: 404 }, |
| 25 | ) |
| 26 | } |
| 27 | |
| 28 | try { |
| 29 | await stripeServer.subscriptions.update( |
| 30 | subscription.stripe_subscription_id, |
| 31 | { cancel_at_period_end: true }, |
| 32 | ) |
| 33 | } catch (error: unknown) { |
| 34 | const message = |
| 35 | (error as { raw?: { message?: string } })?.raw?.message || |
| 36 | 'Failed to cancel subscription in Stripe.' |
| 37 | logger.error( |
| 38 | { error: message, userId, subscriptionId: subscription.stripe_subscription_id }, |
| 39 | 'Stripe subscription cancellation failed', |
| 40 | ) |
| 41 | return NextResponse.json({ error: message }, { status: 500 }) |
| 42 | } |
| 43 | |
| 44 | try { |
| 45 | await db |
| 46 | .update(schema.subscription) |
| 47 | .set({ cancel_at_period_end: true, scheduled_tier: null }) |
| 48 | .where( |
| 49 | eq( |
| 50 | schema.subscription.stripe_subscription_id, |
| 51 | subscription.stripe_subscription_id, |
| 52 | ), |
| 53 | ) |
| 54 | } catch (error: unknown) { |
| 55 | const message = error instanceof Error ? error.message : String(error) |
| 56 | logger.error( |
| 57 | { error: message, userId, subscriptionId: subscription.stripe_subscription_id }, |
| 58 | 'Stripe subscription set to cancel but failed to update local DB — data is inconsistent', |
| 59 | ) |
| 60 | return NextResponse.json( |
| 61 | { error: 'Subscription canceled but failed to update records. Please contact support.' }, |
| 62 | { status: 500 }, |
| 63 | ) |
| 64 | } |
| 65 | |
| 66 | logger.info( |
| 67 | { userId, subscriptionId: subscription.stripe_subscription_id }, |
| 68 | 'Subscription set to cancel at period end', |
| 69 | ) |
nothing calls this directly
no test coverage detected