race condition fixed, payment inside
This commit is contained in:
81
app/api/payments/cancel-pending/route.ts
Normal file
81
app/api/payments/cancel-pending/route.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { cookies } from 'next/headers'
|
||||
import pool from '@/lib/db'
|
||||
|
||||
// DELETE /api/payments/cancel-pending - Cancel a pending order (frees up inventory)
|
||||
export async function DELETE(request: NextRequest) {
|
||||
try {
|
||||
// Get buyer_id from session cookie
|
||||
const cookieStore = await cookies()
|
||||
const buyerIdCookie = cookieStore.get('buyer_id')?.value
|
||||
|
||||
if (!buyerIdCookie) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Authentication required' },
|
||||
{ status: 401 }
|
||||
)
|
||||
}
|
||||
|
||||
const buyer_id = parseInt(buyerIdCookie, 10)
|
||||
|
||||
const body = await request.json()
|
||||
const { payment_id } = body
|
||||
|
||||
// Validate required fields
|
||||
if (!payment_id) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Missing required field: payment_id' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// Find the pending order
|
||||
const [pendingRows] = await pool.execute(
|
||||
'SELECT * FROM pending_orders WHERE payment_id = ? AND buyer_id = ?',
|
||||
[payment_id, buyer_id]
|
||||
)
|
||||
|
||||
const pendingOrders = pendingRows as any[]
|
||||
if (pendingOrders.length === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Pending order not found or already cancelled' },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
const pendingOrder = pendingOrders[0]
|
||||
|
||||
// Check if payment has already been confirmed (sale exists)
|
||||
const [salesRows] = await pool.execute(
|
||||
'SELECT * FROM sales WHERE payment_id = ?',
|
||||
[payment_id]
|
||||
)
|
||||
const sales = salesRows as any[]
|
||||
if (sales.length > 0) {
|
||||
// Payment already confirmed, don't delete pending order
|
||||
// The IPN handler should have already deleted it, but if not, leave it
|
||||
return NextResponse.json(
|
||||
{ error: 'Payment already confirmed. Cannot cancel.' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
// Delete the pending order (frees up inventory)
|
||||
await pool.execute(
|
||||
'DELETE FROM pending_orders WHERE payment_id = ? AND buyer_id = ?',
|
||||
[payment_id, buyer_id]
|
||||
)
|
||||
|
||||
return NextResponse.json({
|
||||
message: 'Pending order cancelled successfully',
|
||||
payment_id: payment_id,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error cancelling pending order:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to cancel pending order' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user