You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Nuxt 3中集成Stripe实现预订系统的技术求助

汽车预订系统(Nuxt + Stripe)实现指导

核心业务对应Stripe方案

  • 延迟收款逻辑:使用Stripe的「Payment Intent」并设置capture_method: 'manual',客户完成支付后资金处于预授权状态,仅当管理员审核通过后,再手动捕获资金;审核不通过则取消Payment Intent,自动完成退款。
  • 支付信息安全存储:创建Stripe「Customer」对象,将客户的支付方式(如银行卡)关联到该Customer,仅在系统中存储Stripe返回的customer_id和payment_method_id,避免直接存储敏感支付数据。
  • 额外费用收取:利用已关联到Customer的支付方式,直接创建新的Payment Intent完成扣款,无需客户再次输入支付信息。

Nuxt端具体实现步骤

1. 安装依赖

在项目中安装Stripe相关包:

# 前端Stripe SDK
npm install @stripe/stripe-js
# 后端Stripe SDK(用于服务器端API)
npm install stripe

2. 配置Stripe密钥

在Nuxt的环境变量文件(.env)中添加:

# 服务器端用的Secret Key(绝对不能暴露到前端)
STRIPE_SECRET_KEY=sk_xxx
# 前端用的Publishable Key
STRIPE_PUBLISHABLE_KEY=pk_xxx

3. 前端:集成Stripe Elements收集支付信息

在预订页面组件中,加载Stripe.js并初始化Elements:

<template>
  <div>
    <!-- Stripe Elements容器 -->
    <div id="card-element"></div>
    <button @click="handlePayment">提交预订并支付</button>
  </div>
</template>

<script setup>
import { loadStripe } from '@stripe/stripe-js'
import { ref, onMounted } from 'vue'

const stripePromise = loadStripe(process.env.STRIPE_PUBLISHABLE_KEY)
let elements = null

onMounted(async () => {
  const stripe = await stripePromise
  elements = stripe.elements()
  // 创建卡片元素
  const cardElement = elements.create('card')
  cardElement.mount('#card-element')
})

const handlePayment = async () => {
  const stripe = await stripePromise
  // 先调用Nuxt后端API创建Customer和Payment Intent
  const { data: { clientSecret } } = await useFetch('/api/create-payment-intent', {
    method: 'POST',
    body: {
      amount: 1000, // 预订金额(单位:分)
      bookingId: 'your-booking-id' // 关联你的系统预订ID
    }
  })

  // 确认支付
  const { error } = await stripe.confirmCardPayment(clientSecret, {
    payment_method: {
      card: elements.getElement('card'),
      billing_details: {
        name: '客户姓名',
        email: '客户邮箱'
      }
    }
  })

  if (error) {
    // 处理支付错误
    console.error(error.message)
  } else {
    // 支付预授权成功,跳转至预订等待审核页面
    navigateTo('/booking-pending')
  }
}
</script>

4. 后端:创建Customer与Payment Intent

在Nuxt的server/api/create-payment-intent.ts中编写API:

import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2024-06-20' // 使用最新API版本
})

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { amount, bookingId } = body

  // 1. 创建Stripe Customer
  const customer = await stripe.customers.create({
    email: '客户邮箱', // 可从前端传入
    metadata: { bookingId } // 关联预订ID
  })

  // 2. 创建Payment Intent(手动捕获模式)
  const paymentIntent = await stripe.paymentIntents.create({
    amount,
    currency: 'cny', // 根据你的业务设置币种
    customer: customer.id,
    capture_method: 'manual',
    metadata: { bookingId }
  })

  // 3. 将customer_id和payment_intent_id存入你的数据库,关联对应预订记录
  // 这里省略数据库操作逻辑

  return {
    clientSecret: paymentIntent.client_secret
  }
})

5. 审核后收款/退款逻辑

编写后端API处理管理员审核操作:

  • 审核通过,捕获资金:server/api/capture-payment.ts
import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2024-06-20'
})

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { paymentIntentId } = body

  // 捕获预授权的资金
  const paymentIntent = await stripe.paymentIntents.capture(paymentIntentId)

  // 更新数据库中预订状态为「已确认」
  // 省略数据库操作

  return { success: true, paymentIntent }
})
  • 审核不通过,取消支付并退款:server/api/cancel-payment.ts
import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2024-06-20'
})

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { paymentIntentId } = body

  // 取消Payment Intent,自动退款
  const paymentIntent = await stripe.paymentIntents.cancel(paymentIntentId)

  // 更新数据库中预订状态为「已取消」
  // 省略数据库操作

  return { success: true, paymentIntent }
})

6. 额外费用收取逻辑

当需要收取车辆损坏/里程超额费用时,调用后端API:server/api/charge-extra.ts

import Stripe from 'stripe'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
  apiVersion: '2024-06-20'
})

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { customerId, amount, reason } = body

  // 使用已关联的支付方式创建新的Payment Intent并自动捕获
  const paymentIntent = await stripe.paymentIntents.create({
    amount,
    currency: 'cny',
    customer: customerId,
    payment_method: 'pm_xxx', // 从数据库中取出该Customer关联的支付方式ID
    confirm: true, // 自动确认并捕获资金
    metadata: { reason }
  })

  // 记录额外费用到数据库
  // 省略数据库操作

  return { success: true, paymentIntent }
})

关键注意事项

  • 敏感操作全走后端:Stripe Secret Key绝对不能出现在前端代码中,所有与Stripe的交互(创建Customer、捕获/取消支付等)必须通过Nuxt服务器端API完成。
  • Webhook处理异步事件:配置Stripe Webhook监听payment_intent.succeeded、payment_intent.canceled等事件,确保系统状态与Stripe同步(比如支付失败时更新预订状态)。
  • PCI合规:使用Stripe Elements收集支付信息,无需自己处理银行卡号等敏感数据,自动满足PCI合规要求。
  • 错误处理:在前端和后端都要处理Stripe返回的错误(比如支付被拒绝、网络异常等),给用户清晰的提示。

内容的提问来源于stack exchange,提问作者Akram Trimech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:15:04