大家好,我是王嗨皮,一名
主业前端,副业全栈的程序员,在这里我会分享关于前端进阶全栈的常用技术如果我的文章能让您有所收获,欢迎一键三连(评论,点赞,关注)。
本篇文章将从零开始,介绍如何使用 Vue3 + Node.js 将 Stripe 支付系统集成到应用程序中。
Stripe注册
访问 Stripe 官网, 完成账号注册。
提示 :Stripe 在正式生产环境中是不支持个人账户, 但在开发模式下,我们可以使用 Sandbox (沙盒模式),进行相关功能开发。
创建后端服务
完成 Stripe 注册后,我们使用 Node.js 创建后端服务。
新建文件夹,自定义项目名称,然后在文件夹下再新建一个目录,server。
在 server 文件夹下打开终端执行 npm init -y 初始化Node项目,并新建入口文件 index.js。
服务端文件结构:
项目结构
📦stripe
┗ 📂server
┃ ┣ 📜index.js
┃ ┗ 📜package.json
接下来,在根目录下安装服务端所需依赖,终端执行
npm i exress cors nodemon stripe dotenv
express:Node常用框架
cors:cors 允许前端跨域请求
nodemon:实时监听后端服务,每次修改代码无需再重启服务
dotenv:加载.env中的环境变量,方便管理密钥等敏感信息
stripe:集成了 Stripe 常用的API,简化处理支付,订阅等功能实现
至此,后端服务已完成创建。
配置环境变量
在项目根目录下新建 .env 环境变量文件,配置一下 Stripe 的API的私钥。
登录 Stripe,在 Dashboard 面板找到 API 私钥,复制到 .env 文件中。

ini
# Stripe 私钥
STRIPE_SECRET_KEY = your api key
创建支付接口
在 index.js 导入所有安装的依赖,并启动后端服务。
javascript
require('dotenv').config()
const express = require('express')
const app = express()
const cors = require('cors')
const dayjs = require('dayjs')
// 引入并导入stripe依赖,获取Stripe私钥
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
app.use(cors())
app.use(express.json())
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
接下来,使用 stripe.checkout.sessions.create 创建支付页面,代码如下:
javascript
app.post('/create-checkout-session', async (req, res) => {
const { priceId } = req.body // 在Stripe Dashboard创建的价格ID
try {
// 移除 FRONTEND_URL 末尾可能存在的斜杠,避免出现//双斜杠
const frontendUrl = process.env.FRONTEND_URL.replace(/\/$/, '')
const session = await stripe.checkout.sessions.create({
// 订阅模式只支持信用卡(支付宝不支持自动续费)
payment_method_types: ['card'],
line_items: [{
price: priceId,
quantity: 1
}],
mode: 'subscription', //订阅模式
// 添加 session_id 到回调 URL,方便前端获取订阅信息
success_url: `http://localhost:5173/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `http://localhost:5173/cancel`
})
// 返回 session.url 用于直接支付页面
res.json({
id: session.id,
url: session.url
})
}catch(error) {
console.error('Error creating checkout session:', error);
res.status(500).send('Error creating checkout session');
}
})
mode :mode 为支付模式,通常有两种,subscription 订阅模式 和 payment 一次性支付,这里我们选择 subscription,也是海外产品支付比较常用的模式。
payment_method_types : 支付方式,card 为信用卡模式,需要额外注意的是 payment_method_types 也支持支付宝,参数为 alipay,但是如果设置了支付宝模式,则 mode 支付模式必须为 payment 一次性支付,支付宝在 Stripe 中是不支持订阅自动续费模式的。
line_items :商品定义,其中 priceId 是在Stripe Dashboard创建的价格ID,由前端作为参数传递过来,后文我们在前端部分会详细解释怎样获取。quantity 为商品数量。
success_url:支付成功后要跳转的页面。
cancel_url:支付失败后要跳转的页面。
最后, 通过res.json将 session.id 和 session.url 都返回给前端,方便做后续处理。
创建前端项目
在 stripe 根目录下新建文件夹 front,与后端 server 文件夹平级,结构目录如下:
项目结构
📦stripe
┣ 📂front
┗ 📂server
┃ ┣ 📜index.js
┃ ┗ 📜package.json
在 front 根目录下,执行 vite 命令创建一个 Vue3 项目。然后分别创建 Home、Success、Cancel 三个页面,并配置对应路由。
其中 Success 和 Cancel 对应后端 success_url 支付成功跳转页面 和 cancel_url 支付失败跳转页面。
接下来,在 Home 页面简单编写一个按钮,代码如下:
html
<template>
<div class="payment-container">
<div class="payment-option">
<button @click="handleSubscribe" class="subscribe-button">
订阅按钮
</button>
</div>
</div>
</template>
添加样式,使页面尽量美观一些
css
.payment-container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
}
h2 {
text-align: center;
margin-bottom: 30px;
color: #333;
}
.payment-option {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.subscribe-button,
.payment-button {
width: 100%;
padding: 12px 20px;
border: none;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
}
.subscribe-button {
background-color: #007bff;
color: white;
}
.subscribe-button:hover {
background-color: #0056b3;
}
到这里,前端项目和相关页面已经创建完成。
调用支付接口
在前端调用接口之前,我们先登录 Stripe,在 Dashboard 中创建一个商品,参考下图:

商品创建成功后,回到前端 Home 页面,定义一个 handleSubscribe 方法调用支付接口,代码如下:
javascript
const handleSubscribe = async () => {
try {
const response = await fetch('http://localhost:3000/create-checkout-session', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
// 价格id
priceId: 'your priceID'
})
})
const session = await response.json()
if (session.url) {
window.location.href = session.url
}
} catch(error) {
console.error('订阅处理错误:', error)
}
}
priceId的获取方法: 进入Stripe Dashboard 产品目录 点击已创建好的产品,进入详情页,找到价格,点击后面更多按钮,找到 复制价格ID,点击复制粘贴即可。

session.url是后端返回的 Stripe 托管支付页面。
在完成调用接口的方法事件编写后,现在我们确保 server 后端服务已运行,然后执行前端项目,点击订阅按钮。

可以看到,点击后成功跳转到了 Stripe 托管的支付页面,左侧可以看到 Stripe Dashboard 中定义的产品名称和具体价格。
我们继续在右侧输入邮箱、测试卡号、持卡人姓名、国家或地区等信息,点击 订阅 。

如上图,代表我们订阅成功,同时页面会跳转到我们之前创建的 Success 页面。
此时,我们回到 Stripe Dashboard,打开左侧 订阅 选项,可以看到已经成功获取到了订阅的用户信息。

如果我们在 Stripe 托管的支付页面点击左上方 "返回"按钮,则会跳转到之前创建的 Cancel 取消支付页面。
Webhook监听支付
最后,我们创建一个使用 Webhook 接口,用来监听 Stripe 支付、退款、订阅等事件的通知。
首先,安装 Stripe Cli,以 windows 系统为例,下载安装包,选择安装目录解压,并将安装路径配置到环境变量 PATH 中去。
如果是 macOS 系统可选择 HomeBrew 进行安装,此处不再赘述。
完成 Stripe Cli 安装后,打开终端执行 stripe login 通过终端返回的链接完成 Stripe 的授权登录。
然后返回终端,再执行 stripe listen --forward-to localhost:3000/webhook。
终端会返回一个webhook的密钥,格式通常为 whsec_xxxxxx

现在,让我们回到项目 server 服务端,将 Webhook 密钥配置到 .env 环境变量中。
在 index.js 文件下创建一个 Webhook 的监听接口,代码如下:
javascript
// ⚠️ Webhook 路由必须在 express.json() 之前,因为需要原始请求体来验证签名
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
const sig = req.headers['stripe-signature']
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET // webhook密钥
let event
try {
// 验证 webhook 签名
event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret)
} catch (err) {
console.error('⚠️ Webhook 签名验证失败:', err.message)
return res.status(400).send(`Webhook Error: ${err.message}`)
}
try {
switch (event.type) {
case 'checkout.session.completed':
const session = event.data.object
console.log('💳 收到支付完成事件!')
console.log('完整的 session 对象:', JSON.stringify(session, null, 2))
console.log('--- 关键信息 ---')
console.log('Session ID:', session.id)
console.log('客户邮箱:', session.customer_email)
console.log('支付状态:', session.payment_status)
console.log('支付金额:', session.amount_total / 100, session.currency.toUpperCase())
console.log('支付模式:', session.mode)
break
}
} catch (error) {
console.error('处理 Webhook 事件时出错:', error.message)
}
// 返回 200 响应告诉 Stripe 已收到事件(必须有!)
res.json({received: true})
})
webhook 监听接口定义完成后,重启一下服务端,然后我们在前端重新执行一次订阅支付请求。

可以看到控制台获取到了 Webhook 监听的支付成功的信息,以下是 Webhook 监听支付的几种常用状态:
| 事件类型 | 触发时机 | 监听等级 |
|---|---|---|
| checkout.session.completed | 用户首次支付成功(订阅或一次性购买) | ⭐⭐⭐⭐⭐ |
| invoice.payment_succeeded | 订阅续费成功 | ⭐⭐⭐⭐⭐ |
| invoice.payment_failed | 订阅续费失败 | ⭐⭐⭐⭐⭐ |
| customer.subscription.deleted | 用户取消订阅 | ⭐⭐⭐⭐⭐ |
虽然 Webhook 不是强制性的,但它能帮助我们更高效地处理支付流程、避免漏掉重要事件,如果业务逻辑中需要处理这些事件,建议使用 Webhook。
到此为止,我们使用 Vue3 + Node.js + Stripe 实现了一个简单的支付功能,Stripe更多功能使用,例如自定义订阅等等,可以查看 Stripe文档 了解。
我是王嗨皮,如果我的文章能让您有所收获,欢迎一键三连(评论,点赞,关注)。