


























Stripe 的支付集成主要分为前端和后端两部分:前端负责安全收集支付信息(如使用 Stripe.js 或预构建的 Checkout 页面),后端负责处理敏感操作(如创建付款Intent)并通过 Webhook 接收异步事件。下面是一份从环境搭建到核心功能实现的开发说明,希望对你有帮助。
在开始编码之前,你需要完成 Stripe 账户的设置、安装官方 SDK 以及配置本地开发环境。
登录 Stripe 仪表盘,在左侧菜单的 开发者 > API 密钥 中可以找到你的密钥 。
pk_test_ 或 pk_live_ 开头。用于客户端,安全地识别你的 Stripe 账户 。sk_test_ 或 sk_live_ 开头。用于服务器端,必须严格保密,绝不能暴露在客户端代码或版本控制中 。在服务器端(Node.js 环境),你需要安装官方的 Stripe Node.js 库 :
npm install stripe --save
在客户端(如 React),你需要安装 Stripe.js 的 React 封装库 :
npm install @stripe/react-stripe-js @stripe/stripe-js
Stripe CLI 是一个强大的命令行工具,可以帮助你模拟事件、转发 Webhook 到本地服务器,无需部署即可调试 。
stripe login,在浏览器中完成授权 。http://localhost:3000/api/webhooks):bash stripe listen --forward-to localhost:3000/api/webhooks whsec_...),你需要将其配置在环境变量中 。服务器端是你的应用与 Stripe 进行安全通信的核心。所有的敏感操作,如创建 PaymentIntent、处理 Webhook,都应该在这里完成。
在你的后端代码中(例如 lib/stripe.js),使用你的 Secret Key 初始化 Stripe 客户端。建议采用懒加载模式,避免在构建时因缺少密钥而报错 。
import Stripe from 'stripe';
let _stripe = null;
const getStripe = () => {
if (!_stripe) {
_stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: ‘2023-10-16’, // 指定 API 版本
maxNetworkRetries: 2, // 网络问题自动重试
});
}
return _stripe;
};
export default getStripe;
PaymentIntent 代表一个面向客户的支付意图。当你需要自定义支付流程(如使用 Payment Element 或 Card Element)时,你需要先创建一个 PaymentIntent 并返回其 client_secret 给前端 。
// API 路由: /api/create-payment-intent
import getStripe from ‘../lib/stripe’;
export default async function handler(req, res) {
const stripe = getStripe();
const { amount, currency, paymentMethodTypes } = req.body;
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: amount, // 单位是分(例如 1000 表示 $10.00)
currency: currency, // 例如 ‘usd’, ‘cny’ (人民币是分)
payment_method_types: paymentMethodTypes || [‘card’],
// 可选项:捕获方式,自动还是手动
capture_method: ‘automatic’,
});
res.json({
clientSecret: paymentIntent.client_secret,
});
} catch (err) {
res.status(500).json({ error: err.message });
}
}
Webhook 是 Stripe 通知你的服务器异步事件的方式(例如支付成功、退款、订阅状态变更)。你需要构建一个原始的 POST 端点来接收这些事件,并使用 constructEvent 方法验证签名,以确保请求确实来自 Stripe 。
在你的 Webhook 处理器中(例如 /api/webhooks):
import getStripe from ‘../lib/stripe’;
export const config = {
api: {
bodyParser: false, // 需要获取原始请求体用于验证
},
};
export default async function webhookHandler(req, res) {
const stripe = getStripe();
const sig = req.headers[‘stripe-signature’];
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
let event;
try {
// 获取原始请求体
const rawBody = await getRawBody(req);
event = stripe.webhooks.constructEvent(rawBody, sig, endpointSecret);
} catch (err) {
console.log(`⚠️ Webhook signature verification failed.`, err.message);
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// 处理事件类型
switch (event.type) {
case ‘payment_intent.succeeded’:
const paymentIntent = event.data.object;
console.log(`PaymentIntent for ${paymentIntent.amount} succeeded.`);
// 在这里更新数据库中的订单状态
break;
case ‘payment_intent.payment_failed’:
console.log(‘Payment failed.’);
break;
case ‘checkout.session.completed’:
const session = event.data.object;
// 处理 Checkout 会话完成逻辑
break;
// ... 处理其他事件(如 customer.subscription.created, invoice.paid 等)
default:
console.log(`Unhandled event type ${event.type}`);
}
res.json({received: true});
}
前端负责安全地收集支付信息,并通过 client_secret 与 Stripe 完成最终的确认支付。
在 React 应用中,你需要使用 loadStripe 加载 Stripe.js,并使用 Elements 包裹你的支付表单组件 。
import { Elements } from ‘@stripe/react-stripe-js’;
import { loadStripe } from ‘@stripe/stripe-js’;
import CheckoutForm from ‘../components/CheckoutForm’;
// 使用你的 Publishable Key 加载 Stripe
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PK);
export default function PaymentPage() {
const [clientSecret, setClientSecret] = useState(‘’);
useEffect(() => {
// 调用后端 API 创建 PaymentIntent 并获取 clientSecret
fetch(‘/api/create-payment-intent’, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({ amount: 2000, currency: ‘usd’ }),
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, []);
return (
<div>
{clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
</Elements>
)}
</div>
);
}
在 CheckoutForm 组件中,使用 useStripe 和 useElements 钩子来获取 Stripe 实例,并使用 confirmPayment 方法完成支付 。
import { useStripe, useElements, CardElement } from ‘@stripe/react-stripe-js’;
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
if (!stripe || !elements) {
return; // Stripe.js 尚未加载完成
}
const cardElement = elements.getElement(CardElement);
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: ‘Customer Name’,
// 其他账单信息
},
},
});
if (error) {
console.log(‘Payment failed:’, error.message);
} else if (paymentIntent && paymentIntent.status === ‘succeeded’) {
console.log(‘Payment succeeded!’);
// 重定向到成功页面或刷新购物车
}
setLoading(false);
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button type=“submit” disabled={!stripe || loading}>
Pay
</button>
</form>
);
}
如果你不想构建复杂的表单,可以使用 Stripe 托管的 Checkout 页面。这种方式最快速,且 PCI-DSS 合规由 Stripe 负责。
在后端创建一个 Checkout Session 并重定向用户 :
// 后端代码
const session = await stripe.checkout.sessions.create({
payment_method_types: [‘card’],
line_items: [
{
price: ‘price_1234567890’, // 价格 ID
quantity: 1,
},
],
mode: ‘payment’, // 或 ‘subscription’
success_url: ‘https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}’,
cancel_url: ‘https://yourdomain.com/cancel’,
});
// 返回 session.url 给前端,前端直接重定向到该 URL
res.json({ url: session.url });
Stripe 提供了大量的测试卡号。例如,使用 4242 4242 4242 4242,输入任意未来的到期日(如 12/34)和任意 CVC(如 123),即可模拟支付成功 。
如果你的购物车总额为 0(例如使用了折扣码),Stripe 不允许创建金额为 0 的 PaymentIntent 或 Checkout 会话。在这种情况下,你需要在前端或后端特殊处理:跳过 Stripe 支付流程,直接调用订单完成接口 。
pk_test_/sk_test_)替换为生产环境密钥(pk_live_/sk_live_)。checkout.session.completed, invoice.paid)。constructEvent 进行签名验证。通过以上步骤,你就完成了一个基于 Stripe 的标准支付集成。如果需要处理更复杂的业务逻辑,如订阅、Connect 平台账务等,可以参考 Stripe 官方文档中的对应指南。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。