Files
cbd420/app/api/sales/from-pending-order/route.ts
2025-12-31 07:49:35 +00:00

110 lines
3.4 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import pool from '@/lib/db'
// POST /api/sales/from-pending-order - Create a sale from a pending order (for IPN handlers)
// This endpoint should be called by your IPN/webhook handler when payment is confirmed
// It creates the sale and awards referral points
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const { payment_id } = body
if (!payment_id) {
return NextResponse.json(
{ error: 'Missing required field: payment_id' },
{ status: 400 }
)
}
const connection = await pool.getConnection()
await connection.beginTransaction()
try {
// Find the pending order
const [pendingRows] = await connection.execute(
'SELECT * FROM pending_orders WHERE payment_id = ?',
[payment_id]
)
const pendingOrders = pendingRows as any[]
if (pendingOrders.length === 0) {
await connection.rollback()
connection.release()
return NextResponse.json(
{ error: 'Pending order not found' },
{ status: 404 }
)
}
const pendingOrder = pendingOrders[0]
// Check if sale already exists
const [existingSalesRows] = await connection.execute(
'SELECT id FROM sales WHERE payment_id = ?',
[payment_id]
)
const existingSales = existingSalesRows as any[]
if (existingSales.length > 0) {
// Sale already exists, return it
await connection.commit()
connection.release()
return NextResponse.json({
sale_id: existingSales[0].id,
message: 'Sale already exists',
})
}
// Create the sale from pending order data
const [result] = await connection.execute(
'INSERT INTO sales (drop_id, buyer_id, buyer_data_id, size, payment_id, price_amount, price_currency, points_used) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
[
pendingOrder.drop_id,
pendingOrder.buyer_id,
pendingOrder.buyer_data_id,
pendingOrder.size,
payment_id,
pendingOrder.price_amount,
pendingOrder.price_currency,
pendingOrder.points_used || 0,
]
)
const saleId = (result as any).insertId
// Award referral points to the referrer (if any)
// The stored procedure will:
// 1. Check if the buyer has a referrer
// 2. Calculate points based on purchase amount and points_per_chf setting
// 3. Update the referrer's referral_points balance
// 4. Record the transaction in referral_point_transactions
await connection.execute('CALL award_referral_points(?)', [saleId])
// Delete the pending order (it's now converted to a sale)
await connection.execute(
'DELETE FROM pending_orders WHERE payment_id = ?',
[payment_id]
)
await connection.commit()
connection.release()
return NextResponse.json({
sale_id: saleId,
message: 'Sale created successfully',
}, { status: 201 })
} catch (error) {
await connection.rollback()
connection.release()
throw error
}
} catch (error) {
console.error('Error creating sale from pending order:', error)
return NextResponse.json(
{ error: 'Failed to create sale from pending order' },
{ status: 500 }
)
}
}