Files
soul/lib/payment/factory.ts

247 lines
6.7 KiB
TypeScript
Raw Normal View History

/**
* (Payment Gateway Factory)
*
*
* 作者: 卡若
* 版本: v4.0
*/
import {
CreateTradeData,
TradeResult,
NotifyResult,
PaymentPlatform,
PaymentGateway,
GatewayNotFoundError,
PaymentMethod
} from './types';
/**
*
*/
export abstract class AbstractGateway {
protected config: Record<string, unknown>;
constructor(config: Record<string, unknown> = {}) {
this.config = config;
}
/**
*
*/
abstract createTrade(data: CreateTradeData): Promise<TradeResult>;
/**
*
*/
abstract verifySign(data: Record<string, string>): boolean;
/**
*
*/
abstract parseNotify(data: string | Record<string, string>): NotifyResult;
/**
*
*/
abstract closeTrade(tradeSn: string): Promise<boolean>;
/**
*
*/
abstract queryTrade(tradeSn: string): Promise<NotifyResult | null>;
/**
* 退
*/
abstract refund(tradeSn: string, refundSn: string, amount: number, reason?: string): Promise<boolean>;
/**
*
*/
successResponse(): string {
return 'success';
}
/**
*
*/
failResponse(): string {
return 'fail';
}
}
// 网关类型映射
type GatewayClass = new (config: Record<string, unknown>) => AbstractGateway;
/**
*
*/
export class PaymentFactory {
private static gateways: Map<string, GatewayClass> = 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<string, unknown> {
const configMap: Record<PaymentPlatform, () => Record<string, unknown>> = {
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);
}