feat: implement background payment sync worker and admin trigger UI
This commit is contained in:
@@ -11,6 +11,7 @@ import { format } from 'date-fns';
|
||||
import { tr } from 'date-fns/locale';
|
||||
import TransactionSearch from '@/components/admin/TransactionSearch';
|
||||
import TransactionStatusFilter from '@/components/admin/TransactionStatusFilter';
|
||||
import SyncPaymentsButton from '@/components/admin/SyncPaymentsButton';
|
||||
|
||||
async function getTransactions(filters: { merchant_id?: string; q?: string; status?: string }) {
|
||||
let sql = `
|
||||
@@ -71,6 +72,8 @@ export default async function TransactionsPage(props: {
|
||||
<div className="flex items-center gap-4 flex-1">
|
||||
<TransactionSearch />
|
||||
<TransactionStatusFilter />
|
||||
<div className="h-8 w-px bg-gray-100 mx-2"></div>
|
||||
<SyncPaymentsButton />
|
||||
</div>
|
||||
|
||||
<button className="flex items-center justify-center gap-2 px-6 py-3 bg-gray-900 text-white rounded-2xl text-sm font-bold hover:bg-gray-800 transition shadow-lg shadow-gray-200">
|
||||
|
||||
22
app/api/admin/sync-payments/route.ts
Normal file
22
app/api/admin/sync-payments/route.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
import { NextResponse } from 'next/server';
|
||||
import { syncPendingPayments } from '@/lib/sync-worker';
|
||||
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
// Authenticate admin (simple check for now, can be hardened)
|
||||
// In a real app, check session or API key
|
||||
|
||||
const results = await syncPendingPayments();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Sync completed",
|
||||
processedCount: results.length,
|
||||
results: results
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error('[Sync API Error]:', error.message);
|
||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
30
app/api/transactions/[id]/intent/route.ts
Normal file
30
app/api/transactions/[id]/intent/route.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { db } from '@/lib/db';
|
||||
|
||||
export async function POST(
|
||||
req: NextRequest,
|
||||
context: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const { id } = await context.params;
|
||||
const { network, token } = await req.json();
|
||||
|
||||
if (!id || !network || !token) {
|
||||
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
|
||||
}
|
||||
|
||||
// Update metadata with intent
|
||||
// Using jsonb_set to merge or set properly
|
||||
await db.query(`
|
||||
UPDATE transactions
|
||||
SET metadata = metadata || jsonb_build_object('intent_network', $2::text, 'intent_token', $3::text)
|
||||
WHERE id = $1
|
||||
`, [id, network, token]);
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
} catch (error: any) {
|
||||
console.error("[Intent Update Error]:", error.message);
|
||||
return NextResponse.json({ error: error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user