Files
Pay2Gateway/app/api/v1/checkout/route.ts

136 lines
4.2 KiB
TypeScript

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 }
);
}
}