141 lines
3.6 KiB
TypeScript
141 lines
3.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
// Alpha: In-memory payment storage (mock payment gateway)
|
|
const payments: Map<string, {
|
|
id: string;
|
|
type: 'sponsorship' | 'membership_fee';
|
|
amount: number;
|
|
platformFee: number;
|
|
netAmount: number;
|
|
payerId: string;
|
|
payerType: 'sponsor' | 'driver';
|
|
leagueId: string;
|
|
seasonId?: string;
|
|
status: 'pending' | 'completed' | 'failed' | 'refunded';
|
|
createdAt: Date;
|
|
completedAt?: Date;
|
|
}> = new Map();
|
|
|
|
const PLATFORM_FEE_RATE = 0.10;
|
|
|
|
export async function GET(request: NextRequest) {
|
|
const { searchParams } = new URL(request.url);
|
|
const leagueId = searchParams.get('leagueId');
|
|
const payerId = searchParams.get('payerId');
|
|
const type = searchParams.get('type');
|
|
|
|
let results = Array.from(payments.values());
|
|
|
|
if (leagueId) {
|
|
results = results.filter(p => p.leagueId === leagueId);
|
|
}
|
|
if (payerId) {
|
|
results = results.filter(p => p.payerId === payerId);
|
|
}
|
|
if (type) {
|
|
results = results.filter(p => p.type === type);
|
|
}
|
|
|
|
return NextResponse.json({ payments: results });
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const { type, amount, payerId, payerType, leagueId, seasonId } = body;
|
|
|
|
if (!type || !amount || !payerId || !payerType || !leagueId) {
|
|
return NextResponse.json(
|
|
{ error: 'Missing required fields: type, amount, payerId, payerType, leagueId' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
if (!['sponsorship', 'membership_fee'].includes(type)) {
|
|
return NextResponse.json(
|
|
{ error: 'Type must be "sponsorship" or "membership_fee"' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
if (!['sponsor', 'driver'].includes(payerType)) {
|
|
return NextResponse.json(
|
|
{ error: 'PayerType must be "sponsor" or "driver"' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const platformFee = amount * PLATFORM_FEE_RATE;
|
|
const netAmount = amount - platformFee;
|
|
|
|
const id = `payment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
const payment = {
|
|
id,
|
|
type,
|
|
amount,
|
|
platformFee,
|
|
netAmount,
|
|
payerId,
|
|
payerType,
|
|
leagueId,
|
|
seasonId: seasonId || undefined,
|
|
status: 'pending' as const,
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
payments.set(id, payment);
|
|
|
|
return NextResponse.json({ payment }, { status: 201 });
|
|
} catch (err) {
|
|
console.error('Payment creation failed:', err);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to create payment' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
// Complete a payment (mock payment gateway callback)
|
|
export async function PATCH(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const { paymentId, status } = body;
|
|
|
|
if (!paymentId || !status) {
|
|
return NextResponse.json(
|
|
{ error: 'Missing required fields: paymentId, status' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
if (!['completed', 'failed', 'refunded'].includes(status)) {
|
|
return NextResponse.json(
|
|
{ error: 'Status must be "completed", "failed", or "refunded"' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const payment = payments.get(paymentId);
|
|
if (!payment) {
|
|
return NextResponse.json(
|
|
{ error: 'Payment not found' },
|
|
{ status: 404 }
|
|
);
|
|
}
|
|
|
|
payment.status = status;
|
|
if (status === 'completed') {
|
|
payment.completedAt = new Date();
|
|
}
|
|
|
|
payments.set(paymentId, payment);
|
|
|
|
return NextResponse.json({ payment });
|
|
} catch (err) {
|
|
console.error('Payment update failed:', err);
|
|
return NextResponse.json(
|
|
{ error: 'Failed to update payment' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
} |