NestJS 中的处理付款模块

将支付模块集成到您的 NestJS 应用程序中可以为您的用户实现无缝交易。在本指南中,我们将引导您将 **Stripe** 集成到您的 NestJS 应用程序中。

1.设置 NestJS 应用程序

首先设置您的 NestJS 项目。如果您还没有这样做,请安装 **NestJS CLI** 并创建一个新的应用程序:

npm i -g @nestjs/cli
nest new my-app

导航到新创建的项目目录:

cd my-app

2.安装 Stripe 和必要的软件包

为了集成 Stripe,我们需要安装 Stripe 包和其他必要的依赖项:

npm install stripe @nestjs/config
  • Stripe:Node.js 的官方 Stripe 包。
  • @nestjs/config:用于管理 NestJS 内的配置。
  • 3.配置 Stripe API 密钥

    获得必要的依赖项后,您需要配置 API 密钥。转到 Stripe 仪表板获取您的 **测试** 和 **实时** API 密钥。

    在项目根目录中创建一个 `.env` 文件来存储您的 Stripe 密钥:

    STRIPE_SECRET_KEY=your_stripe_secret_key_here
    STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret_here

    4. Stripe 中的 Webhook

    什么是 Webhook?

    Stripe 中的 **Webhook** 是 Stripe 向您的应用程序通知 Stripe 帐户中发生的事件的一种方式。这是一种机制,可让您从 Stripe 接收有关特定事件(例如成功付款、订阅续订、争议等)的实时更新。

    Webhook 有什么用途?

  • 实时通知:Webhook 允许 Stripe 在发生某些事件(例如付款成功或付款状态更新)时通知您的应用程序。
  • 处理付款成功或失败:例如,付款完成后,Stripe 会向您的 webhook 端点发送事件以通知您。这可以帮助您更新用户界面或采取适当的操作(例如发送确认电子邮件或更新订单状态)。
  • 安全性:Webhook 可确保您收到有关 Stripe 方面更改的通知,这样您就可以在后端安全地处理敏感的付款相关操作。
  • 异步处理:某些操作(如付款授权)可能需要一些时间来处理。Webhook 可确保一旦付款状态确定,即使用户已离开网站或通过其他方式(如移动钱包)付款,您也会收到通知。
  • 为什么 Webhooks 很重要?

  • 实时更新:即使用户没有主动与您的应用程序交互,它们也允许您的系统在事件发生时立即做出反应。
  • 准确性:Webhook 确保您的系统始终与 Stripe 同步,尤其是在付款或订阅状态发生变化时。
  • 可扩展性:您可以依靠 Stripe 通知您的系统有关关键事件,无需频繁轮询 Stripe 以获取更新。
  • 简而言之,webhook 对于在 Stripe 集成中以可扩展、实时和安全的方式处理付款和相关操作至关重要。

    5. 设置 Stripe 服务

    现在,让我们创建一个服务来处理 Stripe 支付请求,包括 webhook 验证。

    创建 Stripe 服务

    nest generate service stripe

    在 `stripe.service.ts` 中配置 Stripe 服务并实现 webhook 处理逻辑:

    import { Injectable, Logger } from '@nestjs/common';
    import Stripe from 'stripe';
    import { ConfigService } from '@nestjs/config';
    
    @Injectable()
    export class StripeService {
      private stripe: Stripe;
      private readonly logger = new Logger(StripeService.name);
    
      constructor(private configService: ConfigService) {
      const secretKey = this.configService.get('STRIPE_SECRET_KEY');
      this.stripe = new Stripe(secretKey, {
        apiVersion: '2022-08-01',
      });
      }
    
      async createPaymentIntent(amount: number) {
      return this.stripe.paymentIntents.create({
        amount,
        currency: 'usd',
      });
      }
    
      async handleWebhook(payload: any, sig: string) {
      const webhookSecret = this.configService.get('STRIPE_WEBHOOK_SECRET');
    
      try {
        const event = this.stripe.webhooks.constructEvent(payload, sig, webhookSecret);
    
        switch (event.type) {
        case 'payment_intent.succeeded':
          this.logger.log('Payment Intent was successful!', event.data.object);
          break;
        case 'payment_intent.failed':
          this.logger.log('Payment Intent failed!', event.data.object);
          break;
        // Handle other events
        default:
          this.logger.warn(`Unhandled event type: ${event.type}`);
        }
    
      } catch (err) {
        this.logger.error('Error verifying webhook signature', err);
        throw new Error('Webhook verification failed');
      }
      }
    }

    解释:

  • Stripe 初始化:我们使用环境配置中的密钥初始化 Stripe。
  • 付款意向创建:createPaymentIntent 函数将生成一个新的付款意向,我们可以使用它来处理付款。
  • Webhook 处理:handleWebhook 函数会监听 Stripe 事件(如 payment_intent.succeeded 或 payment_intent.failed)并进行相应处理。使用 webhook 密钥验证事件的真实性。
  • 6. 创建付款控制器

    为了处理付款请求,创建一个控制器:

    nest generate controller stripe

    在 `stripe.controller.ts` 中,创建一个端点来触发付款,并创建一个端点来接收来自 Stripe 的 webhook:

    import { Controller, Post, Body, Headers } from '@nestjs/common';
    import { StripeService } from './stripe.service';
    
    @Controller('payments')
    export class StripeController {
      constructor(private readonly stripeService: StripeService) {}
    
      @Post('create-payment-intent')
      async createPaymentIntent(@Body() body: { amount: number }) {
      return this.stripeService.createPaymentIntent(body.amount);
      }
    
      @Post('webhook')
      async handleWebhook(@Body() payload: any, @Headers() headers: any) {
      const sig = headers['stripe-signature'];
      return this.stripeService.handleWebhook(payload, sig);
      }
    }

    7. 测试支付模块

    要测试支付功能,请运行 NestJS 服务器:

    npm run start

    您现在可以向 `/payments/create-payment-intent` 端点发送一个 POST 请求,其中包含金额(以美分为单位)的 JSON 正文:

    {
      "amount": 5000
    }

    这将创建 50 美元的付款意向。您可以使用 **Postman** 或 **cURL** 等工具来测试 API。

    8. 前端集成

    后端设置完成后,您可以使用 Stripe 的 **Stripe.js** 和 **Elements** 来处理前端支付表单。有关在客户端集成 Stripe 的更多详细信息,请参阅 Stripe 的官方文档。

    结论

    在本教程中,我们成功地将 Stripe 的支付系统集成到 NestJS 应用程序中。此设置是一个起点,您可以根据业务需求进一步自定义它。通过此设置,您现在可以通过一种简单、安全的方式在 NestJS 应用程序中处理付款。