Stripe
如何设置和使用 Stripe 处理支付和订阅
MinuteShip 使用 Stripe 进行支付管理,支持一次性支付和订阅支付。
设置
MinuteShip 模板默认提供三种价格计划:免费计划、专业版订阅计划(月度/年度)和终身计划(一次性支付),按照以下步骤设置:
创建 Stripe 账户
在 stripe.com 创建 Stripe 账户。
获取 API 密钥
从 Stripe 控制台获取您的 API 密钥:
- 进入到 Stripe 控制台 >
Developers>API keys - 复制密钥(注意:测试模式以
sk_test_开头,生产模式以sk_live_开头) - 将其保存到环境变量文件中作为
STRIPE_SECRET_KEY
设置 Webhook
设置 Webhook 并获取您的 Webhook 密钥:
- 进入到 Stripe 控制台 >
Developers>Webhooks - 点击
Add endpoint - 输入 Webhook URL:
https://YOUR-DOMAIN.com/api/webhooks/stripe - 选择要监听的事件:
invoice.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcharge.refunded
- 点击
Reveal查看 Webhook 签名密钥(以whsec_开头) - 将其保存到环境变量文件中作为
STRIPE_WEBHOOK_SECRET
创建产品和价格计划
在 Stripe 中创建产品并设置价格计划:
- 进入到 Stripe 控制台 >
Product Catalog - 创建专业版订阅计划的产品:
- 点击
Add product - 名称:
专业版计划 - 描述:
具有订阅价格的高级功能 - 添加月度价格:
- 点击
添加价格 - 价格:$9.90(货币选择 USD)
- 定期:月度
- 保存并复制价格 ID(以
price_开头),这将用于VITE_STRIPE_PRICE_PRO_MONTHLY
- 点击
- 添加年度价格:
- 点击
Add price - 价格:$99.00(货币选择 USD)
- 定期:年度
- 保存并复制价格 ID(以
price_开头),这将用于VITE_STRIPE_PRICE_PRO_YEARLY
- 点击
- 点击
- 创建终身计划的产品:
- 点击
Add product - 名称:
终身计划 - 描述:
终身访问的一次性支付 - 添加价格:
- 价格:$199.00(货币选择 USD)
- 类型:一次性
- 保存并复制价格 ID(以
price_开头),这将用于VITE_STRIPE_PRICE_LIFETIME
- 点击
添加环境变量
添加以下环境变量:
.env
# 支付提供商
VITE_PAYMENT_PROVIDER=stripe
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Price plans
VITE_STRIPE_PRICE_PRO_MONTHLY=price_...
VITE_STRIPE_PRICE_PRO_YEARLY=price_...
VITE_STRIPE_PRICE_LIFETIME=price_...
更新网站配置
更新 src/config/website.ts 中的 payment 部分,配置价格计划 — 金额、货币、周期和计划元数据。enable、provider 和 priceId 字段会根据环境变量(VITE_PAYMENT_PROVIDER 和 VITE_STRIPE_PRICE_*)自动解析,无需硬编码。
您必须配置此部分,使其与您在 Stripe 中创建的产品和价格一致:
src/config/website.ts
payment: {
enable: isPaymentEnabled, // ← 自动:当 VITE_PAYMENT_PROVIDER 设置时为 true
provider: isPaymentEnabled ? paymentProvider : undefined, // ← 自动:'stripe'
price: {
plans: {
free: {
id: 'free',
prices: [],
isFree: true,
isLifetime: false,
},
pro: {
id: 'pro',
prices: [
{
type: 'subscription',
priceId: priceIds.proMonthly, // ← 自动:来自 VITE_STRIPE_PRICE_PRO_MONTHLY
amount: 990, // 金额,单位为分($9.90)
currency: 'USD',
interval: 'month',
},
{
type: 'subscription',
priceId: priceIds.proYearly, // ← 自动:来自 VITE_STRIPE_PRICE_PRO_YEARLY
amount: 9900, // 金额,单位为分($99.00)
currency: 'USD',
interval: 'year',
},
],
isFree: false,
isLifetime: false,
popular: true,
},
lifetime: {
id: 'lifetime',
prices: [
{
type: 'one_time',
priceId: priceIds.lifetime, // ← 自动:来自 VITE_STRIPE_PRICE_LIFETIME
amount: 19900, // 金额,单位为分($199.00)
currency: 'USD',
allowPromotionCode: true,
},
],
isFree: false,
isLifetime: true,
},
},
},
},
Note
如果您正在设置环境,现在可以回到环境配置文档并继续。本文档的其余部分可以稍后阅读。
- 环境配置: 设置环境变量
核心功能
- 一次性支付成为终身会员功能
- 定期订阅支付(月度/年度)
- 支持免费试用期
- 订阅管理与客户门户集成
- 支付事件的 Webhook 处理
- 订阅状态的跟踪和验证功能
- 内置价格组件(表格、卡片、按钮)
- 安全支付操作的服务器端操作
- 多种价格计划支持(免费、专业版、终身制)
开发环境
对于本地开发,您可以使用 Stripe CLI 将事件转发到您的本地服务器:
按照 Stripe CLI 文档完成安装,然后登录到与 STRIPE_SECRET_KEY 相同的 Stripe 测试模式账户:
stripe login
将事件转发到您的本地服务器:
stripe listen \
--skip-update \
--events checkout.session.completed,customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,invoice.paid,charge.refunded \
--forward-to http://localhost:3000/api/webhooks/stripe
CLI 会输出一个临时 Webhook 签名密钥。将它复制到 .env.local,然后重启开发服务器:
STRIPE_WEBHOOK_SECRET=whsec_...
模板还提供 Stripe 测试模式 E2E 套件:
pnpm e2e:stripe
支付确认与事件顺序
invoice.paid 是 Stripe 支付成功的权威事件。checkout.session.completed 用于创建本地支付上下文,但不会单独授予访问权限。
Stripe 不保证事件投递顺序。如果 invoice.paid 先到达,MinuteShip 会在本次请求中还原 Checkout Session 并创建已支付记录。支付结果页随后按 Checkout Session ID 和当前登录用户查找记录,不需要等待 Stripe 再次投递。
该流程也支持完全折扣的 Lifetime 结账。零金额订单没有 PaymentIntent,因此 MinuteShip 会通过生成的 Invoice 和客户信息完成匹配。
Webhook 响应与重试
| 结果 | HTTP 状态码 |
|---|---|
| 支付功能未启用 | 200 |
| Stripe 不是当前配置的支付提供商 | 404 |
缺少负载或 Stripe-Signature 请求头 | 400 |
| 签名无效 | 400 |
| 处理成功或安全地忽略重复事件 | 200 |
| Stripe API 或数据库临时故障 | 500 |
MinuteShip 会对临时故障返回 500,让 Stripe 重试。重复投递会以幂等方式处理。
客户门户
Stripe 客户门户提供了一个托管门户,供客户管理他们的订阅。您可以自定义外观和可用功能。
- 进入到 Stripe 控制台 >
Settings>Billing>Customer Portal - 自定义客户门户界面显示的内容,例如,您可以添加一个自定义的 logo 和标题
- 点击
Save changes保存门户配置
生产环境
- 进入到 Stripe 控制台 > 开发者 > Webhooks
- 点击
添加端点 - 输入 Webhook URL:
https://YOUR-DOMAIN.com/api/webhooks/stripe - 选择要监听的事件:
invoice.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcharge.refunded
- 创建后,点击
显示查看 Webhook 签名密钥 - 复制 Webhook 签名密钥(以
whsec_开头)并将其添加到您的环境变量中
Note
Lifetime 购买发生全额退款时,只会撤销对应订单的权限并将其标记为已取消;部分退款不会撤销权限。请保持启用
charge.refunded,否则 MinuteShip 无法收到退款状态。
测试卡
要测试 Stripe 集成,请使用 Stripe 的测试模式和测试信用卡:
- 4242 4242 4242 4242 - 成功支付
- 4000 0000 0000 3220 - 需要 3D 安全认证
- 4000 0000 0000 9995 - 资金不足失败
您可以在 Stripe 文档中找到更多关于 Stripe 测试卡 的信息。
创建发票
MinuteShip 已经为一次性支付配置了发票创建功能。
src/payment/provider/stripe.ts
// Automatically create invoice for one-time payments
checkoutParams.invoice_creation = {
enabled: true,
};
如果您想自动发送已付发票,您可以在Customer emails settings中启用它,在Email customers about下,选择Successful payments。之后,您可以在 Stripe 控制台 > 发票中访问发票。
您可以在 Stripe 文档中找到更多关于自动发送已付发票的信息。
支付流程图
这是完整的支付流程图。

常见问答
如何激活微信支付和支付宝?
您可以在 Stripe 控制台 > Settings > Payment methods 中激活微信支付和支付宝。您可以在 Stripe 文档中找到更多关于微信支付和支付宝的信息。
如何限制用户只能有一个订阅?
您可以在 Stripe 控制台 > Settings > Checkout and Payment Links > Subscriptions 中启用 Limit customers to 1 subscription,您可以在 Stripe 文档中找到更多关于限制用户只能有一个订阅的信息。
最佳实践
- 保护 API 密钥:永远不要在客户端代码中暴露您的 Stripe 密钥
- 验证 Webhook 签名:始终验证 Webhook 事件的签名
- 优雅处理错误:当支付失败时提供用户友好的错误消息
- 彻底测试 Webhooks:确保所有 Webhook 事件都得到正确处理