'use client'; import React, { useState, useEffect } from 'react'; import { Copy, CheckCircle2, RefreshCw, AlertCircle, ChevronDown } from 'lucide-react'; import cryptoConfig from '@/lib/crypto-config.json'; interface CryptoCheckoutProps { amount: number; currency: string; txId: string; wallets?: { [key: string]: any; }; onSuccess: (txHash: string) => void; } export default function CryptoCheckout({ amount, currency, txId, wallets, onSuccess }: CryptoCheckoutProps) { const [selectedNetwork, setSelectedNetwork] = useState(cryptoConfig.networks[0]); const [selectedToken, setSelectedToken] = useState(selectedNetwork.tokens[0]); const [depositAddress, setDepositAddress] = useState('Yükleniyor...'); const [isVerifying, setIsVerifying] = useState(false); const [copied, setCopied] = useState(false); const [status, setStatus] = useState<'waiting' | 'verifying' | 'success' | 'error'>('waiting'); const [cryptoAmount, setCryptoAmount] = useState('Hesaplanıyor...'); const [unitPrice, setUnitPrice] = useState(''); const [unitPriceUsd, setUnitPriceUsd] = useState(''); // Update address based on selected network useEffect(() => { if (wallets) { // Support all 4 networks and both string/object formats const rawVal = wallets[selectedNetwork.id] || wallets['EVM']; const addr = typeof rawVal === 'string' ? rawVal : rawVal?.address; setDepositAddress(addr || 'Adres Bulunamadı'); } }, [selectedNetwork, wallets]); // Fetch exchange rate useEffect(() => { async function fetchExchangeRate() { setCryptoAmount('...'); try { const symbol = selectedToken.symbol; let rateInTry = 32.5; let rateInUsd = 1.0; // 1. Get USDTRY rate first const tryRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=USDTTRY`); const tryData = await tryRes.json(); const tryToUsdRate = parseFloat(tryData.price) || 32.5; const isStable = ['USDT', 'USDC', 'BUSD', 'DAI'].includes(symbol); if (!isStable) { // Try to fetch [SYMBOL]USDT try { const pair = `${symbol}USDT`; const res = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=${pair}`); const data = await res.json(); if (data.price) { rateInUsd = parseFloat(data.price); rateInTry = rateInUsd * tryToUsdRate; } else { // Try fallback mappings if direct USDT pair fails rateInTry = tryToUsdRate; // Default to 1 USD value } } catch (e) { rateInTry = tryToUsdRate; } } else { rateInTry = tryToUsdRate; rateInUsd = 1.0; } setUnitPrice(rateInTry.toLocaleString('tr-TR', { minimumFractionDigits: 2, maximumFractionDigits: 4 })); setUnitPriceUsd(rateInUsd.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 4 })); const finalAmount = (amount / rateInTry).toFixed(selectedToken.decimals < 9 ? 4 : 6); setCryptoAmount(finalAmount); } catch (error) { setCryptoAmount((amount / 32.5).toFixed(2)); } } fetchExchangeRate(); }, [amount, selectedToken, selectedNetwork]); // Auto-polling for payment verification useEffect(() => { let interval: NodeJS.Timeout; if (status === 'waiting' && depositAddress !== 'Yükleniyor...') { interval = setInterval(() => { verifyPayment(); }, 8000); // Check every 8 seconds } return () => clearInterval(interval); }, [status, depositAddress, selectedNetwork, selectedToken]); const changeNetwork = (networkId: string) => { const network = cryptoConfig.networks.find(n => n.id === networkId) || cryptoConfig.networks[0]; setSelectedNetwork(network); setSelectedToken(network.tokens[0]); }; // Save payment intent to DB so background sync knows what to check useEffect(() => { if (!txId || !selectedNetwork || !selectedToken) return; const saveIntent = async () => { try { await fetch(`/api/transactions/${txId}/intent`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ network: selectedNetwork.id, token: selectedToken.symbol }) }); } catch (err) { console.error("Failed to save payment intent:", err); } }; const timer = setTimeout(saveIntent, 1000); // Debounce return () => clearTimeout(timer); }, [txId, selectedNetwork.id, selectedToken.symbol]); const handleCopy = () => { navigator.clipboard.writeText(depositAddress); setCopied(true); setTimeout(() => setCopied(false), 2000); }; const verifyPayment = async () => { setIsVerifying(true); try { const response = await fetch('/api/crypto-sweep', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ txId: txId, network: selectedNetwork.id, token: selectedToken.symbol }) }); const data = await response.json(); if (data.success) { setStatus('success'); onSuccess(data.hashes?.merchant || '0x_mock_hash'); } else if (data.status === 'waiting') { setStatus('waiting'); } } catch (err) { console.error(err); } finally { setIsVerifying(false); } }; const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=${depositAddress}`; return (
{/* Crypto Selection Header */}
{/* @ts-ignore */}
{/* @ts-ignore */} {selectedToken.symbol}

Ödenecek Tutar

{cryptoAmount} {selectedToken.symbol}

Kur

1 {selectedToken.symbol} = {unitPrice} TRY

($ {unitPriceUsd})

{status === 'success' ? (

Ödeme Alındı

Mağazaya yönlendiriliyorsunuz...

) : ( <>
{depositAddress !== 'Yükleniyor...' ? ( Wallet QR ) : ( )}
{depositAddress}

Sadece {selectedNetwork.name} ağı üzerinden {selectedToken.symbol} gönderin.

)}
); }