106 lines
3.4 KiB
TypeScript
106 lines
3.4 KiB
TypeScript
import { type NextRequest, NextResponse } from "next/server"
|
|
import Stripe from "stripe"
|
|
|
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
|
apiVersion: "2024-12-18.acacia",
|
|
})
|
|
|
|
const CCG_TICKET_PRICE_ID = "price_1SbokZ8IwXvKSVJpRvkTqePT"
|
|
const CCG_ACCOMMODATION_PRICE_ID = "price_1Sboq08IwXvKSVJpf8RRSoCy"
|
|
const CCG_FOOD_PRICE_ID = "price_1Sboq18IwXvKSVJpY7NJWaYd"
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const formData = await request.formData()
|
|
const paymentMethod = formData.get("paymentMethod") as string
|
|
const registrationDataStr = formData.get("registrationData") as string
|
|
const packagesStr = formData.get("packages") as string
|
|
|
|
const registrationData = registrationDataStr ? JSON.parse(registrationDataStr) : null
|
|
const packages = packagesStr ? JSON.parse(packagesStr) : { accommodation: false, food: false }
|
|
|
|
const lineItems: Stripe.Checkout.SessionCreateParams.LineItem[] = [
|
|
{
|
|
price: CCG_TICKET_PRICE_ID,
|
|
quantity: 1,
|
|
},
|
|
]
|
|
|
|
if (packages.accommodation) {
|
|
lineItems.push({
|
|
price: CCG_ACCOMMODATION_PRICE_ID,
|
|
quantity: 1,
|
|
})
|
|
}
|
|
|
|
if (packages.food) {
|
|
lineItems.push({
|
|
price: CCG_FOOD_PRICE_ID,
|
|
quantity: 1,
|
|
})
|
|
}
|
|
|
|
let paymentMethodTypes: Stripe.Checkout.SessionCreateParams.PaymentMethodType[] = ["card"]
|
|
|
|
if (paymentMethod === "sepa_debit") {
|
|
paymentMethodTypes = ["sepa_debit"]
|
|
} else if (paymentMethod === "crypto") {
|
|
paymentMethodTypes = ["customer_balance"]
|
|
}
|
|
|
|
const session = await stripe.checkout.sessions.create({
|
|
payment_method_types: paymentMethodTypes,
|
|
line_items: lineItems,
|
|
mode: "payment",
|
|
success_url: `${request.nextUrl.origin}/success?session_id={CHECKOUT_SESSION_ID}`,
|
|
cancel_url: `${request.nextUrl.origin}/register`,
|
|
metadata: registrationData
|
|
? {
|
|
name: registrationData.name,
|
|
contact: registrationData.contact,
|
|
contributions: registrationData.contributions.substring(0, 500),
|
|
expectations: registrationData.expectations.substring(0, 500),
|
|
howHeard: registrationData.howHeard || "",
|
|
dietary:
|
|
registrationData.dietary.join(", ") +
|
|
(registrationData.dietaryOther ? `, ${registrationData.dietaryOther}` : ""),
|
|
crewConsent: registrationData.crewConsent,
|
|
includesAccommodation: packages.accommodation ? "yes" : "no",
|
|
includesFood: packages.food ? "yes" : "no",
|
|
}
|
|
: {},
|
|
...(paymentMethod === "crypto" && {
|
|
payment_method_options: {
|
|
customer_balance: {
|
|
funding_type: "bank_transfer",
|
|
bank_transfer: {
|
|
type: "us_bank_account",
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
allow_promotion_codes: true,
|
|
billing_address_collection: "required",
|
|
phone_number_collection: {
|
|
enabled: true,
|
|
},
|
|
})
|
|
|
|
// Use 303 redirect for POST requests (tells browser to follow with GET)
|
|
return new Response(null, {
|
|
status: 303,
|
|
headers: { Location: session.url! },
|
|
})
|
|
} catch (err) {
|
|
console.error("Error creating checkout session:", err)
|
|
return NextResponse.json({ error: "Error creating checkout session" }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
export async function GET() {
|
|
return NextResponse.json(
|
|
{ message: "This is an API endpoint. Use POST to create a checkout session." },
|
|
{ status: 405 },
|
|
)
|
|
}
|