"use client"; import { Copy, Loader2, QrCode } from "lucide-react"; import { useRouter } from "next/navigation"; import { useSession } from "next-auth/react"; import { useEffect, useMemo, useState } from "react"; import { cn } from "@/lib/utils"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; export function WechatPricingButton({ planId, planName, enabled, }: { planId: string; planName: string; enabled: boolean; }) { const { data: session } = useSession(); const router = useRouter(); const [isPending, setIsPending] = useState(false); const [open, setOpen] = useState(false); const [outTradeNo, setOutTradeNo] = useState(null); const [qrCodeImageUrl, setQrCodeImageUrl] = useState(null); const [codeUrl, setCodeUrl] = useState(null); const [statusText, setStatusText] = useState("请使用微信扫码完成支付"); const canPoll = useMemo(() => open && Boolean(outTradeNo), [open, outTradeNo]); useEffect(() => { if (!canPoll || !outTradeNo) { return; } let timer: number | undefined; let stopped = false; const poll = async () => { try { const response = await fetch(`/api/billing/wechat/order-status?outTradeNo=${encodeURIComponent(outTradeNo)}`); if (!response.ok) { return; } const data = (await response.json()) as { status?: string }; if (stopped || !data.status) { return; } if (data.status === "paid") { setStatusText("支付成功,正在跳转..."); stopped = true; setTimeout(() => { router.push(`/lovart/pricing?checkout=success&plan=${encodeURIComponent(planId)}`); }, 800); return; } if (data.status !== "created" && data.status !== "processing") { setStatusText(`当前状态:${data.status}`); } } catch { // ignore polling failure } if (!stopped) { timer = window.setTimeout(poll, 3000); } }; void poll(); return () => { stopped = true; if (timer) { window.clearTimeout(timer); } }; }, [canPoll, outTradeNo, planId, router]); async function handleCheckout() { if (isPending) { return; } if (!enabled) { window.alert("微信支付尚未配置,请先配置微信支付环境变量。"); return; } if (!session?.user || session.user.type === "guest") { router.push("/login?callbackUrl=/lovart/pricing"); return; } setIsPending(true); try { const response = await fetch("/api/billing/wechat/checkout", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ planId }), }); const data = (await response.json()) as { error?: string; outTradeNo?: string; qrCodeImageUrl?: string; codeUrl?: string; }; if (!response.ok || !data.outTradeNo || !data.qrCodeImageUrl || !data.codeUrl) { window.alert(data.error || "创建微信支付订单失败,请稍后重试。"); return; } setOutTradeNo(data.outTradeNo); setQrCodeImageUrl(data.qrCodeImageUrl); setCodeUrl(data.codeUrl); setStatusText("请使用微信扫码完成支付"); setOpen(true); } catch (error) { console.error("[WechatPricingButton] checkout error", error); window.alert("创建微信支付订单失败,请稍后重试。"); } finally { setIsPending(false); } } async function handleCopyLink() { if (!codeUrl) { return; } try { await navigator.clipboard.writeText(codeUrl); window.alert("支付链接已复制"); } catch { window.alert("复制失败,请手动复制"); } } return ( <> 微信扫码支付 {statusText}
{qrCodeImageUrl ? (
wechat pay qrcode
) : (
正在生成二维码...
)}

订单号:{outTradeNo || "-"}

); }