Files
Pay2Gateway/app/merchant/[id]/(dashboard)/integration/page.tsx

218 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import { db } from '@/lib/db';
import {
Terminal,
Copy,
Globe,
Webhook,
Zap,
ShieldCheck,
Code2,
Server,
Link as LinkIcon
} 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);
const queryText = isUUID
? 'SELECT * FROM merchants WHERE id = $1 LIMIT 1'
: 'SELECT * FROM merchants WHERE short_id = $1 LIMIT 1';
const result = await db.query(queryText, [identifier]);
return result.rows[0];
}
export default async function MerchantIntegrationPage(props: {
params: Promise<{ id: string }>;
}) {
const resolvedParams = await props.params;
const identifier = resolvedParams.id;
const merchant = await getMerchant(identifier);
const cookieStore = await cookies();
if (!merchant) return null;
if (!cookieStore.get(`merchant_auth_${merchant.id}`)) {
redirect(`/merchant/${identifier}/login`);
}
const host = process.env.NEXT_PUBLIC_BASE_URL || 'https://p2cgateway.store';
const checkoutUrl = `${host}/checkout?merchant_id=${merchant.short_id || merchant.id}&amount=100&currency=TRY&ref_id=SİPARİŞ_123`;
return (
<div className="max-w-6xl space-y-16 animate-in fade-in slide-in-from-bottom-4 duration-700 pb-32">
{/* Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6">
<div>
<h1 className="text-4xl font-black text-gray-900 tracking-tight">Entegrasyon Rehberi</h1>
<p className="text-xs text-gray-400 font-black uppercase tracking-[0.3em] mt-3 px-1 border-l-4 border-blue-600 pl-4">Ödeme sistemini sisteminize dahil edin</p>
</div>
</div>
{/* Methods Selection */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10">
{/* Option 1: Quick Link */}
<div className="bg-white p-12 rounded-[48px] border border-gray-100 shadow-xl shadow-gray-100/50 space-y-10 relative overflow-hidden group">
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-full -mr-16 -mt-16 group-hover:scale-150 transition-transform duration-700"></div>
<div className="space-y-6 relative">
<div className="w-16 h-16 bg-blue-600 rounded-3xl flex items-center justify-center text-white shadow-lg shadow-blue-200">
<LinkIcon size={32} />
</div>
<h2 className="text-2xl font-black text-gray-900">1. Hızlı Ödeme Linki</h2>
<p className="text-gray-500 font-medium leading-relaxed">
Kod yazmanıza gerek kalmadan, müşterilerinizi doğrudan ödeme sayfamıza yönlendirebilirsiniz. Parametreleri URL üzerinden iletebilirsiniz.
</p>
</div>
<div className="space-y-4">
<p className="text-[10px] font-black text-gray-400 uppercase tracking-widest pl-1">Örnek Yapı</p>
<div className="bg-gray-50 p-6 rounded-3xl border border-gray-100 font-mono text-[11px] text-gray-600 break-all leading-relaxed relative group/code">
{checkoutUrl}
<button className="absolute top-4 right-4 p-2 bg-white rounded-lg shadow-sm opacity-0 group-hover/code:opacity-100 transition-opacity">
<Copy size={14} className="text-gray-400" />
</button>
</div>
</div>
</div>
{/* Option 2: Server-to-Server API */}
<div className="bg-gray-900 p-12 rounded-[48px] shadow-2xl space-y-10 relative overflow-hidden group">
<div className="absolute top-0 right-0 w-32 h-32 bg-white/5 rounded-full -mr-16 -mt-16"></div>
<div className="space-y-6 relative">
<div className="w-16 h-16 bg-emerald-500 rounded-3xl flex items-center justify-center text-white shadow-lg shadow-emerald-900/20">
<Server size={32} />
</div>
<h2 className="text-2xl font-black text-white">2. Profesyonel API (v1)</h2>
<p className="text-gray-400 font-medium leading-relaxed">
Sunucu taraflı entegrasyon ile daha güvenli işlemler başlatın. Fiyat manipülasyonunu engeller ve sessiz oturumlar oluşturur.
</p>
</div>
<div className="space-y-4">
<p className="text-[10px] font-black text-gray-500 uppercase tracking-widest pl-1">Endpoint</p>
<div className="bg-white/5 p-6 rounded-3xl border border-white/10 font-mono text-[11px] text-emerald-400">
POST {host}/api/v1/checkout
</div>
</div>
</div>
</div>
{/* API Details Section */}
<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-gray-50 rounded-2xl flex items-center justify-center text-gray-900">
<ShieldCheck size={28} />
</div>
<div>
<h3 className="text-2xl font-black text-gray-900">API Erişimi ve Güvenlik</h3>
<p className="text-xs text-gray-400 font-bold uppercase tracking-widest mt-1">İsteklerinizi doğrulamak için bu anahtarları kullanın</p>
</div>
</div>
<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">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 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">Secure API Secret Key</label>
<ApiKeyVisibilityToggle apiKey={merchant.api_key} />
</div>
</div>
</div>
{/* 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 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>
{/* 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="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>
{/* Footer Resources */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{[
{ title: 'Postman Koleksiyonu', icon: Terminal, color: 'blue' },
{ title: 'Geliştirici Dokümanları', icon: Code2, color: 'emerald' },
{ title: 'Teknik Yardım', icon: Globe, color: 'gray' },
].map((r) => (
<div key={r.title} className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm flex items-center gap-6 hover:shadow-lg transition-all cursor-pointer group hover:-translate-y-1">
<div className={`w-14 h-14 bg-gray-50 rounded-2xl flex items-center justify-center text-gray-400 group-hover:bg-blue-600 group-hover:text-white transition-all`}>
<r.icon size={24} />
</div>
<span className="text-sm font-black text-gray-900 uppercase tracking-tight">{r.title}</span>
</div>
))}
</div>
</div>
);
}