LogoMkSaaS文档

支付

如何设置和使用 Stripe 处理支付和订阅

MkSaaS 使用 Stripe 进行支付处理和订阅管理。这种集成以灵活、开发者友好的方式来处理一次性支付和订阅支付功能。

设置

MkSaaS 模板默认提供三种价格计划:免费计划、专业版订阅计划(月度/年度)和终身计划(一次性支付),按照以下步骤设置:

  1. stripe.com 创建 Stripe 账户

  2. 从 Stripe 控制台获取您的 API 密钥:

    • 进入到 Stripe 控制台 > Developers > API keys
    • 复制秘密密钥(测试模式以 sk_test_ 开头,生产模式以 sk_live_ 开头)
    • 将其保存到 .env 文件中作为 STRIPE_SECRET_KEY
  3. 设置 Webhook 并获取您的 Webhook 秘密:

    • 进入到 Stripe 控制台 > Developers > Webhooks
    • 点击 Add endpoint
    • 输入 webhook URL:https://your-domain.com/api/webhooks/stripe
    • 选择要监听的事件:
      • checkout.session.completed
      • customer.subscription.created
      • customer.subscription.updated
      • customer.subscription.deleted
    • 点击 Reveal 查看 Webhook 签名秘密(以 whsec_ 开头)
    • 将其保存到 .env 文件中作为 STRIPE_WEBHOOK_SECRET

如果您想在开发环境中测试支付流程,您可以在 Webhooks 部分找到更多信息。

  1. 在 Stripe 中创建产品并设置价格计划:

    • 进入到 Stripe 控制台 > Product Catalog
    • 创建专业版订阅产品
      • 点击 Add product
      • 名称:专业版计划
      • 描述:具有订阅价格的高级功能
      • 添加月度价格
        • 点击 添加价格
        • 价格:$9.90(货币选择 USD)
        • 定期:月度
        • 保存并复制价格 ID(以 price_ 开头),这将用于 NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY
      • 添加年度价格
        • 点击 Add price
        • 价格:$99.00(货币选择 USD)
        • 定期:年度
        • 保存并复制价格 ID(以 price_ 开头),这将用于 NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY
    • 创建终身产品
      • 点击 Add product
      • 名称:终身计划
      • 描述:终身访问的一次性支付
      • 添加价格:
        • 价格:$199.00(货币选择 USD)
        • 类型:一次性
        • 保存并复制价格 ID(以 price_ 开头),这将用于 NEXT_PUBLIC_STRIPE_PRICE_LIFETIME

价格计划

  1. 添加以下环境变量:
.env
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

# 价格计划
NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_LIFETIME=price_...
  1. 设置 Stripe 客户门户:
  • 进入到 Stripe 控制台 > Settings > Billing > Customer Portal
  • 自定义客户门户界面显示的内容,例如,您可以添加一个自定义的 logo 和标题
  • 点击 Save changes 保存门户配置

客户门户

  1. 更新 website.tsx 文件以在支付配置中使用 Stripe 作为支付提供商,并在价格配置中配置您的价格计划
src/config/website.tsx
import { PaymentTypes, PlanIntervals } from '@/payment/types';

export const websiteConfig = {
  // ...其他配置
  payment: {
    provider: 'stripe', // 要使用的支付提供商
  },
  price: {
    plans: {
      free: {
        id: 'free',
        prices: [],
        isFree: true,
        isLifetime: false,
        credits: {
          enable: true,
          amount: 50,
          expireDays: 30,
        },
      },
      pro: {
        id: 'pro',
        prices: [
          {
            type: PaymentTypes.SUBSCRIPTION,
            priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY!,
            amount: 990,
            currency: 'USD',
            interval: PlanIntervals.MONTH,
          },
          {
            type: PaymentTypes.SUBSCRIPTION,
            priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY!,
            amount: 9900,
            currency: 'USD',
            interval: PlanIntervals.YEAR,
          },
        ],
        isFree: false,
        isLifetime: false,
        popular: true,
        credits: {
          enable: true,
          amount: 1000,
          expireDays: 30,
        },
      },
      lifetime: {
        id: 'lifetime',
        prices: [
          {
            type: PaymentTypes.ONE_TIME,
            priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_LIFETIME!,
            amount: 19900,
            currency: 'USD',
            allowPromotionCode: true,
          },
        ],
        isFree: false,
        isLifetime: true,
        credits: {
          enable: true,
          amount: 1000,
          expireDays: 30,
        },
      },
    },
  },
  // ...其他配置
}

如果您正在设置环境,现在可以回到环境配置文档并继续。本文档的其余部分可以稍后阅读。

环境配置

设置环境变量


支付系统架构

MkSaaS 中的支付系统设计包含以下组件:

index.ts
types.ts
README.md

这种模块化结构使得扩展新的支付方式、价格计划和 UI 组件扩展支付系统变得容易。

核心功能

  • 终身访问的一次性支付
  • 定期订阅支付(月度/年度)
  • 订阅管理与客户门户集成
  • 支付事件的 Webhook 处理
  • 订阅状态跟踪和验证
  • 内置价格组件(表格、卡片、按钮)
  • 安全支付操作的服务器端操作
  • 支付状态管理的 React Hook
  • 多种价格计划支持(免费、专业版、终身)

使用方法

MkSaaS 为处理结账会话和客户门户提供简单的实用方法:

import { createCheckout, createCustomerPortal } from '@/payment';

// 创建结账会话
const checkoutResult = await createCheckout({
  planId: 'pro',
  priceId: process.env.NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY!,
  customerEmail: 'user@example.com',
  successUrl: 'https://example.com/payment/success',
  cancelUrl: 'https://example.com/payment/cancel',
  metadata: { userId: 'user_123' },
});

// 重定向到结账 URL
window.location.href = checkoutResult.url;

// 创建客户门户会话
const portalResult = await createCustomerPortal({
  customerId: 'cus_123',
  returnUrl: 'https://example.com/account/billing',
});

// 重定向到门户 URL
window.location.href = portalResult.url;

Webhooks

Stripe Webhooks 对于处理异步事件(如成功支付和订阅更新)至关重要。

开发环境

对于本地开发,您可以使用 Stripe CLI 将事件转发到您的本地服务器:

pnpm install -g stripe/stripe-cli
npm install -g stripe/stripe-cli
yarn global add stripe/stripe-cli
brew install stripe/stripe-cli/stripe

登录到 Stripe:

stripe login

将事件转发到您的本地服务器:

stripe listen --forward-to localhost:3000/api/webhooks/stripe

Webhook 密钥在终端中打印,复制它并将其添加到 .env 文件中:

STRIPE_WEBHOOK_SECRET=whsec_...

您可以使用 Stripe CLI 触发测试事件,或在网站上测试事件:

stripe trigger checkout.session.completed
stripe trigger customer.subscription.created
stripe trigger customer.subscription.updated
stripe trigger customer.subscription.deleted

生产环境

  1. 进入到 Stripe 控制台 > 开发者 > Webhooks
  2. 点击 添加端点
  3. 输入 Webhook URL:https://your-domain.com/api/webhooks/stripe
  4. 选择要监听的事件:
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
  5. 创建后,点击 显示 查看 Webhook 签名密钥
  6. 复制 Webhook 签名密钥(以 whsec_ 开头)并将其添加到您的环境变量中

UI 组件

MkSaaS 包含用于处理支付的预构建 React 组件:

Server Action

MkSaaS 为支付操作提供 Server Action:

React Hooks

MkSaaS 为支付操作提供 React Hooks:

Webhook 事件

支付系统在 handleWebhookEvent 方法中处理这些 Webhook 事件:

src/payment/provider/stripe.ts
public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
  // 处理各种 Stripe webhook 事件的实现:
  // - checkout.session.completed
  // - customer.subscription.created
  // - customer.subscription.updated
  // - customer.subscription.deleted
}

自定义支付提供商

创建新的支付提供商

MkSaaS 使得使用新提供商扩展支付系统变得容易:

  1. src/payment/provider 目录中创建新文件
  2. types.ts 实现 PaymentProvider 接口
  3. index.ts 中更新提供商选择逻辑

新提供商的示例实现:

src/payment/provider/my-provider.ts
import {
  PaymentProvider,
  CreateCheckoutParams,
  CheckoutResult,
  CreatePortalParams,
  PortalResult,
  Subscription,
  getSubscriptionsParams
} from '@/payment/types';

export class MyProvider implements PaymentProvider {
  constructor() {
    // 初始化您的提供商
  }

  public async createCheckout(params: CreateCheckoutParams): Promise<CheckoutResult> {
    // 创建结账会话的实现
  }

  public async createCustomerPortal(params: CreatePortalParams): Promise<PortalResult> {
    // 创建客户门户的实现
  }

  public async getSubscriptions(params: getSubscriptionsParams): Promise<Subscription[]> {
    // 获取订阅的实现
  }

  public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
    // 处理 webhook 事件的实现
  }
}

然后在 index.ts 中更新提供商选择:

src/payment/index.ts
import { MyProvider } from './provider/my-provider';

export const initializePaymentProvider = (): PaymentProvider => {
  if (!paymentProvider) {
    if (websiteConfig.payment.provider === 'stripe') {
      paymentProvider = new StripeProvider();
    } else if (websiteConfig.payment.provider === 'my-provider') {
      paymentProvider = new MyProvider();
    } else {
      throw new Error(
        `不支持的支付提供商: ${websiteConfig.payment.provider}`
      );
    }
  }

  return paymentProvider;
};

测试卡

要测试 Stripe 集成,请使用 Stripe 的测试模式和测试信用卡:

  • 4242 4242 4242 4242 - 成功支付
  • 4000 0000 0000 3220 - 需要 3D 安全认证
  • 4000 0000 0000 9995 - 资金不足失败

您可以在 Stripe 文档中找到更多关于 Stripe 测试卡 的信息。

创建发票

MkSaaS 已经为一次性支付配置了发票创建功能。

src/payment/provider/stripe.ts
// 自动为一次性支付创建发票
checkoutParams.invoice_creation = {
  enabled: true,
};

如果您想自动发送已付发票,您可以在Customer emails settings中启用它,在Email customers about下,选择Successful payments

发票

之后,您可以在 Stripe 控制台 > 发票中访问发票。

您可以在 Stripe 文档中找到更多关于自动发送已付发票的信息。

常见问答

如何激活微信支付和支付宝?

您可以在 Stripe 控制台 > Settings > Payment methods 中激活微信支付和支付宝。

Payment Methods

您可以在 Stripe 文档中找到更多关于微信支付支付宝的信息。

最佳实践

  1. 保护 API 密钥:永远不要在客户端代码中暴露您的 Stripe 密钥
  2. 验证 Webhook 签名:始终验证 Webhook 事件的签名
  3. 优雅处理错误:当支付失败时提供用户友好的错误消息
  4. 使用幂等性密钥:使用幂等性密钥防止重复收费
  5. 彻底测试 Webhooks:确保所有 Webhook 事件都得到正确处理

视频教程

下一步

现在您了解了如何在 MkSaaS 中使用支付,您可能想要探索这些相关功能: