export interface PaymentOrder { orderId: string userId: string type: "section" | "fullbook" sectionId?: string sectionTitle?: string amount: number paymentMethod: "wechat" | "alipay" | "usdt" | "paypal" referralCode?: string status: "pending" | "completed" | "failed" | "refunded" createdAt: string expireAt: string transactionId?: string completedAt?: string } export class PaymentService { /** * Create a new payment order */ static async createOrder(params: { userId: string type: "section" | "fullbook" sectionId?: string sectionTitle?: string amount: number paymentMethod: string referralCode?: string }): Promise { const response = await fetch("/api/payment/create-order", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(params), }) const result = await response.json() if (result.code !== 0) { throw new Error(result.message || "创建订单失败") } return result.data } /** * Verify payment completion */ static async verifyPayment(orderId: string, transactionId?: string): Promise { const response = await fetch("/api/payment/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ orderId, transactionId }), }) const result = await response.json() return result.code === 0 && result.data.status === "completed" } /** * Get user orders */ static async getUserOrders(userId: string): Promise { const response = await fetch(`/api/orders?userId=${userId}`) const result = await response.json() if (result.code !== 0) { throw new Error(result.message || "获取订单失败") } return result.data } /** * Get payment gateway config */ static getPaymentConfig(method: "wechat" | "alipay" | "usdt" | "paypal") { // In production, fetch from settings API // For now, use localStorage const settings = JSON.parse(localStorage.getItem("settings") || "{}") return settings.paymentMethods?.[method] || {} } /** * Generate payment QR code URL */ static getPaymentQRCode(method: "wechat" | "alipay", amount: number, orderId: string): string { const config = this.getPaymentConfig(method) // If it's a redirect URL, return it directly if ( config.qrCode?.startsWith("http") || config.qrCode?.startsWith("weixin://") || config.qrCode?.startsWith("alipays://") ) { return config.qrCode } // Otherwise return the QR code image return config.qrCode || "" } /** * Open payment app (Wechat/Alipay) */ static openPaymentApp(method: "wechat" | "alipay", orderId: string): boolean { const config = this.getPaymentConfig(method) const redirectUrl = config.qrCode if (!redirectUrl) { console.error("[Karuo] No payment URL configured for", method) return false } // Open URL in new window/tab window.open(redirectUrl, "_blank") return true } }