VibeAny Docs
支付

Stripe 接入

配置 Stripe Checkout、价格、Webhook、订阅,并在测试环境完成验收。

Stripe 是 Starter 内置的两个支付适配器之一。当前集成使用托管 Checkout、订阅到期取消、Customer Portal 和带签名的 Webhook。

1. 创建商品和价格

为 Starter 展示的每个订阅周期创建周期性价格,并为所有可见积分包创建一次性价格。复制 Stripe Price IDprice_...),不要使用 Product ID(prod_...)。

默认商品目录需要以下配置:

STRIPE_PRICE_STARTER_MONTHLY=price_xxx
STRIPE_PRICE_STARTER_ANNUAL=price_xxx
STRIPE_PRICE_PRO_MONTHLY=price_xxx
STRIPE_PRICE_PRO_ANNUAL=price_xxx
STRIPE_PRICE_CREDITS_SMALL=price_xxx
STRIPE_PRICE_CREDITS_MEDIUM=price_xxx
STRIPE_PRICE_CREDITS_LARGE=price_xxx

旧变量 STRIPE_PRICE_STARTERSTRIPE_PRICE_PRO 仍可作为月付价格的后备值,但新项目应使用明确的 _MONTHLY 变量名。

Enterprise 和落地页商品的环境变量只是扩展点。Enterprise 不在内置方案目录中,示例落地页权益也没有完整的结账履约逻辑。完成并测试对应商品行为前,不要公开这些 SKU。

2. 配置 Stripe

NEXT_PUBLIC_ENABLE_PAYMENTS=true
PAYMENTS_PROVIDER=stripe

STRIPE_SECRET_KEY=sk_test_xxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx

STRIPE_PRICE_STARTER_MONTHLY=price_xxx
STRIPE_PRICE_STARTER_ANNUAL=price_xxx
STRIPE_PRICE_PRO_MONTHLY=price_xxx
STRIPE_PRICE_PRO_ANNUAL=price_xxx
STRIPE_PRICE_CREDITS_SMALL=price_xxx
STRIPE_PRICE_CREDITS_MEDIUM=price_xxx
STRIPE_PRICE_CREDITS_LARGE=price_xxx

CRON_SECRET=replace_with_a_strong_random_server_secret

同一环境必须整套使用同一种模式的配置:

  • 测试模式 Secret Key 和 Publishable Key;
  • 测试模式 Price ID;
  • 测试端点或本地 Stripe CLI 生成的签名密钥。

完成生产环境验收后,再把整套配置一起切换为对应的生产模式值。绝不能把 STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETCRON_SECRET 暴露给浏览器代码。

内置 Stripe Checkout 适配器当前明确只请求卡支付。启用可能延迟完成的支付方式前,请先接入并测试异步支付事件。

3. 配置 Webhook

创建 Stripe Webhook 端点:

https://your-domain.com/api/payments/webhook

订阅以下事件:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.paid
  • invoice.payment_succeeded
  • invoice.payment_failed

该路由会基于未经修改的原始请求体校验 Stripe-Signature。把端点签名密钥写入 STRIPE_WEBHOOK_SECRET

本地转发可以使用:

stripe login
stripe listen --forward-to http://localhost:3000/api/payments/webhook

Stripe CLI 输出的签名密钥只能用于本地环境。

4. 结账与生命周期

请调用统一路由,不要调用服务商专用路由:

POST /api/payments/checkout
Content-Type: application/json

{ "skuKey": "credits_small" }
POST /api/payments/subscription/checkout
Content-Type: application/json

{ "planKey": "starter", "period": "month" }

结账适配器会把用户 ID 和商品目录元数据写入 Checkout Session;订阅结账还会把这些信息写入 subscription_data。订阅结账使用服务端生成的幂等键。

取消订阅会将 Stripe 订阅更新为 cancel_at_period_end: true。Customer Portal 使用订阅记录中保存的客户 ID 创建。即使以后切换了部署实例的当前支付服务商,这些操作仍会继续调用 Stripe。

成功跳转只会显示通用的成功通知,不会查询 Stripe,也不会发放积分。请等待 Webhook 完成处理,并检查持久状态。

5. 在测试模式验证

先运行静态检查和自动化测试:

npm run preflight
npm run test:unit

可选的托管结账冒烟测试会创建真实的 Stripe 测试模式 Checkout Session,但不会提交付款:

PAYMENT_PROVIDER_SANDBOX_E2E=true \
  E2E_TEST_EMAIL=<existing-test-user-email> \
  E2E_TEST_PASSWORD=<test-user-password> \
  PLAYWRIGHT_BASE_URL=https://<preview-or-test-origin> \
  npm run e2e -- tests/e2e/payment-provider-sandbox.spec.ts --project=chromium

本地服务应设置 PLAYWRIGHT_BASE_URL=http://localhost:3000。缺少任一测试凭证时,该测试会主动 skip,因此命令显示绿色并不足以通过验收:测试摘要必须明确显示 2 passed0 skipped

完整验收还必须包括:

  1. 完成一笔 Stripe 测试支付;
  2. 事件已投递到公网 HTTPS Webhook;
  3. 从数据库回读订阅或积分账本;
  4. 重放重复事件,确认没有重复履约;
  5. 验证到期取消与 Customer Portal。

请阅读 Webhook、订阅与积分,了解持久履约模型。

本页目录