You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Nest JS的支付服务:如何按支付方式动态注入仓储依赖

在NestJS中实现支付服务的动态仓储依赖注入

1. 标准化抽象仓储契约

先明确抽象仓储的统一接口(TypeScript接口无法用于NestJS依赖注入,因此用抽象类),确保所有具体实现遵循同一规范:

// src/payment/repositories/payment.repository.ts
export abstract class PaymentRepository {
  abstract createPixCharge(data: any): Promise<string>; // 返回巴西银行通用支付码
  abstract createBoletoCharge(data: any): Promise<string>;
  abstract createCreditCardCharge(data: any): Promise<string>;
}

2. 实现网关-specific仓储类

针对每个支付网关,创建对应仓储实现,直接调用你已开发的createPixCharge等服务:

PagSeguro仓储实现

// src/payment/repositories/pagseguro-payment.repository.ts
import { Injectable } from '@nestjs/common';
import { PaymentRepository } from './payment.repository';
import { createPixCharge, createBoletoCharge, createCreditCardCharge } from '../services/pagseguro.services';

@Injectable()
export class PagSeguroPaymentRepository implements PaymentRepository {
  async createPixCharge(data: any): Promise<string> {
    return createPixCharge(data);
  }

  async createBoletoCharge(data: any): Promise<string> {
    return createBoletoCharge(data);
  }

  async createCreditCardCharge(data: any): Promise<string> {
    return createCreditCardCharge(data);
  }
}

PayPal仓储实现(示例)

// src/payment/repositories/paypal-payment.repository.ts
import { Injectable } from '@nestjs/common';
import { PaymentRepository } from './payment.repository';
import { createCreditCardCharge } from '../services/paypal.services';

@Injectable()
export class PayPalPaymentRepository implements PaymentRepository {
  async createPixCharge(data: any): Promise<string> {
    throw new Error('PayPal不支持PIX支付');
  }

  async createBoletoCharge(data: any): Promise<string> {
    throw new Error('PayPal不支持Boleto支付');
  }

  async createCreditCardCharge(data: any): Promise<string> {
    return createCreditCardCharge(data);
  }
}

3. 用工厂模式实现动态注入

在NestJS模块中通过useFactory定义动态提供者,根据请求上下文或配置参数选择对应仓储实例:

// src/payment/payment.module.ts
import { Module, Provider } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';
import { PaymentRepository } from './repositories/payment.repository';
import { PagSeguroPaymentRepository } from './repositories/pagseguro-payment.repository';
import { PayPalPaymentRepository } from './repositories/paypal-payment.repository';

const PaymentRepositoryProvider: Provider = {
  provide: PaymentRepository,
  useFactory: (request: Request) => {
    // 从请求体/参数中获取用户选择的网关标识
    const { gateway } = request.body;
    
    switch(gateway) {
      case 'pagseguro':
        return new PagSeguroPaymentRepository();
      case 'paypal':
        return new PayPalPaymentRepository();
      default:
        throw new Error('不支持的支付网关');
    }
  },
  inject: [REQUEST], // 注入请求对象实现请求级动态选择
};

@Module({
  providers: [
    PaymentRepositoryProvider,
    // 注册你已开发的各网关支付服务
  ],
  exports: [PaymentRepository],
})
export class PaymentModule {}

4. 关联业务服务与仓储

在核心业务服务中直接依赖抽象仓储,NestJS会自动注入对应网关的具体实现:

// src/payment/services/payment.service.ts
import { Injectable } from '@nestjs/common';
import { PaymentRepository } from '../repositories/payment.repository';

@Injectable()
export class PaymentService {
  constructor(
    private readonly paymentRepository: PaymentRepository,
  ) {}

  async createCharge(paymentMethod: string, data: any): Promise<string> {
    switch(paymentMethod) {
      case 'pix':
        return this.paymentRepository.createPixCharge(data);
      case 'boleto':
        return this.paymentRepository.createBoletoCharge(data);
      case 'credit_card':
        return this.paymentRepository.createCreditCardCharge(data);
      default:
        throw new Error('不支持的支付方式');
    }
  }
}

可选:按支付方式拆分仓储优化扩展性

如果后续需要更细粒度的扩展,可按支付方式拆分抽象仓储(如PixRepository、BoletoRepository),用自定义token注册不同网关的实现,再通过工厂动态选择,进一步降低耦合。

内容的提问来源于stack exchange,提问作者Felipe Leal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:32:39