Files
soul/lib/payment-service.ts

118 lines
3.0 KiB
TypeScript
Raw Normal View History

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<PaymentOrder> {
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<boolean> {
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<PaymentOrder[]> {
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("[v0] No payment URL configured for", method)
return false
}
// Open URL in new window/tab
window.open(redirectUrl, "_blank")
return true
}
}