如何在 React Native 中关闭 Stripe 保存支付方式功能
结论
可以关闭。普通的一次性支付在创建 PaymentIntent 时,不要设置 setup_future_usage,也不要使用 SetupIntent,或主动把 PaymentMethod 绑定到 Customer。
setup_future_usage='off_session' 不是关闭保存功能,作用正好相反。它会告诉 Stripe,这个支付方式以后可能用于用户不在线时的付款,因此 PaymentSheet 可能会显示保存支付方式的相关提示。
automatic_payment_methods={"enabled": false} 只控制 Stripe 是否自动选择支付方式,与保存功能无关。
正确配置方式
在服务端创建一次性支付的 PaymentIntent,省略 setup_future_usage:
const paymentIntent = await stripe.paymentIntents.create({
amount: 1999,
currency: 'usd',
payment_method_types: ['card'],
});
不要使用下面的配置:
const paymentIntent = await stripe.paymentIntents.create({
amount: 1999,
currency: 'usd',
payment_method_types: ['card'],
setup_future_usage: 'off_session',
});
如果需要继续使用自动支付方式,可以保留 automatic_payment_methods,但仍然不要传入 setup_future_usage:
const paymentIntent = await stripe.paymentIntents.create({
amount: 1999,
currency: 'usd',
automatic_payment_methods: {
enabled: true,
},
});
React Native 端按常规方式初始化 PaymentSheet:
const { error } = await initPaymentSheet({
merchantDisplayName: 'Example Store',
paymentIntentClientSecret,
});
if (error) {
console.error(error);
return;
}
const result = await presentPaymentSheet();
if (result.error) {
console.error(result.error);
}
是否保存支付方式由服务端创建的 Intent 决定,不能通过 React Native 客户端隐藏某个界面元素来控制。
如果页面仍然显示已保存的支付方式
通常是因为 PaymentSheet 配置了 Stripe Customer,例如:
await initPaymentSheet({
merchantDisplayName: 'Example Store',
paymentIntentClientSecret,
customerId,
customerEphemeralKeySecret,
});
传入 customerId 和 customerEphemeralKeySecret 后,PaymentSheet 会读取该 Customer 已绑定的支付方式。如果业务完全不需要管理客户级别的支付方式,可以不向 PaymentSheet 提供 Customer 配置:
await initPaymentSheet({
merchantDisplayName: 'Example Store',
paymentIntentClientSecret,
});
这样只会阻止 PaymentSheet 加载该 Customer 已保存的支付方式,不会自动删除之前已经绑定的 PaymentMethod。
已创建的 PaymentIntent 怎么处理
如果现有的 PaymentIntent 已设置:
setup_future_usage=off_session
建议重新创建一个没有设置 setup_future_usage 的 PaymentIntent,再使用新的 client_secret 初始化 PaymentSheet。不要传入空字符串、false 或自定义的 "none",这些都不是有效值。
还需要检查的地方
确认服务端没有执行以下操作:
await stripe.paymentMethods.attach(paymentMethodId, {
customer: customerId,
});
还要检查是否使用了 SetupIntent。SetupIntent 本来就是用来收集并保存支付方式,以便以后扣款的,不适用于纯一次性支付。
如果页面显示的是 Link 登录或保存信息入口,它和 setup_future_usage 控制的 Customer 支付方式保存并不是同一项功能。如果业务只允许银行卡支付,可以在创建 PaymentIntent 时明确指定支付方式:
const paymentIntent = await stripe.paymentIntents.create({
amount: 1999,
currency: 'usd',
payment_method_types: ['card'],
});
最终需要满足以下条件:
- 不设置
setup_future_usage - 不使用
SetupIntent - 不主动将
PaymentMethodattach 到Customer - 完全不需要已保存的支付方式时,不向 PaymentSheet 传入 Customer 配置
- 不使用
automatic_payment_methods控制保存功能,它处理的是支付方式选择问题
备注:内容仅供参考。
