支付
如何设置和使用 Stripe 处理支付和订阅
MkSaaS 使用 Stripe 进行支付处理和订阅管理。这种集成以灵活、开发者友好的方式来处理一次性支付和订阅支付功能。
设置
MkSaaS 模板默认提供三种价格计划:免费计划、专业版订阅计划(月度/年度)和终身计划(一次性支付),按照以下步骤设置:
-
在 stripe.com 创建 Stripe 账户
-
从 Stripe 控制台获取您的 API 密钥:
- 进入到 Stripe 控制台 >
Developers
>API keys
- 复制秘密密钥(测试模式以
sk_test_
开头,生产模式以sk_live_
开头) - 将其保存到
.env
文件中作为STRIPE_SECRET_KEY
- 进入到 Stripe 控制台 >
-
设置 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
- 进入到 Stripe 控制台 >
如果您想在开发环境中测试支付流程,您可以在 Webhooks 部分找到更多信息。
-
在 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
- 点击
- 进入到 Stripe 控制台 >
- 添加以下环境变量:
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_...
- 设置 Stripe 客户门户:
- 进入到 Stripe 控制台 >
Settings
>Billing
>Customer Portal
- 自定义客户门户界面显示的内容,例如,您可以添加一个自定义的 logo 和标题
- 点击
Save changes
保存门户配置
- 更新
website.tsx
文件以在支付配置中使用 Stripe 作为支付提供商,并在价格配置中配置您的价格计划:
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 中的支付系统设计包含以下组件:
这种模块化结构使得扩展新的支付方式、价格计划和 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
生产环境
- 进入到 Stripe 控制台 > 开发者 > Webhooks
- 点击
添加端点
- 输入 Webhook URL:
https://your-domain.com/api/webhooks/stripe
- 选择要监听的事件:
checkout.session.completed
customer.subscription.created
customer.subscription.updated
customer.subscription.deleted
- 创建后,点击
显示
查看 Webhook 签名密钥 - 复制 Webhook 签名密钥(以
whsec_
开头)并将其添加到您的环境变量中
UI 组件
MkSaaS 包含用于处理支付的预构建 React 组件:
Server Action
MkSaaS 为支付操作提供 Server Action:
React Hooks
MkSaaS 为支付操作提供 React Hooks:
Webhook 事件
支付系统在 handleWebhookEvent
方法中处理这些 Webhook 事件:
public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
// 处理各种 Stripe webhook 事件的实现:
// - checkout.session.completed
// - customer.subscription.created
// - customer.subscription.updated
// - customer.subscription.deleted
}
自定义支付提供商
创建新的支付提供商
MkSaaS 使得使用新提供商扩展支付系统变得容易:
- 在
src/payment/provider
目录中创建新文件 - 从
types.ts
实现PaymentProvider
接口 - 在
index.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
中更新提供商选择:
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 已经为一次性支付配置了发票创建功能。
// 自动为一次性支付创建发票
checkoutParams.invoice_creation = {
enabled: true,
};
如果您想自动发送已付发票,您可以在Customer emails settings
中启用它,在Email customers about
下,选择Successful payments
。
之后,您可以在 Stripe 控制台 > 发票中访问发票。
您可以在 Stripe 文档中找到更多关于自动发送已付发票的信息。
常见问答
如何激活微信支付和支付宝?
您可以在 Stripe 控制台 > Settings
> Payment methods
中激活微信支付和支付宝。
您可以在 Stripe 文档中找到更多关于微信支付和支付宝的信息。
最佳实践
- 保护 API 密钥:永远不要在客户端代码中暴露您的 Stripe 密钥
- 验证 Webhook 签名:始终验证 Webhook 事件的签名
- 优雅处理错误:当支付失败时提供用户友好的错误消息
- 使用幂等性密钥:使用幂等性密钥防止重复收费
- 彻底测试 Webhooks:确保所有 Webhook 事件都得到正确处理
视频教程
下一步
现在您了解了如何在 MkSaaS 中使用支付,您可能想要探索这些相关功能: