NestJS集成Stripe支付时stripePaymentService依赖解析失败求助
完整错误信息
Error: Nest can't resolve dependencies of the stripePaymentService (?). Please make sure that the argument paymentIntentRepository at index [0] is available in the AppModule context.
Potential solutions:
- Is AppModule a valid NestJS module?
- If paymentIntentRepository is a provider, is it part of the current AppModule?
- If paymentIntentRepository is exported from a separate @Module, is that module imported within AppModule?
用户提供的代码片段
stripePaymentModule代码
/* eslint-disable prettier/prettier */ import { Module } from '@nestjs/common'; import { stripePaymentController } from './stripe-payment.controller'; import { stripePaymentService } from './stripe-payment.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { paymentIntent } from './entities/paymentIntent.entity'; import { ConfigModule } from '@nestjs/config'; @Module({ imports:[ ConfigModule.forRoot({ isGlobal: true, }), TypeOrmModule.forFeature([paymentIntent])], controllers: [stripePaymentController], providers: [stripePaymentService], exports: [stripePaymentService], }) export class stripePaymentModule {}
stripePaymentService代码
/* eslint-disable prettier/prettier */ import { Injectable, Logger } from '@nestjs/common'; import { InjectStripe } from 'nestjs-stripe'; import { ConfigService } from '@nestjs/config'; import Stripe from 'stripe'; import { paymentIntent } from './entities/paymentIntent.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; @Injectable() export class stripePaymentService { stripe: Stripe; logger = new Logger(stripePaymentService.name); constructor( @InjectRepository(paymentIntent) private readonly paymentIntent:Repository<paymentIntent>, ) {const stripeApiKey = process.env.STRIPE_SECRET_KEY; this.stripe = new Stripe(stripeApiKey, { apiVersion: '2022-11-15', });} async payment_intent(data: any, user) { const intent = await this.stripe.paymentIntents.create({ amount: data.amount, currency: data.currency, description: data.description, payment_method_types: ['card'], }); return await this.paymentIntent.save({'userId':user.userId, 'intent_response':JSON.stringify(intent)}) // return intent; } }
AppModule代码
/* eslint-disable prettier/prettier */ import { Module } from '@nestjs/common'; import { UsersModule } from './users/users.module'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthModule } from './auth/auth.module'; import { User } from './users/entities/user.entity'; import { PassportModule } from '@nestjs/passport'; import { MailModule } from './mail/mail.module'; import { FlightBookingModule } from './flight-booking/flight-booking.module'; import { TravelBookings } from './flight-booking/entities/bookingToken.entity'; import { stripePaymentService } from './stripe/stripe-payment.service'; import { stripePaymentController } from './stripe/stripe-payment.controller'; import { StripeModule } from 'nestjs-stripe'; import { stripePaymentModule } from './stripe/stripe-payment.module'; import { paymentIntent } from './stripe/entities/paymentIntent.entity'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true }), StripeModule.forRoot({ apiKey: process.env.STRIPE_API_KEY, apiVersion: '2022-11-15' }), TypeOrmModule.forRootAsync({ imports: [ConfigModule], useFactory: (configService: ConfigService) => ({ type: 'postgres', host: configService.get('DB_HOST'), port: +configService.get<number>('DB_PORT'), username: configService.get('DB_USERNAME'), password: configService.get('DB_PASSWORD'), database: configService.get('DB_NAME'), entities: [User, TravelBookings, paymentIntent], synchronize: true, }), inject: [ConfigService], }), PassportModule, UsersModule, AuthModule, MailModule, FlightBookingModule, stripePaymentModule ], controllers: [stripePaymentController], providers: [stripePaymentService], }) export class AppModule {}
核心原因:重复注册导致上下文冲突
你的AppModule中同时做了三件事:导入stripePaymentModule、注册stripePaymentService、注册stripePaymentController。Nest会尝试在AppModule的上下文实例化stripePaymentService,但AppModule中没有直接注册paymentIntentRepository(该Repository仅在stripePaymentModule的TypeOrmModule.forFeature([paymentIntent])中声明),因此触发依赖解析失败。
具体修复步骤
1. 移除AppModule中的重复注册
删除AppModule里controllers数组中的stripePaymentController,以及providers数组中的stripePaymentService。这些组件已经在stripePaymentModule中注册并导出,只需保留stripePaymentModule的导入即可。
修改后的AppModule关键部分:
@Module({ imports: [ // ... 其他保留的导入项 stripePaymentModule // 仅保留这个导入 ], // 移除以下两行重复注册代码 // controllers: [stripePaymentController], // providers: [stripePaymentService], }) export class AppModule {}
2. 优化stripePaymentModule的ConfigModule配置
由于AppModule已经全局注册了ConfigModule.forRoot({ isGlobal: true }),stripePaymentModule中无需重复注册,删除冗余配置:
@Module({ imports:[ // 删除这一段重复的全局Config注册 // ConfigModule.forRoot({ // isGlobal: true, // }), TypeOrmModule.forFeature([paymentIntent]) ], controllers: [stripePaymentController], providers: [stripePaymentService], exports: [stripePaymentService], }) export class stripePaymentModule {}
3. 可选:用@InjectStripe简化Stripe实例化
你已经导入了nestjs-stripe的StripeModule,可以直接通过@InjectStripe()注入Stripe实例,无需手动从环境变量取密钥初始化,代码更简洁:
@Injectable() export class stripePaymentService { logger = new Logger(stripePaymentService.name); constructor( @InjectRepository(paymentIntent) private readonly paymentIntentRepo: Repository<paymentIntent>, @InjectStripe() private readonly stripe: Stripe // 直接注入实例 ) {} async payment_intent(data: any, user) { const intent = await this.stripe.paymentIntents.create({ amount: data.amount, currency: data.currency, description: data.description, payment_method_types: ['card'], }); return await this.paymentIntentRepo.save({ userId: user.userId, intent_response: JSON.stringify(intent) }); } }
注意:确保StripeModule.forRoot中使用的密钥(STRIPE_API_KEY)与服务中原本使用的STRIPE_SECRET_KEY一致,避免密钥不匹配。
内容的提问来源于stack exchange,提问作者jatin

