53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { stripeClient } from "../../../../lib/stripeClient";
|
|
|
|
export async function POST(req: Request) {
|
|
try {
|
|
const body = await req.json();
|
|
const accountId = body.accountId as string;
|
|
const priceId = body.priceId as string;
|
|
|
|
if (!accountId || !priceId) {
|
|
return NextResponse.json(
|
|
{ error: "accountId and priceId are required." },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Retrieve the price on the connected account to prevent client-side tampering.
|
|
const price = await stripeClient.prices.retrieve(
|
|
priceId,
|
|
{},
|
|
{ stripeAccount: accountId }
|
|
);
|
|
|
|
if (!price.unit_amount || !price.currency) {
|
|
return NextResponse.json(
|
|
{ error: "Price is missing unit_amount or currency." },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
// Direct charge on the connected account with an application fee.
|
|
const intent = await stripeClient.paymentIntents.create(
|
|
{
|
|
amount: price.unit_amount,
|
|
currency: price.currency,
|
|
automatic_payment_methods: { enabled: true },
|
|
application_fee_amount: Math.max(50, Math.floor(price.unit_amount * 0.1)),
|
|
},
|
|
{
|
|
stripeAccount: accountId,
|
|
}
|
|
);
|
|
|
|
return NextResponse.json({ clientSecret: intent.client_secret });
|
|
} catch (err: any) {
|
|
return NextResponse.json(
|
|
{ error: err?.message || "Failed to create payment intent." },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|