2025-12-24 14:41:11 +08:00

215 lines
7.8 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.

'use client'
import { Suspense, useEffect, useState } from 'react'
import { useSearchParams } from 'next/navigation'
import { CheckCircle, XCircle, Loader2 } from 'lucide-react'
import Link from 'next/link'
import Image from 'next/image'
export const dynamic = 'force-dynamic'
function PaymentSuccessContent() {
const searchParams = useSearchParams()
const orderNo = searchParams.get('order_no')
const [orderStatus, setOrderStatus] = useState<'loading' | 'success' | 'failed' | 'pending'>('loading')
const [orderInfo, setOrderInfo] = useState<any>(null)
useEffect(() => {
if (!orderNo) {
setOrderStatus('failed')
return
}
const checkOrderStatus = async () => {
try {
const response = await fetch(`/api/payment/status?order_no=${orderNo}`)
const data = await response.json()
if (data.success) {
setOrderInfo(data.order)
setOrderStatus(
data.order.status === 'paid'
? 'success'
: data.order.status === 'failed'
? 'failed'
: 'pending'
)
} else {
setOrderStatus('failed')
}
} catch (error) {
console.error('查询订单状态错误:', error)
setOrderStatus('failed')
}
}
checkOrderStatus()
// 如果订单还在pending状态,每3秒轮询一次(最多轮询10次)
let pollCount = 0
const pollInterval = setInterval(() => {
if (pollCount >= 10) {
clearInterval(pollInterval)
return
}
pollCount++
checkOrderStatus()
}, 3000)
return () => clearInterval(pollInterval)
}, [orderNo])
return (
<div className="min-h-screen bg-gradient-to-b from-apple-gray-50 to-white flex items-center justify-center px-4 py-12">
<div className="max-w-md w-full">
{/* Logo */}
<div className="text-center mb-8">
<div className="flex justify-center mb-4">
<div className="relative w-16 h-16">
<Image
src="/images/logo.png"
alt="FLNXI Logo"
fill
className="object-contain"
priority
/>
</div>
</div>
</div>
{/* 支付结果卡片 */}
<div className="bg-white rounded-3xl apple-shadow-lg p-8">
{orderStatus === 'loading' && (
<div className="text-center py-8">
<Loader2 className="w-16 h-16 text-apple-blue animate-spin mx-auto mb-4" />
<h2 className="text-2xl font-bold text-apple-gray-900 mb-2">
正在确认支付结果...
</h2>
<p className="text-apple-gray-600">
请稍候,我们正在验证您的支付信息
</p>
</div>
)}
{orderStatus === 'success' && (
<div className="text-center py-8">
<div className="w-16 h-16 bg-gradient-to-r from-green-500 to-emerald-600 rounded-full flex items-center justify-center mx-auto mb-4">
<CheckCircle className="w-8 h-8 text-white" />
</div>
<h2 className="text-3xl font-bold text-apple-gray-900 mb-2">
支付成功!
</h2>
<p className="text-apple-gray-600 mb-6">
感谢您的购买,订单已确认
</p>
{orderInfo && (
<div className="bg-apple-gray-50 rounded-xl p-4 mb-6 text-left">
<div className="space-y-2 text-sm">
<div className="flex justify-between">
<span className="text-apple-gray-600">订单号:</span>
<span className="font-mono font-semibold">{orderInfo.order_no}</span>
</div>
<div className="flex justify-between">
<span className="text-apple-gray-600">商品名称:</span>
<span className="font-semibold">{orderInfo.product_name}</span>
</div>
<div className="flex justify-between">
<span className="text-apple-gray-600">支付金额:</span>
<span className="font-bold text-green-600">¥{orderInfo.amount}</span>
</div>
{orderInfo.trade_no && (
<div className="flex justify-between">
<span className="text-apple-gray-600">交易号:</span>
<span className="font-mono text-xs">{orderInfo.trade_no}</span>
</div>
)}
</div>
</div>
)}
<div className="space-y-3">
<Link
href="/"
className="block w-full py-3 bg-gradient-to-r from-apple-blue to-blue-600 text-white rounded-full font-semibold button-hover apple-shadow"
>
返回首页
</Link>
<p className="text-xs text-apple-gray-500">
我们将在1-3个工作日内为您开通服务
</p>
</div>
</div>
)}
{orderStatus === 'pending' && (
<div className="text-center py-8">
<Loader2 className="w-16 h-16 text-orange-500 animate-spin mx-auto mb-4" />
<h2 className="text-2xl font-bold text-apple-gray-900 mb-2">
支付处理中
</h2>
<p className="text-apple-gray-600 mb-6">
您的订单已提交,正在等待支付确认
</p>
{orderNo && (
<p className="text-xs text-apple-gray-500 font-mono mb-6">
订单号:{orderNo}
</p>
)}
<p className="text-sm text-apple-gray-500">
如果已完成支付,请稍候片刻,系统会自动更新订单状态
</p>
</div>
)}
{orderStatus === 'failed' && (
<div className="text-center py-8">
<div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">
<XCircle className="w-8 h-8 text-red-600" />
</div>
<h2 className="text-2xl font-bold text-apple-gray-900 mb-2">
支付失败
</h2>
<p className="text-apple-gray-600 mb-6">
订单处理失败,请检查支付信息或联系客服
</p>
<div className="space-y-3">
<Link
href="/#pricing"
className="block w-full py-3 bg-gradient-to-r from-apple-blue to-blue-600 text-white rounded-full font-semibold button-hover apple-shadow"
>
重新购买
</Link>
<Link
href="/#contact"
className="block w-full py-3 border-2 border-apple-gray-200 text-apple-gray-700 rounded-full font-semibold hover:border-apple-blue hover:text-apple-blue transition-all"
>
联系客服
</Link>
</div>
</div>
)}
</div>
</div>
</div>
)
}
export default function PaymentSuccessPage() {
return (
<Suspense
fallback={
<div className="min-h-screen bg-gradient-to-b from-apple-gray-50 to-white flex items-center justify-center px-4 py-12">
<div className="text-center">
<Loader2 className="w-12 h-12 text-apple-blue animate-spin mx-auto mb-4" />
<p className="text-apple-gray-600">页面加载中...</p>
</div>
</div>
}
>
<PaymentSuccessContent />
</Suspense>
)
}