feat: enhance merchant panel with balance breakdown, payout history, and security improvements
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { cookies } from 'next/headers';
|
||||
import { redirect } from 'next/navigation';
|
||||
import ApiKeyVisibilityToggle from '@/components/merchant/ApiKeyVisibilityToggle';
|
||||
|
||||
async function getMerchant(identifier: string) {
|
||||
const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier);
|
||||
@@ -116,54 +117,82 @@ export default async function MerchantIntegrationPage(props: {
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
|
||||
<div className="space-y-4">
|
||||
<label className="text-[10px] font-black text-gray-400 uppercase tracking-widest ml-2">Merchant ID</label>
|
||||
<label className="text-[10px] font-black text-gray-400 uppercase tracking-widest ml-2">Public Merchant ID</label>
|
||||
<div className="bg-gray-50 p-5 rounded-2xl border border-gray-100 flex items-center justify-between">
|
||||
<code className="text-xs font-mono font-bold text-gray-600">{merchant.id}</code>
|
||||
<Copy size={16} className="text-gray-300 cursor-pointer hover:text-blue-600 transition" />
|
||||
<code className="text-xs font-mono font-bold text-gray-600 truncate">{merchant.id}</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<label className="text-[10px] font-black text-gray-400 uppercase tracking-widest ml-2">API Secret Key</label>
|
||||
<div className="bg-gray-50 p-5 rounded-2xl border border-gray-100 flex items-center justify-between">
|
||||
<code className="text-xs font-mono font-bold text-gray-600">
|
||||
{merchant.api_key.substring(0, 8)}••••••••••••••••••••••••
|
||||
</code>
|
||||
<button className="text-[10px] font-black text-blue-600 uppercase tracking-widest hover:underline">Anahtarı Göster</button>
|
||||
</div>
|
||||
<label className="text-[10px] font-black text-gray-400 uppercase tracking-widest ml-2">Secure API Secret Key</label>
|
||||
<ApiKeyVisibilityToggle apiKey={merchant.api_key} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Webhook Settings */}
|
||||
<div className="bg-white p-12 rounded-[48px] border border-gray-100 shadow-sm space-y-12">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="w-14 h-14 bg-purple-50 rounded-2xl flex items-center justify-center text-purple-600">
|
||||
<Webhook size={28} />
|
||||
{/* Webhook & Payout Addresses */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10">
|
||||
{/* Webhook Settings */}
|
||||
<div className="bg-white p-12 rounded-[48px] border border-gray-100 shadow-sm space-y-12">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="w-14 h-14 bg-purple-50 rounded-2xl flex items-center justify-center text-purple-600">
|
||||
<Webhook size={28} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-black text-gray-900">Webhooks</h3>
|
||||
<p className="text-xs text-gray-400 font-bold uppercase tracking-widest mt-1">Anlık Bildirimler</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-black text-gray-900">Olay Bildirimleri (Webhooks)</h3>
|
||||
<p className="text-xs text-gray-400 font-bold uppercase tracking-widest mt-1">Ödeme sonuçlarını anlık olarak sunucunuzda karşılayın</p>
|
||||
|
||||
<div className="space-y-8">
|
||||
<div className="p-8 bg-gray-50 rounded-[32px] border border-gray-100 space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[11px] font-black text-gray-400 uppercase tracking-widest ml-2">URL</span>
|
||||
<span className={`text-[10px] font-black px-3 py-1 rounded-full ${merchant.webhook_url ? 'bg-emerald-100 text-emerald-700' : 'bg-red-100 text-red-700'}`}>
|
||||
{merchant.webhook_url ? 'AKTİF' : 'TANIMSZ'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="bg-white p-6 rounded-2xl border border-gray-200">
|
||||
<code className="text-sm font-bold text-gray-700 break-all">
|
||||
{merchant.webhook_url || 'https://siteniz.com/callback'}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-8">
|
||||
<p className="text-gray-500 font-medium leading-relaxed max-w-2xl">
|
||||
İşlem tamamlandığında sistemimiz belirttiğiniz URL'ye <code className="bg-gray-100 px-2 py-1 rounded text-blue-600 font-bold">POST</code> isteği gönderir. Bu isteğin içerisinde işlemin tüm detayları yer alır.
|
||||
</p>
|
||||
{/* Payout Addresses */}
|
||||
<div className="bg-white p-12 rounded-[48px] border border-gray-100 shadow-sm space-y-12">
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="w-14 h-14 bg-emerald-50 rounded-2xl flex items-center justify-center text-emerald-600">
|
||||
<Zap size={28} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-2xl font-black text-gray-900">Hak Ediş Adresleriniz</h3>
|
||||
<p className="text-xs text-gray-400 font-bold uppercase tracking-widest mt-1">Ödemeleriniz bu adreslere iletilir</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8 bg-gray-50 rounded-[32px] border border-gray-100 space-y-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="text-[11px] font-black text-gray-400 uppercase tracking-widest ml-2">Webhook URL</span>
|
||||
<span className={`text-[10px] font-black px-3 py-1 rounded-full ${merchant.webhook_url ? 'bg-emerald-100 text-emerald-700' : 'bg-red-100 text-red-700'}`}>
|
||||
{merchant.webhook_url ? 'HİZMETE HAZIR' : 'HENÜZ TANIMLANMAMIŞ'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="bg-white p-6 rounded-2xl border border-gray-200">
|
||||
<code className="text-sm font-bold text-gray-700 break-all">
|
||||
{merchant.webhook_url || 'https://siteniz.com/api/payment-callback'}
|
||||
</code>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{['EVM', 'SOLANA', 'TRON', 'BITCOIN'].map((net) => {
|
||||
const addr = merchant.payout_addresses?.[net] || (net === 'EVM' ? merchant.payout_address : null);
|
||||
return (
|
||||
<div key={net} className="flex items-center justify-between p-4 bg-gray-50 rounded-2xl border border-gray-100 group">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-8 h-8 rounded-xl flex items-center justify-center text-white text-[10px] font-black ${net === 'SOLANA' ? 'bg-emerald-500' : net === 'POLYGON' ? 'bg-purple-500' : net === 'TRON' ? 'bg-red-500' : 'bg-orange-500'}`}>
|
||||
{net.slice(0, 1)}
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[9px] font-black text-gray-400 uppercase tracking-[0.2em]">{net}</p>
|
||||
<p className="text-[11px] font-mono font-bold text-gray-900 truncate max-w-[180px] lg:max-w-[250px]">
|
||||
{addr || 'TANIMLANMAMIŞ'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{addr && <Copy size={14} className="text-gray-300 cursor-pointer hover:text-blue-600 transition" />}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user