65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import Stripe from 'stripe';
|
|
|
|
const stripeSecretKey = process.env.STRIPE_SECRET_KEY;
|
|
|
|
const stripe = stripeSecretKey
|
|
? new Stripe(stripeSecretKey, { apiVersion: '2024-06-20' })
|
|
: null;
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
if (!stripe) {
|
|
return NextResponse.json({ error: 'Stripe is not configured.' }, { status: 500 });
|
|
}
|
|
|
|
const body = await request.json();
|
|
const credits = Number(body?.credits);
|
|
const amount = Number(body?.amount);
|
|
const userId = body?.userId as string | undefined;
|
|
|
|
// TODO: Get userId from auth token
|
|
const resolvedUserId = userId ?? 'test-user-id';
|
|
|
|
if (!resolvedUserId || !Number.isFinite(credits) || credits <= 0) {
|
|
return NextResponse.json({ error: 'Invalid checkout payload.' }, { status: 400 });
|
|
}
|
|
|
|
if (!Number.isFinite(amount) || amount <= 0) {
|
|
return NextResponse.json({ error: 'Invalid amount.' }, { status: 400 });
|
|
}
|
|
|
|
const origin = request.headers.get('origin') ?? 'http://localhost:3000';
|
|
|
|
const session = await stripe.checkout.sessions.create({
|
|
mode: 'payment',
|
|
payment_method_types: ['card'],
|
|
line_items: [
|
|
{
|
|
quantity: 1,
|
|
price_data: {
|
|
currency: 'eur',
|
|
unit_amount: amount * 100,
|
|
product_data: {
|
|
name: `${credits} HolaCompi Credits`,
|
|
description: 'Pay-as-you-go voice call credits',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
success_url: `${origin}/dashboard/credits?success=true`,
|
|
cancel_url: `${origin}/dashboard/credits?canceled=true`,
|
|
metadata: {
|
|
userId: resolvedUserId,
|
|
credits: credits.toString(),
|
|
amount: amount.toString(),
|
|
},
|
|
});
|
|
|
|
return NextResponse.json({ sessionId: session.id, url: session.url });
|
|
} catch (error) {
|
|
console.error('Stripe checkout error:', error);
|
|
return NextResponse.json({ error: 'Failed to create checkout session.' }, { status: 500 });
|
|
}
|
|
}
|