/** * 支付网关工厂 (Payment Gateway Factory) * 统一管理所有支付网关,实现工厂模式 * * 作者: 卡若 * 版本: v4.0 */ import { CreateTradeData, TradeResult, NotifyResult, PaymentPlatform, PaymentGateway, GatewayNotFoundError, PaymentMethod } from './types'; /** * 抽象支付网关基类 */ export abstract class AbstractGateway { protected config: Record; constructor(config: Record = {}) { this.config = config; } /** * 创建交易 */ abstract createTrade(data: CreateTradeData): Promise; /** * 验证签名 */ abstract verifySign(data: Record): boolean; /** * 解析回调数据 */ abstract parseNotify(data: string | Record): NotifyResult; /** * 关闭交易 */ abstract closeTrade(tradeSn: string): Promise; /** * 查询交易 */ abstract queryTrade(tradeSn: string): Promise; /** * 发起退款 */ abstract refund(tradeSn: string, refundSn: string, amount: number, reason?: string): Promise; /** * 回调成功响应 */ successResponse(): string { return 'success'; } /** * 回调失败响应 */ failResponse(): string { return 'fail'; } } // 网关类型映射 type GatewayClass = new (config: Record) => AbstractGateway; /** * 支付网关工厂 */ export class PaymentFactory { private static gateways: Map = new Map(); /** * 注册支付网关 */ static register(name: string, gatewayClass: GatewayClass): void { this.gateways.set(name, gatewayClass); console.log(`[PaymentFactory] 注册支付网关: ${name}`); } /** * 创建支付网关实例 * @param gateway 网关名称,格式如 'wechat_jsapi',会取下划线前的部分 */ static create(gateway: PaymentGateway | string): AbstractGateway { const gatewayName = gateway.split('_')[0] as PaymentPlatform; const GatewayClass = this.gateways.get(gatewayName); if (!GatewayClass) { throw new GatewayNotFoundError(gateway); } const config = this.getGatewayConfig(gatewayName); return new GatewayClass(config); } /** * 获取网关配置 */ private static getGatewayConfig(gateway: PaymentPlatform): Record { const configMap: Record Record> = { alipay: () => ({ // 支付宝新版接口需要 app_id,如果没有配置则使用 pid(旧版兼容) appId: process.env.ALIPAY_APP_ID || process.env.ALIPAY_PID || '2088511801157159', pid: process.env.ALIPAY_PID || '2088511801157159', sellerEmail: process.env.ALIPAY_SELLER_EMAIL || 'zhengzhiqun@vip.qq.com', privateKey: process.env.ALIPAY_PRIVATE_KEY || '', publicKey: process.env.ALIPAY_PUBLIC_KEY || '', md5Key: process.env.ALIPAY_MD5_KEY || 'lz6ey1h3kl9zqkgtjz3avb5gk37wzbrp', enabled: process.env.ALIPAY_ENABLED === 'true', mode: process.env.ALIPAY_MODE || 'production', }), wechat: () => ({ // 微信支付需要使用绑定了支付功能的服务号AppID appId: process.env.WECHAT_APPID || 'wx7c0dbf34ddba300d', // 服务号AppID(已绑定商户号) appSecret: process.env.WECHAT_APP_SECRET || 'f865ef18c43dfea6cbe3b1f1aebdb82e', serviceAppId: process.env.WECHAT_SERVICE_APPID || 'wx7c0dbf34ddba300d', serviceSecret: process.env.WECHAT_SERVICE_SECRET || 'f865ef18c43dfea6cbe3b1f1aebdb82e', mchId: process.env.WECHAT_MCH_ID || '1318592501', mchKey: process.env.WECHAT_MCH_KEY || 'wx3e31b068be59ddc131b068be59ddc2', certPath: process.env.WECHAT_CERT_PATH || '', keyPath: process.env.WECHAT_KEY_PATH || '', enabled: process.env.WECHAT_ENABLED === 'true', mode: process.env.WECHAT_MODE || 'production', }), paypal: () => ({ clientId: process.env.PAYPAL_CLIENT_ID || '', clientSecret: process.env.PAYPAL_CLIENT_SECRET || '', mode: process.env.PAYPAL_MODE || 'sandbox', enabled: process.env.PAYPAL_ENABLED === 'true', }), stripe: () => ({ publicKey: process.env.STRIPE_PUBLIC_KEY || '', secretKey: process.env.STRIPE_SECRET_KEY || '', webhookSecret: process.env.STRIPE_WEBHOOK_SECRET || '', mode: process.env.STRIPE_MODE || 'test', enabled: process.env.STRIPE_ENABLED === 'true', }), usdt: () => ({ gatewayType: process.env.USDT_GATEWAY_TYPE || 'nowpayments', apiKey: process.env.NOWPAYMENTS_API_KEY || '', ipnSecret: process.env.NOWPAYMENTS_IPN_SECRET || '', enabled: process.env.USDT_ENABLED === 'true', }), coin: () => ({ rate: parseInt(process.env.COIN_RATE || '100', 10), enabled: process.env.COIN_ENABLED === 'true', }), }; return configMap[gateway]?.() || {}; } /** * 获取已启用的支付网关列表 */ static getEnabledGateways(): PaymentMethod[] { const methods: PaymentMethod[] = []; // 支付宝 if (process.env.ALIPAY_ENABLED === 'true' || true) { // 默认启用 methods.push({ gateway: 'alipay_wap', name: '支付宝', icon: '/icons/alipay.png', enabled: true, available: true, }); } // 微信支付 if (process.env.WECHAT_ENABLED === 'true' || true) { // 默认启用 methods.push({ gateway: 'wechat_native', name: '微信支付', icon: '/icons/wechat.png', enabled: true, available: true, }); } // PayPal if (process.env.PAYPAL_ENABLED === 'true') { methods.push({ gateway: 'paypal', name: 'PayPal', icon: '/icons/paypal.png', enabled: true, available: true, }); } // Stripe if (process.env.STRIPE_ENABLED === 'true') { methods.push({ gateway: 'stripe', name: 'Stripe', icon: '/icons/stripe.png', enabled: true, available: true, }); } // USDT if (process.env.USDT_ENABLED === 'true') { methods.push({ gateway: 'usdt', name: 'USDT (TRC20)', icon: '/icons/usdt.png', enabled: true, available: true, }); } return methods; } /** * 检查网关是否已注册 */ static hasGateway(name: string): boolean { return this.gateways.has(name); } /** * 获取所有已注册的网关名称 */ static getRegisteredGateways(): string[] { return Array.from(this.gateways.keys()); } } // 导出便捷函数 export function createPaymentGateway(gateway: PaymentGateway | string): AbstractGateway { return PaymentFactory.create(gateway); }