feat: implement Stripe checkout integration and add related API endpoints
This commit is contained in:
62
server/api/checkout.session.post.ts
Normal file
62
server/api/checkout.session.post.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import Stripe from 'stripe'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const config = useRuntimeConfig()
|
||||
const stripeSecretKey = config.stripeSecretKey
|
||||
|
||||
if (!stripeSecretKey) {
|
||||
throw createError({ statusCode: 500, statusMessage: 'Stripe secret key not configured' })
|
||||
}
|
||||
|
||||
const stripe = new Stripe(stripeSecretKey, {
|
||||
apiVersion: '2024-10-28.acacia',
|
||||
})
|
||||
|
||||
const body = await readBody<{
|
||||
designId: string
|
||||
templateId?: string
|
||||
designName?: string
|
||||
amount: number
|
||||
currency?: string
|
||||
successUrl: string
|
||||
cancelUrl: string
|
||||
customerEmail?: string
|
||||
}>(event)
|
||||
|
||||
if (!body?.designId || !body?.amount || !body?.successUrl || !body?.cancelUrl) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Missing required fields' })
|
||||
}
|
||||
|
||||
const { currency = 'usd' } = body
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
mode: 'payment',
|
||||
payment_method_types: ['card'],
|
||||
billing_address_collection: 'auto',
|
||||
customer_email: body.customerEmail,
|
||||
line_items: [
|
||||
{
|
||||
quantity: 1,
|
||||
price_data: {
|
||||
currency,
|
||||
unit_amount: Math.round(body.amount * 100),
|
||||
product_data: {
|
||||
name: body.designName ?? `Slipmat design ${body.designId}`,
|
||||
metadata: {
|
||||
designId: body.designId,
|
||||
...(body.templateId ? { templateId: body.templateId } : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
designId: body.designId,
|
||||
...(body.templateId ? { templateId: body.templateId } : {}),
|
||||
},
|
||||
success_url: body.successUrl,
|
||||
cancel_url: body.cancelUrl,
|
||||
})
|
||||
|
||||
return { id: session.id, url: session.url }
|
||||
})
|
||||
36
server/api/transactions.post.ts
Normal file
36
server/api/transactions.post.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody<{
|
||||
stripeSessionId: string
|
||||
designId: string
|
||||
templateId?: string
|
||||
amount: number
|
||||
currency: string
|
||||
customerEmail?: string
|
||||
assets?: {
|
||||
previewUrl?: string
|
||||
productionUrl?: string
|
||||
}
|
||||
}>(event)
|
||||
|
||||
if (!body?.stripeSessionId || !body?.designId) {
|
||||
throw createError({ statusCode: 400, statusMessage: 'Missing required fields' })
|
||||
}
|
||||
|
||||
// TODO: Persist the transaction to your database of choice.
|
||||
// Example shape:
|
||||
// await db.transaction.create({
|
||||
// stripeSessionId: body.stripeSessionId,
|
||||
// designId: body.designId,
|
||||
// templateId: body.templateId,
|
||||
// amount: body.amount,
|
||||
// currency: body.currency,
|
||||
// customerEmail: body.customerEmail,
|
||||
// previewUrl: body.assets?.previewUrl,
|
||||
// productionUrl: body.assets?.productionUrl,
|
||||
// })
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
receivedAt: new Date().toISOString(),
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user