























以下是一个标准的 Stripe 支付流程示意图,涵盖了从用户点击支付到最终完成的完整数据流向:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 用户端 │ │ 你的服务器 │ │ Stripe │
│ (浏览器/App)│ │ (后端API) │ │ (支付网关) │
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘
│ │ │
│ 1. 请求创建支付 │ │
│ ──────────────────────>│ │
│ │ │
│ │ 2. 创建 PaymentIntent │
│ │ ──────────────────────>│
│ │ │
│ │ 3. 返回 client_secret │
│ │ <──────────────────────│
│ │ │
│ 4. 返回 client_secret │ │
│ <──────────────────────│ │
│ │ │
│ 5. 用户填写支付信息 │ │
│ (Card Element) │ │
│ ───────────────────────────────────────────────>│
│ │ │
│ 6. Stripe.js 处理支付 │ │
│ <───────────────────────────────────────────────│
│ (显示成功/失败) │ │
│ │ │
│ │ 7. Webhook 通知 │
│ │ <──────────────────────│
│ │ (payment_intent.succeeded)
│ │ │
│ 8. 查询支付状态 │ │
│ ──────────────────────>│ │
│ │ 9. 返回订单确认 │
│ <──────────────────────│ │
│ │ │
client_secret给后端client_secret返回给前端,前端将其保存在内存中stripe.confirmCardPayment(client_secret, payment_method),将加密的支付信息直接发送到Stripe(注意:卡信息不经过你的服务器,直接发送给Stripe,这大大降低了你的PCI合规负担)payment_intent.succeeded)
用户 ──> 点击支付 ──> 后端创建Checkout Session ──> 302重定向到Stripe页面 ──>
用户输入卡信息 ──> 支付完成 ──> 重定向回你的网站(success_url/cancel_url) ──>
Stripe发送Webhook ──> 后端更新订单
优点:实现最快,PCI合规完全由Stripe负责
缺点:用户会离开你的网站
用户 ──> 在你网站填写表单 ──> 前端渲染Stripe组件 ──>
用户直接在当前页面支付 ──> 支付结果实时返回 ──>
Webhook异步确认
优点:用户体验最好,用户不离开你的网站
缺点:需要更多前端开发工作
用户订阅 ──> 创建订阅(含试用期) ──> 生成发票 ──>
首次支付 ──> 后续周期自动扣款 ──>
Webhook处理:invoice.paid(成功) / invoice.payment_failed(失败)
PaymentIntent状态机:
┌─────────────┐
│ requires_ │
│ payment_ │
│ method │
└──────┬──────┘
│ 用户提交支付信息
↓
┌─────────────┐
│ requires_ │
│ action │ ◄──── 3D Secure验证
│ (3DS) │
└──────┬──────┘
│ 验证通过
↓
┌─────────────┐
│ processing │ ────► 异步处理中
└──────┬──────┘
│ 成功 │ 失败
↓ ↓
┌─────────────┐ ┌─────────────┐
│ succeeded │ │ requires_ │
│ │ │ payment_ │
│ │ │ method │
└─────────────┘ └─────────────┘
idempotency_key,防止重复扣款requires_action状态时前端需调用handleCardAction// 前端
async function handlePayment() {
// 1. 获取clientSecret
const { clientSecret } = await fetch('/api/create-payment', {
method: 'POST',
body: JSON.stringify({ amount: 1000 })
}).then(r => r.json());
// 2. 确认支付
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
clientSecret,
confirmParams: { return_url: 'https://your-site.com/success' }
});
// 3. 处理结果
if (error) showError(error.message);
}
// 后端 - 创建PaymentIntent
app.post('/api/create-payment', async (req, res) => {
const paymentIntent = await stripe.paymentIntents.create({
amount: req.body.amount,
currency: 'usd',
automatic_payment_methods: { enabled: true }
});
res.json({ clientSecret: paymentIntent.client_secret });
});
// 后端 - Webhook处理器
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (req, res) => {
const sig = req.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
switch(event.type) {
case 'payment_intent.succeeded':
// 更新订单状态为已支付
break;
}
});
这个流程确保了支付的安全性和可靠性,同时将敏感信息处理交由Stripe负责,最大限度地减轻了你的PCI合规负担。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。