在电商、订阅服务等线上场景中,用户经常需要多次完成支付操作,如果每次支付都要求用户重新输入银行卡号、有效期、CVV等敏感信息,不仅会降低用户操作效率,还可能增加信息泄露的风险。Stripe的PaymentIntent API作为处理支付流程的核心接口,不仅支持完成单次支付,还能在合规的前提下安全保存用户的银行卡信息,实现后续支付的快速复用,同时避免开发者直接触碰敏感卡数据,满足PCI DSS合规要求。

PaymentIntent API核心概念
PaymentIntent是Stripe用来表示一次支付意图的对象,它跟踪整个支付流程的状态,从创建到最终完成或失败。使用PaymentIntent API处理支付时,敏感卡信息不会经过开发者的服务器,而是由Stripe的前端SDK直接收集并加密传输,开发者只需要通过API传递非敏感的支付元数据即可。
如果需要保存用户的银行卡信息用于后续复用,核心是通过setup_future_usage参数标记该PaymentIntent的支付方法可以被后续使用,同时配合Stripe的支付方式保存机制完成合规存储。
完整实现流程
1. 后端创建PaymentIntent
首先在服务端调用Stripe API创建PaymentIntent,设置setup_future_usage为off_session,表示允许该支付方式用于后续无用户交互的离线支付。
<?php
require 'vendor/autoload.php';
// 初始化Stripe客户端,替换为自己的密钥
StripeStripe::setApiKey('sk_test_xxxxxxxxxxxxxxxxxxxxxxxx');
// 创建PaymentIntent,标记支付方式可后续使用
$paymentIntent = StripePaymentIntent::create([
'amount' => 1000, // 金额,单位为分,这里表示10元
'currency' => 'cny', // 货币类型,人民币
'setup_future_usage' => 'off_session', // 允许后续无会话使用
'metadata' => [
'user_id' => 'user_123' // 关联的用户ID,用于后续查询
]
]);
// 返回客户端密钥给前端
echo json_encode(['clientSecret' => $paymentIntent->client_secret]);
?>
2. 前端收集卡信息并提交
前端使用Stripe JS SDK收集用户的银行卡信息,避免敏感数据经过自己的服务器。首先引入Stripe JS库,然后初始化Stripe实例,创建支付元素收集卡信息,最后确认支付。
// 引入Stripe JS后初始化
const stripe = Stripe('pk_test_xxxxxxxxxxxxxxxxxxxxxxxx');
const elements = stripe.elements();
// 创建卡信息收集元素
const cardElement = elements.create('card');
cardElement.mount('#card-element');
// 获取后端返回的客户端密钥
let clientSecret = '';
fetch('/create-payment-intent', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
clientSecret = data.clientSecret;
});
// 提交支付表单
const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: '张三' // 用户账单信息
}
}
});
if (error) {
console.error('支付失败:', error.message);
} else if (paymentIntent.status === 'succeeded') {
console.log('支付成功,卡信息已保存');
}
});
3. 保存支付方式关联
支付成功后,Stripe会自动将本次使用的支付方式(PaymentMethod)与对应的客户(Customer)关联,前提是你在创建PaymentIntent时关联了Customer对象,或者后续手动将PaymentMethod绑定到Customer。如果没有提前创建Customer,可以先创建Customer再绑定支付方式。
<?php
require 'vendor/autoload.php';
StripeStripe::setApiKey('sk_test_xxxxxxxxxxxxxxxxxxxxxxxx');
// 创建客户
$customer = StripeCustomer::create([
'email' => 'user@ippipp.com',
'name' => '张三'
]);
// 将支付成功的支付方式绑定到客户
$paymentMethod = StripePaymentMethod::retrieve('pm_xxxxxxxxxxxxxxxxxxxxxxxx');
$paymentMethod->attach(['customer' => $customer->id]);
// 也可以将客户的默认支付方式设置为当前卡
StripeCustomer::update($customer->id, [
'invoice_settings' => [
'default_payment_method' => $paymentMethod->id
]
]);
?>
4. 复用保存的银行卡信息支付
当用户后续需要再次支付时,不需要重新收集卡信息,直接使用之前保存的PaymentMethod ID发起支付即可,此时不需要用户再次输入卡信息,也不需要前端收集卡数据的步骤。
<?php
require 'vendor/autoload.php';
StripeStripe::setApiKey('sk_test_xxxxxxxxxxxxxxxxxxxxxxxx');
// 使用之前保存的支付方式发起新的支付
$newPaymentIntent = StripePaymentIntent::create([
'amount' => 2000, // 新的支付金额,20元
'currency' => 'cny',
'customer' => 'cus_xxxxxxxxxxxxxxxxxxxxxxxx', // 之前创建的用户ID
'payment_method' => 'pm_xxxxxxxxxxxxxxxxxxxxxxxx', // 之前保存的支付方式ID
'off_session' => true, // 表示无用户交互的支付
'confirm' => true, // 直接确认支付
'confirmation_method' => 'automatic'
]);
if ($newPaymentIntent->status === 'succeeded') {
echo '复用卡信息支付成功';
} else {
echo '支付状态:' . $newPaymentIntent->status;
}
?>
注意事项
- 所有敏感卡信息都由Stripe直接处理,开发者不要在自己的服务器存储卡号、CVV等信息,避免违反PCI合规要求。
setup_future_usage参数只能在创建PaymentIntent时设置,后续无法修改,需要根据业务场景提前规划。- 复用支付方式时如果支付失败,可能需要引导用户重新验证支付方式,避免直接重试导致支付被拒。
- 测试时可以使用Stripe提供的测试卡号,比如4242424242424242,有效期任意未来日期,CVV填任意三位数字。
常见问题
如何查看用户保存的所有支付方式?
可以通过Stripe API列出某个Customer下关联的所有PaymentMethod,前端展示时只显示卡的后四位和品牌即可,不要展示完整卡号。
<?php
$paymentMethods = StripePaymentMethod::all([
'customer' => 'cus_xxxxxxxxxxxxxxxxxxxxxxxx',
'type' => 'card'
]);
foreach ($paymentMethods->data as $pm) {
echo '卡品牌:' . $pm->card->brand . ' 后四位:' . $pm->card->last4 . PHP_EOL;
}
?>
用户想要删除保存的银行卡信息怎么办?
可以调用Stripe API detach支付方式,将其从Customer上解绑,这样该支付方式就无法再被复用。
<?php
StripePaymentMethod::retrieve('pm_xxxxxxxxxxxxxxxxxxxxxxxx')->detach();
echo '支付方式已删除';
?>
StripePaymentIntent_API银行卡信息保存支付复用支付安全修改时间:2026-06-19 10:00:17