Files
computer/api/create-payment-intent.ts
zeekay 6d6cdb2483 feat: Extract zoo.computer from monorepo
Extracted from zoo monorepo for independent deployment.

Domain: computer.zoo.ngo
Deployment: GitHub Pages (GitHub Actions)
App Directory: computer
2025-11-02 10:41:38 -08:00

71 lines
1.7 KiB
TypeScript

import Stripe from 'stripe';
import type { VercelRequest, VercelResponse } from '@vercel/node';
// Initialize Stripe with secret key
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', {
apiVersion: '2024-12-18.acacia',
});
// CORS headers
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
};
export default async function handler(
req: VercelRequest,
res: VercelResponse
) {
// Handle CORS preflight
if (req.method === 'OPTIONS') {
return res.status(200).setHeaders(corsHeaders).end();
}
if (req.method !== 'POST') {
return res
.status(405)
.setHeaders(corsHeaders)
.json({ error: 'Method not allowed' });
}
try {
const { amount, currency = 'usd', metadata = {} } = req.body;
// Validate amount
if (!amount || amount <= 0) {
return res
.status(400)
.setHeaders(corsHeaders)
.json({ error: 'Invalid amount' });
}
// Create payment intent
const paymentIntent = await stripe.paymentIntents.create({
amount: Math.round(amount * 100), // Convert to cents
currency,
automatic_payment_methods: {
enabled: true,
},
metadata,
});
return res
.status(200)
.setHeaders(corsHeaders)
.json({
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
});
} catch (error) {
console.error('Error creating payment intent:', error);
return res
.status(500)
.setHeaders(corsHeaders)
.json({
error: 'Failed to create payment intent',
message: error instanceof Error ? error.message : 'Unknown error'
});
}
}