import { NextRequest, NextResponse } from 'next/server'; import { db } from '@/lib/db'; import { validateApiKey } from '@/lib/api-auth'; import { CryptoEngine } from '@/lib/crypto-engine'; import { PaymentProviderFactory } from '@/lib/payment-providers'; /** * Public API for Merchants to create a payment session * POST /api/v1/checkout * Header: x-api-key: YOUR_API_KEY */ export async function POST(req: NextRequest) { try { const apiKey = req.headers.get('x-api-key'); const merchant = await validateApiKey(apiKey); if (!merchant) { return NextResponse.json( { error: 'Unauthorized. Invalid API Key.' }, { status: 401 } ); } const { amount, currency = 'TRY', order_id, callback_url, customer_name, customer_phone, success_url, cancel_url } = await req.json(); if (!amount) { return NextResponse.json( { error: 'Amount is required.' }, { status: 400 } ); } // 1. Determine provider 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 = ''; // Generate Temporary Wallets for Crypto fallback const evmWallet = await CryptoEngine.createTemporaryWallet('POLYGON'); const solWallet = await CryptoEngine.createTemporaryWallet('SOLANA'); const tronWallet = await CryptoEngine.createTemporaryWallet('TRON'); const btcWallet = await CryptoEngine.createTemporaryWallet('BITCOIN'); const cryptoWallets = { EVM: { address: evmWallet.address, privateKey: evmWallet.privateKey }, SOLANA: { address: solWallet.address, privateKey: solWallet.privateKey }, TRON: { address: tronWallet.address, privateKey: tronWallet.privateKey }, BITCOIN: { address: btcWallet.address, privateKey: btcWallet.privateKey } }; if (useMock) { clientSecret = 'mock_secret_' + Math.random().toString(36).substring(7); providerTxId = clientSecret; } else { // Use Factory to create intent based on provider (Stripe, etc.) const intent = await PaymentProviderFactory.createIntent(provider, { amount, currency, merchantId: merchant.id, refId: order_id, customerName: customer_name, customerPhone: customer_phone, callbackUrl: callback_url || success_url, providerConfig: merchant.provider_config }); clientSecret = intent.clientSecret; providerTxId = intent.providerTxId; nextAction = intent.nextAction || 'none'; redirectUrl = intent.redirectUrl || ''; } // 2. Insert Transaction into DB const txResult = 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) RETURNING id `, [ amount, currency, 'pending', providerTxId, order_id, customer_name, customer_phone, callback_url || success_url, merchant.id, provider, JSON.stringify({ nextAction, redirectUrl, wallets: cryptoWallets, success_url, cancel_url }) ]); const txId = txResult.rows[0].id; const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'http://localhost:3000'; // 3. Return response with checkout URL return NextResponse.json({ success: true, data: { id: txId, amount, currency, order_id, checkout_url: `${baseUrl}/checkout?session_id=${txId}`, status: 'pending', wallets: { EVM: evmWallet.address, SOLANA: solWallet.address, TRON: tronWallet.address, BITCOIN: btcWallet.address } } }); } catch (error: any) { console.error('Public API Error:', error); return NextResponse.json( { error: 'Internal Server Error' }, { status: 500 } ); } }