/** * 通用支付模块类型定义 (Universal Payment Module Types) * 基于 Universal_Payment_Module v4.0 设计 * * 作者: 卡若 * 版本: v4.0 */ // 支付平台枚举 export type PaymentPlatform = 'alipay' | 'wechat' | 'paypal' | 'stripe' | 'usdt' | 'coin'; // 支付网关类型 export type PaymentGateway = | 'alipay_web' | 'alipay_wap' | 'alipay_qr' | 'wechat_native' | 'wechat_jsapi' | 'wechat_h5' | 'wechat_app' | 'paypal' | 'stripe' | 'usdt' | 'coin'; // 订单状态 export type OrderStatus = 'created' | 'paying' | 'paid' | 'closed' | 'refunded'; // 交易状态 export type TradeStatus = 'paying' | 'paid' | 'closed' | 'refunded'; // 交易类型 export type TradeType = 'purchase' | 'recharge'; // 支付结果类型 export type PaymentResultType = 'url' | 'qrcode' | 'json' | 'address' | 'direct'; // 货币类型 export type Currency = 'CNY' | 'USD' | 'EUR' | 'USDT'; /** * 创建订单请求参数 */ export interface CreateOrderParams { userId: string; title: string; amount: number; // 金额(元) currency?: Currency; productId?: string; productType?: 'section' | 'fullbook' | 'membership' | 'vip'; extraParams?: Record; } /** * 订单信息 */ export interface Order { sn: string; // 订单号 userId: string; title: string; priceAmount: number; // 原价(分) payAmount: number; // 应付金额(分) currency: Currency; status: OrderStatus; productId?: string; productType?: string; extraData?: Record; paidAt?: Date; closedAt?: Date; expiredAt?: Date; createdAt: Date; updatedAt: Date; } /** * 发起支付请求参数 */ export interface CheckoutParams { orderSn: string; gateway: PaymentGateway; returnUrl?: string; openid?: string; // 微信JSAPI需要 coinAmount?: number; // 虚拟币抵扣 } /** * 创建交易请求数据 */ export interface CreateTradeData { goodsTitle: string; goodsDetail?: string; tradeSn: string; orderSn: string; amount: number; // 金额(分) notifyUrl: string; returnUrl?: string; platformType?: string; // web/wap/jsapi/native/h5/app createIp?: string; openId?: string; attach?: Record; } /** * 支付交易结果 */ export interface TradeResult { type: PaymentResultType; payload: string | Record; tradeSn: string; expiration?: number; // 过期时间(秒) amount?: number; coinDeducted?: number; prepayId?: string; // 微信预支付ID } /** * 回调解析结果 */ export interface NotifyResult { status: 'paying' | 'paid' | 'closed' | 'refunded' | 'failed'; tradeSn: string; platformSn: string; payAmount: number; // 分 payTime: Date; currency: Currency; attach?: Record; rawData?: Record; } /** * 交易流水 */ export interface PayTrade { id?: string; tradeSn: string; orderSn: string; userId: string; title: string; amount: number; // 分 cashAmount: number; // 现金支付金额(分) coinAmount: number; // 虚拟币抵扣金额 currency: Currency; platform: PaymentPlatform; platformType?: string; platformSn?: string; platformCreatedParams?: Record; platformCreatedResult?: Record; status: TradeStatus; type: TradeType; payTime?: Date; notifyData?: Record; sellerId?: string; createdAt: Date; updatedAt: Date; } /** * 退款记录 */ export interface Refund { id?: string; refundSn: string; tradeSn: string; orderSn: string; amount: number; // 分 reason?: string; status: 'pending' | 'processing' | 'success' | 'failed'; platformRefundSn?: string; refundedAt?: Date; operatorId?: string; createdAt: Date; updatedAt: Date; } /** * 支付网关配置 */ export interface GatewayConfig { enabled: boolean; mode: 'sandbox' | 'production'; [key: string]: unknown; } /** * 支付宝配置 */ export interface AlipayConfig extends GatewayConfig { appId: string; pid: string; sellerEmail?: string; privateKey?: string; publicKey?: string; md5Key?: string; } /** * 微信支付配置 */ export interface WechatConfig extends GatewayConfig { appId: string; appSecret?: string; serviceAppId?: string; // 服务号AppID serviceSecret?: string; mchId: string; mchKey: string; certPath?: string; keyPath?: string; } /** * 统一响应格式 */ export interface PaymentResponse { code: number; message: string; data: T | null; } /** * 支付方式信息 */ export interface PaymentMethod { gateway: PaymentGateway; name: string; icon: string; enabled: boolean; available: boolean; // 当前环境是否可用 } /** * 支付异常 */ export class PaymentException extends Error { constructor(message: string, public code?: string) { super(message); this.name = 'PaymentException'; } } export class SignatureError extends PaymentException { constructor(message = '签名验证失败') { super(message, 'SIGNATURE_ERROR'); this.name = 'SignatureError'; } } export class AmountMismatchError extends PaymentException { constructor(message = '金额不匹配') { super(message, 'AMOUNT_MISMATCH'); this.name = 'AmountMismatchError'; } } export class GatewayNotFoundError extends PaymentException { constructor(gateway: string) { super(`不支持的支付网关: ${gateway}`, 'GATEWAY_NOT_FOUND'); this.name = 'GatewayNotFoundError'; } } /** * 工具函数:元转分 */ export function yuanToFen(yuan: number): number { return Math.round(yuan * 100); } /** * 工具函数:分转元 */ export function fenToYuan(fen: number): number { return Math.round(fen) / 100; } /** * 生成订单号 * 格式: YYYYMMDD + 6位随机数 */ export function generateOrderSn(prefix = ''): string { const date = new Date(); const dateStr = date.toISOString().slice(0, 10).replace(/-/g, ''); const random = Math.floor(Math.random() * 1000000).toString().padStart(6, '0'); return `${prefix}${dateStr}${random}`; } /** * 生成交易流水号 * 格式: T + YYYYMMDDHHMMSS + 5位随机数 */ export function generateTradeSn(prefix = 'T'): string { const now = new Date(); const timestamp = now.toISOString() .replace(/[-:T]/g, '') .slice(0, 14); const random = Math.floor(Math.random() * 100000).toString().padStart(5, '0'); return `${prefix}${timestamp}${random}`; }