110 lines
3.4 KiB
TypeScript
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 }
|
|
)
|
|
}
|
|
}
|
|
|