Refactor: Fully migrated to direct PostgreSQL, implemented Public API v1, fixed Vercel deployment conflicts, and updated documentation
This commit is contained in:
@@ -5,59 +5,110 @@ import { db } from '@/lib/db';
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { txId, merchantAddress, amount, currency } = body;
|
||||
const { txId, network, token } = body;
|
||||
|
||||
console.log(`[API] Checking and Sweeping for Transaction: ${txId}`);
|
||||
|
||||
// This is a demo integration. In a real application:
|
||||
// 1. We would look up the transaction ID from the DB
|
||||
// 2. Fetch the temporary wallet private key created for that specific TX
|
||||
// 3. We use the platform address defined in our .env or settings
|
||||
if (!txId) {
|
||||
return NextResponse.json({ success: false, error: "Transaction ID is required" }, { status: 400 });
|
||||
}
|
||||
|
||||
// For this demo, we'll use the user's devnet wallet as both the source (temp wallet) and platform
|
||||
const demoTempWalletPrivKey = "3Ab6AyfDDWquPJ6ySjHmQmiW3USg7CuDxJSNtrNQySsXj5v4KfBKcw9vnK1Rrfwm6RYq43PdKjiNZekgtNzGsNm2";
|
||||
const platformAddress = "5pLH1tqZhx8p8WpZ18yr28N42KXB3FXVPzZ9ceCtpBVe";
|
||||
|
||||
// Ensure we have a merchant address or use a fallback for testing
|
||||
const targetMerchant = merchantAddress || "5pLH1tqZhx8p8WpZ18yr28N42KXB3FXVPzZ9ceCtpBVe"; // using same for demo
|
||||
|
||||
// Initialize Crypto Engine for Solana
|
||||
const cryptoEngine = new CryptoEngine('SOLANA');
|
||||
const selectedNetwork = network || 'POLYGON';
|
||||
const selectedToken = token || 'USDT';
|
||||
|
||||
console.log("Starting Sweep Process on SOLANA DEVNET...");
|
||||
console.log(`[API] Processing sweep for TX: ${txId} on ${selectedNetwork} with ${selectedToken}`);
|
||||
|
||||
// 1. Fetch the transaction from DB to get the temporary wallet private key
|
||||
const result = await db.query('SELECT * FROM transactions WHERE stripe_pi_id = $1', [txId]);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return NextResponse.json({ success: false, error: "Transaction not found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const transaction = result.rows[0];
|
||||
|
||||
// 1.1 Check if already processed
|
||||
if (transaction.status === 'succeeded') {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Transaction already processed",
|
||||
status: 'succeeded'
|
||||
});
|
||||
}
|
||||
|
||||
const metadata = transaction.metadata || {};
|
||||
const wallets = metadata.wallets || {};
|
||||
|
||||
// 2. Determine which wallet to use (EVM or SOLANA)
|
||||
const walletType = selectedNetwork === 'SOLANA' ? 'SOLANA' : 'EVM';
|
||||
const tempWalletConfig = wallets[walletType];
|
||||
|
||||
if (!tempWalletConfig || !tempWalletConfig.privateKey) {
|
||||
return NextResponse.json({ success: false, error: `No temporary wallet found for ${walletType}` }, { status: 500 });
|
||||
}
|
||||
|
||||
// 3. Define Platform Address (In production, load from env/settings)
|
||||
const platformAddress = selectedNetwork === 'SOLANA'
|
||||
? process.env.SOL_PLATFORM_ADDRESS || "5pLH1tqZhx8p8WpZ18yr28N42KXB3FXVPzZ9ceCtpBVe"
|
||||
: process.env.EVM_PLATFORM_ADDRESS || "0x70997970C51812dc3A010C7d01b50e0d17dc79C8";
|
||||
|
||||
// 4. Define Merchant Address (Fetch from transaction's merchant)
|
||||
const merchantResult = await db.query('SELECT * FROM merchants WHERE id = $1', [transaction.merchant_id]);
|
||||
const merchantAddress = merchantResult.rows[0]?.wallet_address || platformAddress;
|
||||
|
||||
// 5. Initialize Engine and Verify Payment first
|
||||
const cryptoEngine = new CryptoEngine(selectedNetwork);
|
||||
|
||||
// Attempt the sweep (this will do a real devnet transaction if uncommented in engine)
|
||||
const verification = await cryptoEngine.verifyPayment(
|
||||
tempWalletConfig.address,
|
||||
transaction.amount.toString(),
|
||||
selectedToken
|
||||
);
|
||||
|
||||
if (!verification.success) {
|
||||
return NextResponse.json({
|
||||
success: false,
|
||||
error: "Henüz ödeme algılanmadı (On-chain bakiye yetersiz)",
|
||||
status: 'waiting'
|
||||
});
|
||||
}
|
||||
|
||||
// 6. Proceed to Sweep
|
||||
const sweepResult = await cryptoEngine.sweepFunds(
|
||||
demoTempWalletPrivKey,
|
||||
targetMerchant,
|
||||
tempWalletConfig.privateKey,
|
||||
merchantAddress,
|
||||
platformAddress,
|
||||
'SOL' // Using native SOL for demo
|
||||
selectedToken
|
||||
);
|
||||
|
||||
if (!sweepResult.success) {
|
||||
throw new Error("Süpürme işlemi başarısız oldu.");
|
||||
}
|
||||
|
||||
// --- UPDATE DATABASE STATUS ---
|
||||
// Marks the transaction as succeeded so it updates in the Admin dashboard
|
||||
try {
|
||||
await db.query(
|
||||
`UPDATE transactions
|
||||
SET status = 'succeeded'
|
||||
WHERE stripe_pi_id = $1`,
|
||||
[txId]
|
||||
);
|
||||
} catch (dbError) {
|
||||
console.error('[API] Failed to update transaction status in DB:', dbError);
|
||||
// 6. Update transaction status
|
||||
await db.query(`UPDATE transactions SET status = 'succeeded' WHERE id = $1`, [transaction.id]);
|
||||
|
||||
// 7. Automated Webhook Notification
|
||||
if (transaction.callback_url) {
|
||||
console.log(`[Webhook] Notifying merchant at ${transaction.callback_url}`);
|
||||
try {
|
||||
// In production, sign this payload and use a more robust delivery system
|
||||
fetch(transaction.callback_url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
status: 'success',
|
||||
txId: transaction.stripe_pi_id,
|
||||
orderRef: transaction.source_ref_id,
|
||||
hashes: sweepResult
|
||||
})
|
||||
}).catch(e => console.error("Webhook fetch failed:", e.message));
|
||||
} catch (webhookError: any) {
|
||||
console.error("[Webhook Error]:", webhookError.message);
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Ödeme başarıyla doğrulandı ve dağıtıldı (Solana Devnet).",
|
||||
split: {
|
||||
platform: "%1",
|
||||
merchant: "%99"
|
||||
},
|
||||
message: `Ödeme ${selectedNetwork} ağında ${selectedToken} ile başarıyla doğrulandı ve süpürüldü.`,
|
||||
hashes: {
|
||||
platform: sweepResult.platformTx,
|
||||
merchant: sweepResult.merchantTx
|
||||
@@ -65,6 +116,7 @@ export async function POST(request: Request) {
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('[API Error]:', error.message);
|
||||
return NextResponse.json({ success: false, error: error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user