122 lines
4.6 KiB
TypeScript
122 lines
4.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
||
import { db } from '@/lib/db';
|
||
import { PaymentProviderFactory } from '@/lib/payment-providers';
|
||
import { CryptoEngine } from '@/lib/crypto-engine';
|
||
|
||
export async function POST(req: NextRequest) {
|
||
try {
|
||
const { amount, currency, ref_id, callback_url, customer_name, customer_phone, merchant_id } = await req.json();
|
||
|
||
if (!amount || !currency) {
|
||
return NextResponse.json(
|
||
{ error: 'Tutar ve para birimi zorunludur.' },
|
||
{ status: 400 }
|
||
);
|
||
}
|
||
|
||
let merchant;
|
||
// 1. Fetch Merchant to check provider (Support both UUID and Short ID)
|
||
if (merchant_id) {
|
||
const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(merchant_id);
|
||
let result;
|
||
if (isUUID) {
|
||
result = await db.query('SELECT * FROM merchants WHERE id = $1', [merchant_id]);
|
||
} else {
|
||
result = await db.query('SELECT * FROM merchants WHERE short_id = $1', [merchant_id]);
|
||
}
|
||
|
||
if (result.rows.length === 0) {
|
||
return NextResponse.json({ error: 'Firma bulunamadı.' }, { status: 404 });
|
||
}
|
||
merchant = result.rows[0];
|
||
} else {
|
||
// For demo purposes on the landing page, fetch any existing merchant
|
||
const result = await db.query('SELECT * FROM merchants LIMIT 1');
|
||
if (result.rows.length === 0) {
|
||
return NextResponse.json({ error: 'Sistemde kayıtlı firma bulunamadı (Önce admin panelinden firma ekleyin).' }, { status: 404 });
|
||
}
|
||
merchant = result.rows[0];
|
||
}
|
||
|
||
// Use the actual UUID for DB operations
|
||
const resolvedMerchantId = merchant.id;
|
||
|
||
const provider = merchant.payment_provider || 'stripe';
|
||
const useMock = process.env.NEXT_PUBLIC_USE_MOCK_PAYMENTS === 'true';
|
||
|
||
let clientSecret = '';
|
||
let providerTxId = '';
|
||
let nextAction = 'none';
|
||
let redirectUrl = '';
|
||
|
||
if (useMock) {
|
||
clientSecret = 'mock_secret_' + Math.random().toString(36).substring(7);
|
||
providerTxId = clientSecret;
|
||
} else {
|
||
// 2. Use Factory to create intent based on provider
|
||
const intent = await PaymentProviderFactory.createIntent(provider, {
|
||
amount,
|
||
currency,
|
||
merchantId: resolvedMerchantId,
|
||
refId: ref_id,
|
||
customerName: customer_name,
|
||
customerPhone: customer_phone,
|
||
callbackUrl: callback_url,
|
||
providerConfig: merchant.provider_config
|
||
});
|
||
|
||
clientSecret = intent.clientSecret;
|
||
providerTxId = intent.providerTxId;
|
||
nextAction = intent.nextAction || 'none';
|
||
redirectUrl = intent.redirectUrl || '';
|
||
}
|
||
|
||
// 3. Generate Temporary Wallets for Crypto fallback
|
||
const evmWallet = await CryptoEngine.createTemporaryWallet('POLYGON');
|
||
const solWallet = await CryptoEngine.createTemporaryWallet('SOLANA');
|
||
|
||
const cryptoWallets = {
|
||
EVM: { address: evmWallet.address, privateKey: evmWallet.privateKey },
|
||
SOLANA: { address: solWallet.address, privateKey: solWallet.privateKey }
|
||
};
|
||
|
||
// 4. Log transaction in Supabase
|
||
try {
|
||
await db.query(`
|
||
INSERT INTO transactions (
|
||
amount, currency, status, stripe_pi_id, source_ref_id,
|
||
customer_name, customer_phone, callback_url, merchant_id,
|
||
provider, metadata
|
||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||
`, [
|
||
amount, currency, 'pending', providerTxId, ref_id,
|
||
customer_name, customer_phone, callback_url, resolvedMerchantId,
|
||
provider, JSON.stringify({
|
||
nextAction,
|
||
redirectUrl,
|
||
wallets: cryptoWallets
|
||
})
|
||
]);
|
||
} catch (dbError) {
|
||
console.error('Database log error:', dbError);
|
||
}
|
||
|
||
return NextResponse.json({
|
||
clientSecret: clientSecret,
|
||
nextAction,
|
||
redirectUrl,
|
||
provider,
|
||
wallets: {
|
||
EVM: evmWallet.address,
|
||
SOLANA: solWallet.address
|
||
}
|
||
});
|
||
} catch (err: any) {
|
||
console.error('Internal Error:', err);
|
||
return NextResponse.json(
|
||
{ error: `Internal Server Error: ${err.message}` },
|
||
{ status: 500 }
|
||
);
|
||
}
|
||
}
|