Stripe 新版删掉 payment_method_types:Checkout 与 Elements 升级到 2026-09-30.endive 要改哪几行
Endive 是 Stripe flora 命名版本序列的第五个版本(前四个是 Acacia、Basil、Clover、Dahlia)。2026-09-30.endive 是 Endive 这一轮里第一个带 breaking change 的版本,后续 Endive 版本只做增量改动。完整记录见 Endive changelog,历史版本在 changelog 首页。
这一版删了什么
三个参数被移除,指向同一件事:支付方式不再由集成代码写死,改由 Dashboard 的动态支付方式配置决定。
- Checkout Sessions 的
payment_method_types - Payment Intents 与 Setup Intents 的同名参数
payment_method_types - Elements 的
paymentMethodTypes选项
替代路径:Checkout 用 dynamic payment methods,或用 allowed_payment_method_types / excluded_payment_method_types 显式收窄;Elements 用 allowedPaymentMethodTypes,或直接在 Dashboard 里管理支付方式。
同期 GA 的能力
- v1 资源的 thin events:v1 API 资源现在普遍可用 thin events,事件负载轻量且与 API 版本解耦,webhook 集成更容易向前兼容。
- PaymentIntent 增加 Payment Record 属性:可以直接从 PaymentIntent 对象取到关联的 Payment Record。
- 新支付方式:SeQura(西班牙 BNPL);Checkout 中可保存 Bancontact 支付信息,用于后续 off-session 的 SEPA Direct Debit 扣款。
- Billing:classic billing 模式下的 Invoice Item 提供 proration 明细;Invoice Item 支持 invoicing rules;Invoice 增加 uncollectible 状态详情。
- Connect 到期要求报错:Accounts、Persons、Capabilities API 对「将来才到期」的 requirements 也会返回错误,不再只报当前或已过期的。
breaking change 清单里其余部分
- 3D Secure 支持 Data Share Only
- Payment Evaluation 的 signal scores 变为可空
- Payment Methods 移除 PayTo 专用字段
- BLIK 支付失败返回更具体的 decline code
- 弃用 payment request button
- MB WAY、Bizum、BLIK 配合
stripe.handleNextAction时展示 pending-authorization UI - Checkout 中保存 Bancontact 支付信息供后续 off-session 使用
- 新增 Standalone 3D Secure API
- allowed payment method types 支持 card-present 支付方式
- 支付失败时返回支付方式类型信息
- Connect:Accounts v2 capabilities 增加 rejected 状态;Account Links v2 移除
configurations参数;统一 SEPA Direct Debit 支付设置;区分平台主动拒绝账户与 Stripe 拒绝 - Billing:统一 Subscriptions 与 Invoices 的计费周期锚点格式;支持按需暂停与恢复订阅;把订阅取消作为 pending update 的一部分来调度
迁移:实际要改的几行
Checkout 侧删掉白名单,需要收窄时改用新参数:
// 之前
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card'], // 已移除
line_items: [{ price, quantity: 1 }],
success_url,
});
// 现在
const session = await stripe.checkout.sessions.create({
mode: 'payment',
allowed_payment_method_types: ['card'], // 只在确实要收窄时写
line_items: [{ price, quantity: 1 }],
success_url,
});
Elements 初始化选项改名:
// 之前
stripe.elements({ paymentMethodTypes: ['card'] });
// 现在
stripe.elements({ allowedPaymentMethodTypes: ['card'] });
Payment Intents / Setup Intents 的服务端创建代码里,同样删掉 payment_method_types;支付方式由 Dashboard 的 dynamic payment methods 决定。
SDK 升级时把 API 版本写死成完整字符串:
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2026-09-30.endive',
});
几个容易踩的坑
写死的 card 白名单会直接失效。 参数已经不存在,继续传会报错,不是静默降级。散落在多个服务、脚本、定时任务里的创建调用都要一起搜出来改。
dynamic payment methods 的开关在 Dashboard,不在代码里。 测试环境和生产环境的配置不一定同步,常见现象是本地能付、线上少了支付方式。上线前把两边的支付方式列表对一遍。
用 webhook 判断支付方式时别依赖已删除的字段。 改看 payment_method.type,需要更完整信息时读 PaymentIntent 上新增的 Payment Record 属性。
API 版本是按账户维度生效的。 升级前确认账号当前锁定的版本,以及各 SDK / 各服务各自传入的 apiVersion,避免一部分请求已经走 2026-09-30.endive、另一部分还停在旧版本。