Node.js 实现 Stripe 支付的简单示例
1. 安装依赖
npm install stripe express
2. 基础服务端实现
// server.js
const express = require('express');
const stripe = require('stripe')('你的_STRIPE_SECRET_KEY'); // 从 Stripe 控制台获取
const app = express();app.use(express.json());
app.use(express.static('public'));// 创建支付意图
app.post('/create-payment-intent', async (req, res) => {try {const { amount, currency = 'usd' } = req.body;// 创建 PaymentIntentconst paymentIntent = await stripe.paymentIntents.create({amount: amount, // 金额(以最小单位计,如美分)currency: currency,automatic_payment_methods: {enabled: true,},});res.json({clientSecret: paymentIntent.client_secret});} catch (error) {res.status(500).json({ error: error.message });}
});// 创建 Checkout Session(更简单的方式)
app.post('/create-checkout-session', async (req, res) => {try {const session = await stripe.checkout.sessions.create({payment_method_types: ['card'],line_items: [{price_data: {currency: 'usd',product_data: {name: '商品名称',},unit_amount: 2000, // $20.00},quantity: 1,},],mode: 'payment',success_url: 'http://localhost:3000/success',cancel_url: 'http://localhost:3000/cancel',});res.json({ id: session.id });} catch (error) {res.status(500).json({ error: error.message });}
});// Webhook 处理(用于接收支付状态更新)
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {const sig = req.headers['stripe-signature'];const webhookSecret = '你的_WEBHOOK_SECRET';let event;try {event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);} catch (err) {return res.status(400).send(`Webhook Error: ${err.message}`);}// 处理事件switch (event.type) {case 'payment_intent.succeeded':const paymentIntent = event.data.object;console.log('PaymentIntent 成功:', paymentIntent.id);// 这里处理支付成功后的业务逻辑break;case 'payment_intent.payment_failed':console.log('支付失败');break;default:console.log(`未处理的事件类型: ${event.type}`);}res.json({received: true});
});app.listen(3000, () => {console.log('服务器运行在 http://localhost:3000');
});
3. 前端实现(使用 Stripe.js)
<!-- public/index.html -->
<!DOCTYPE html>
<html>
<head><script src="https://js.stripe.com/v3/"></script>
</head>
<body><button id="checkout-button">支付 $20</button><script>const stripe = Stripe('你的_STRIPE_PUBLISHABLE_KEY');document.getElementById('checkout-button').addEventListener('click', async () => {// 方法 1: 使用 Checkout Sessionconst response = await fetch('/create-checkout-session', {method: 'POST',});const session = await response.json();// 重定向到 Stripe Checkoutconst result = await stripe.redirectToCheckout({sessionId: session.id});if (result.error) {alert(result.error.message);}});</script>
</body>
</html>
4. 使用 Payment Intents 的更灵活方式
// 前端代码
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {event.preventDefault();// 从后端获取 client secretconst response = await fetch('/create-payment-intent', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({amount: 2000})});const {clientSecret} = await response.json();// 确认支付const {error, paymentIntent} = await stripe.confirmCardPayment(clientSecret, {payment_method: {card: cardElement,billing_details: {name: '客户姓名'}}});if (error) {console.log('支付失败:', error);} else if (paymentIntent.status === 'succeeded') {console.log('支付成功!');}
});
关键要点:
- 环境变量:将 Stripe 密钥存储在环境变量中
- 金额单位:Stripe 使用最小货币单位(美元用美分)
- Webhook:用于接收异步支付通知
- 测试模式:使用测试密钥和测试卡号(如 4242 4242 4242 4242)进行开发
上面只是一个基础实现,实际生产环境中还需要考虑错误处理、安全性、订单管理等更多细节。
