From e8eafad65050ebdd2d9022158bc36dd325c1b532 Mon Sep 17 00:00:00 2001 From: bender Date: Sat, 14 Mar 2026 16:55:23 +0000 Subject: [PATCH] Add src/app/api/payment/process/route.ts --- src/app/api/payment/process/route.ts | 204 +++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 src/app/api/payment/process/route.ts diff --git a/src/app/api/payment/process/route.ts b/src/app/api/payment/process/route.ts new file mode 100644 index 0000000..8017575 --- /dev/null +++ b/src/app/api/payment/process/route.ts @@ -0,0 +1,204 @@ +import { NextRequest, NextResponse } from 'next/server'; + +interface PaymentRequest { + paymentMethod: string; + cardName: string; + cardNumber: string; + expiryDate: string; + cvv: string; + email: string; + phone: string; + amount: number; + currency: string; + items: Array<{ + id: string; + name: string; + price: string; + quantity: number; + }>; + orderDetails: { + subtotal: string; + tax: string; + total: string; + }; +} + +interface PaymentResponse { + success: boolean; + transactionId?: string; + message: string; + order?: { + id: string; + amount: number; + currency: string; + status: string; + }; +} + +function validatePaymentData(data: PaymentRequest): { valid: boolean; error?: string } { + if (!data.cardName?.trim()) { + return { valid: false, error: 'Cardholder name is required' }; + } + + const cardNumberDigits = data.cardNumber.replace(/\D/g, ''); + if (!/^\d{13,19}$/.test(cardNumberDigits)) { + return { valid: false, error: 'Invalid card number' }; + } + + if (!/^\d{2}\/\d{2}$/.test(data.expiryDate)) { + return { valid: false, error: 'Invalid expiry date format' }; + } + + if (!/^\d{3,4}$/.test(data.cvv)) { + return { valid: false, error: 'Invalid CVV' }; + } + + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) { + return { valid: false, error: 'Invalid email address' }; + } + + if (!data.phone?.trim()) { + return { valid: false, error: 'Phone number is required' }; + } + + if (data.amount <= 0) { + return { valid: false, error: 'Invalid payment amount' }; + } + + return { valid: true }; +} + +function luhnCheck(cardNumber: string): boolean { + const digits = cardNumber.replace(/\D/g, ''); + let sum = 0; + let isEven = false; + + for (let i = digits.length - 1; i >= 0; i--) { + let digit = parseInt(digits[i], 10); + + if (isEven) { + digit *= 2; + if (digit > 9) { + digit -= 9; + } + } + + sum += digit; + isEven = !isEven; + } + + return sum % 10 === 0; +} + +function generateTransactionId(): string { + return `TXN-${Date.now()}-${Math.random().toString(36).substr(2, 9).toUpperCase()}`; +} + +export async function POST(request: NextRequest): Promise> { + try { + const data: PaymentRequest = await request.json(); + + // Validate payment data + const validation = validatePaymentData(data); + if (!validation.valid) { + return NextResponse.json( + { + success: false, + message: validation.error || 'Validation failed' + }, + { status: 400 } + ); + } + + // Validate card using Luhn algorithm + if (!luhnCheck(data.cardNumber)) { + return NextResponse.json( + { + success: false, + message: 'Invalid card number' + }, + { status: 400 } + ); + } + + // Validate expiry date + const [month, year] = data.expiryDate.split('/'); + const expiryDate = new Date(2000 + parseInt(year), parseInt(month) - 1); + if (expiryDate < new Date()) { + return NextResponse.json( + { + success: false, + message: 'Card has expired' + }, + { status: 400 } + ); + } + + // Validate items and amount + if (!data.items || data.items.length === 0) { + return NextResponse.json( + { + success: false, + message: 'No items in order' + }, + { status: 400 } + ); + } + + // In production, integrate with actual payment gateway here + // This is a mock processing example + const transactionId = generateTransactionId(); + + // Simulate payment processing delay + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Mock fraud check - reject cards ending in 0002 + const lastFourDigits = data.cardNumber.replace(/\D/g, '').slice(-4); + if (lastFourDigits === '0002') { + return NextResponse.json( + { + success: false, + message: 'Payment declined. Please try another card.' + }, + { status: 402 } + ); + } + + // Log order for email notification + console.log('Payment Processing Log:', { + transactionId, + amount: data.amount, + currency: data.currency, + cardLast4: lastFourDigits, + email: data.email, + phone: data.phone, + itemCount: data.items.length, + timestamp: new Date().toISOString() + }); + + return NextResponse.json( + { + success: true, + transactionId, + message: 'Payment processed successfully', + order: { + id: transactionId, + amount: data.amount, + currency: data.currency, + status: 'completed' + } + }, + { status: 200 } + ); + } catch (error) { + console.error('Payment processing error:', error); + + return NextResponse.json( + { + success: false, + message: 'Payment processing failed. Please try again.' + }, + { status: 500 } + ); + } +}