
在开发涉及支付功能的应用程序时,许多开发者可能会考虑在自己的系统中存储用户的支付卡信息,以避免用户在每次交易时重复输入。然而,这种做法存在严重的安全隐患,并且违反了支付卡行业数据安全标准(pci dss)。
PCI DSS合规性要求: PCI DSS是一套由主要支付卡品牌(如Visa、Mastercard、American Express等)共同建立的安全标准,旨在确保所有处理、存储或传输持卡人数据的实体都维护一个安全的环境。如果您的应用程序自行存储了完整的支付卡号(PAN)、有效期、CVV等敏感信息,您将需要承担巨大的PCI DSS合规性责任,这通常意味着需要进行昂贵的审计、实施严格的安全措施,并可能需要达到PCI合规级别1或SAQ D(适用于处理大量交易的商家)。对于大多数非专业支付服务提供商的应用程序而言,满足这些要求几乎是不可能的,且风险极高。
数据泄露风险: 自行存储敏感卡数据会使您的系统成为潜在的攻击目标。一旦发生数据泄露,不仅会给用户带来经济损失和信任危机,还会给您的企业带来巨额罚款、法律诉讼和品牌声誉的严重损害。
因此,最佳实践是绝不自行存储敏感支付卡信息。Stripe等支付服务提供商提供了安全且合规的解决方案来处理和存储这些数据。
Stripe提供了一种安全且符合PCI DSS的方式来保存用户的支付卡信息,即通过将“支付方法”(PaymentMethod)关联到“客户”(Customer)对象。当用户完成一次支付时,您可以选择将此次使用的支付方法保存起来,以便后续无需用户再次输入卡信息即可发起支付。
核心概念:
实现流程:
创建Stripe Customer对象(如果不存在): 对于首次交易的用户,您应该在后端为他们创建一个Stripe Customer对象。这个Customer ID(cus_xxx)应该与您系统中的用户ID关联起来,并存储在您的数据库中。
// 示例:Spring Boot后端创建Stripe Customer
import com.stripe.Stripe;
import com.stripe.model.Customer;
import com.stripe.param.CustomerCreateParams;
public class StripeService {
static {
Stripe.apiKey = "sk_test_YOUR_SECRET_KEY"; // 替换为您的Stripe Secret Key
}
public String createCustomer(String email, String description) {
try {
CustomerCreateParams params = CustomerCreateParams.builder()
.setEmail(email)
.setDescription(description)
.build();
Customer customer = Customer.create(params);
return customer.getId(); // 返回客户ID,存储到您的数据库
} catch (StripeException e) {
// 错误处理
e.printStackTrace();
return null;
}
}
}创建带有setup_future_usage的PaymentIntent: 当您在后端创建PaymentIntent时,需要指定setup_future_usage参数。这个参数告诉Stripe,本次支付成功后,关联的PaymentMethod应该被保存起来以供未来使用。同时,也需要指定customer参数,将PaymentIntent与特定的Stripe Customer关联。
// 示例:Spring Boot后端创建PaymentIntent
import com.stripe.Stripe;
import com.stripe.model.PaymentIntent;
import com.stripe.param.PaymentIntentCreateParams;
public class StripeService {
static {
Stripe.apiKey = "sk_test_YOUR_SECRET_KEY";
}
public String createPaymentIntent(long amount, String currency, String customerId) {
try {
PaymentIntentCreateParams params = PaymentIntentCreateParams.builder()
.setAmount(amount) // 金额,以最小单位表示(例如:美分)
.setCurrency(currency)
.setCustomer(customerId) // 关联到Stripe Customer
.setSetupFutureUsage(PaymentIntentCreateParams.SetupFutureUsage.OFF_SESSION) // 表示为离线支付保存
.addPaymentMethodType("card") // 允许使用卡片支付
.build();
PaymentIntent paymentIntent = PaymentIntent.create(params);
return paymentIntent.getClientSecret(); // 返回Client Secret给前端
} catch (StripeException e) {
// 错误处理
e.printStackTrace();
return null;
}
}
}前端使用Stripe Elements和Payment Element进行支付确认: 前端使用Stripe.js v3和Payment Element收集卡信息。当用户提交支付时,调用stripe.confirmPayment方法,Stripe会处理卡信息的收集、令牌化和SCA流程。
// 示例:Angular前端代码片段
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { loadStripe, Stripe, StripeElements, StripePaymentElement } from '@stripe/stripe-js';
declare var stripe: Stripe; // 声明全局stripe对象
@Component({
selector: 'app-payment',
templateUrl: './payment.component.html',
styleUrls: ['./payment.component.css']
})
export class PaymentComponent implements OnInit {
private stripe: Stripe | null = null;
private elements: StripeElements | null = null;
private paymentElement: StripePaymentElement | null = null;
clientSecret: string = '';
constructor(private http: HttpClient) {}
async ngOnInit() {
// 1. 初始化Stripe对象
this.stripe = await loadStripe('pk_test_YOUR_PUBLISHABLE_KEY'); // 替换为您的Stripe Publishable Key
// 2. 从后端获取Client Secret
this.http.get<{ clientSecret: string }>('http://localhost:8080/api/payment/create-payment-intent')
.subscribe(response => {
this.clientSecret = response.clientSecret;
if (this.stripe) {
// 3. 初始化Elements
this.elements = this.stripe.elements({ clientSecret: this.clientSecret });
// 4. 创建并挂载Payment Element
this.paymentElement = this.elements.create('payment');
this.paymentElement.mount('#payment-element'); // 挂载到HTML中的一个div元素
}
});
}
async handlePayment() {
if (!this.stripe || !this.elements) {
return;
}
// 5. 确认支付
const { error, paymentIntent } = await this.stripe.confirmPayment({
elements: this.elements,
confirmParams: {
return_url: 'http://localhost:4200/payment-success', // 支付完成后重定向的URL
// 如果需要,可以添加 billing_details
// payment_method_data: {
// billing_details: {
// name: 'John Doe',
// email: 'john.doe@example.com'
// }
// }
},
redirect: 'if_required' // 如果需要SCA,Stripe会处理重定向
});
if (error) {
// 显示错误信息给用户
console.error(error.message);
} else if (paymentIntent && paymentIntent.status === 'succeeded') {
// 支付成功
console.log('Payment succeeded:', paymentIntent);
// 此时,PaymentMethod已经与Customer关联并保存
// paymentIntent.payment_method 会包含保存的PaymentMethod ID (pm_xxx)
// 您可以从paymentIntent.customer中获取Customer ID (cus_xxx)
alert('支付成功!PaymentMethod已保存。');
}
}
}<!-- 示例:Angular前端HTML模板 --> <div id="payment-element"> <!-- Stripe Payment Element 将在此处渲染 --> </div> <button (click)="handlePayment()">支付并保存卡片</button>
后续支付(使用已保存的PaymentMethod): 一旦PaymentMethod被保存并关联到Customer,您就可以在后续交易中通过payment_method参数直接引用它,而无需用户再次输入卡信息。
// 示例:Spring Boot后端使用已保存的PaymentMethod发起支付
import com.stripe.Stripe;
import com.stripe.model.PaymentIntent;
import com.stripe.param.PaymentIntentCreateParams;
public class StripeService {
static {
Stripe.apiKey = "sk_test_YOUR_SECRET_KEY";
}
public String createPaymentIntentWithSavedCard(long amount, String currency, String customerId, String paymentMethodId) {
try {
PaymentIntentCreateParams params = PaymentIntentCreateParams.builder()
.setAmount(amount)
.setCurrency(currency)
.setCustomer(customerId)
.setPaymentMethod(paymentMethodId) // 使用已保存的PaymentMethod ID
.setConfirm(true) // 直接确认支付
.setOffSession(true) // 表示这是一笔离线支付
.build();
PaymentIntent paymentIntent = PaymentIntent.create(params);
return paymentIntent.getId(); // 返回PaymentIntent ID
} catch (StripeException e) {
// 错误处理
e.printStackTrace();
return null;
}
}
}在前端,您通常不需要进行任何操作,因为这笔支付是在后端直接发起的。如果需要用户进行SCA,Stripe会通过Webhook或PaymentIntent的状态更新通知您,您可能需要引导用户完成认证。
通过遵循Stripe推荐的最佳实践,利用PaymentIntent、PaymentMethod和Customer对象,您可以安全、合规地实现支付卡信息的保存功能,极大地提升用户支付体验,同时避免了自行存储敏感数据的巨大风险和合规性负担。记住,安全是支付领域的核心,将敏感数据处理交给专业的支付服务提供商是明智之举。
以上就是Stripe PaymentIntent API 与安全存储支付卡信息教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号