5分钟上线!Next.js+Stripe构建企业级支付系统全攻略

5分钟上线!Next.js+Stripe构建企业级支付系统全攻略

【免费下载链接】next.js The React Framework 【免费下载链接】next.js 项目地址: https://gitcode.com/GitHub_Trending/next/next.js

你是否还在为支付系统的安全合规焦头烂额?还在纠结前后端数据交互的加密实现?本文将带你基于Next.js与Stripe快速搭建三套生产级支付方案,从环境配置到订单回调全程可视化操作,让你零基础也能1小时内完成支付系统部署。

方案概览:三种支付集成模式对比

Next.js与Stripe的集成方案主要分为三种模式,适用于不同业务场景:

集成模式适用场景技术栈安全等级
Checkout重定向快速上线/独立支付页Next.js Server Actions★★★★★
Elements嵌入支付自定义支付界面React Stripe.js/Payment Intents★★★★☆
嵌入式Checkout半定制化支付流Stripe Embedded Checkout★★★★☆

官方示例提供了完整实现代码,可直接作为生产起点:Stripe集成示例

环境准备:10分钟配置开发环境

基础依赖安装

通过create-next-app快速初始化项目,示例已包含TypeScript类型定义和Stripe SDK封装:

npx create-next-app --example with-stripe-typescript payment-system
cd payment-system

核心依赖文件说明:

Stripe账户配置

  1. 登录Stripe控制台创建测试账号
  2. 开发者设置获取API密钥对:
    • 公钥:NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
    • 密钥:STRIPE_SECRET_KEY
  3. 创建.env.local文件并填入密钥:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_SECRET_KEY=sk_test_xxx

方案一:Checkout重定向模式(推荐新手)

实现原理

通过Server Action创建支付会话,客户端重定向到Stripe托管的支付页面,完成后返回成功页。整个支付流程在Stripe域名下完成,符合PCI DSS合规要求。

Checkout工作流程

核心代码实现

1. 创建支付会话(Server Action)

// app/actions/stripe.ts
'use server'
import { createCheckoutSession } from '@/lib/stripe'

export async function checkout(formData: FormData) {
  const amount = Number(formData.get('amount'))
  const session = await createCheckoutSession({
    amount,
    currency: 'usd',
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/donate-with-checkout/result?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/donate-with-checkout`,
  })
  
  return { url: session.url }
}

2. 支付页面组件

Server Component负责渲染表单,通过action属性绑定Server Action:

// app/donate-with-checkout/page.tsx
import { checkout } from '@/app/actions/stripe'
import CustomDonationInput from '@/app/components/CustomDonationInput'

export default function CheckoutPage() {
  return (
    <form action={checkout}>
      <CustomDonationInput />
      <button type="submit">Pay with Checkout</button>
    </form>
  )
}

3. 支付结果页

支付完成后从URL参数获取会话ID,查询订单状态:

// app/donate-with-checkout/result/page.tsx
import { getCheckoutSession } from '@/lib/stripe'

export default async function ResultPage({
  searchParams,
}: {
  searchParams: { session_id: string }
}) {
  const session = await getCheckoutSession(searchParams.session_id)
  
  return (
    <div>
      <h1>Payment Successful!</h1>
      <p>Order ID: {session.id}</p>
    </div>
  )
}

测试支付流程

使用Stripe测试卡号完成支付测试:

  • 卡号:4242 4242 4242 4242
  • 有效期:任意未来日期
  • CVC:123

Checkout界面效果:

Checkout支付界面

方案二:Elements嵌入支付表单

技术架构

通过React Stripe.js在自有页面嵌入支付表单,使用Payment Intents API处理支付流程,支持完全自定义UI:

Elements工作流程

核心实现文件:

关键实现步骤

1. 创建Payment Intent

在Server Action中创建支付意向,返回客户端 secret:

// app/actions/stripe.ts
export async function createPaymentIntent(amount: number) {
  const paymentIntent = await stripe.paymentIntents.create({
    amount: amount * 100, // 金额以分为单位
    currency: 'usd',
    automatic_payment_methods: { enabled: true }
  })
  
  return { clientSecret: paymentIntent.client_secret }
}

2. 渲染支付表单

使用Elements组件包裹PaymentElement,实现完全自定义的支付界面:

// app/donate-with-elements/page.tsx
import { Elements } from '@stripe/react-stripe-js'
import ElementsForm from '@/app/components/ElementsForm'
import { getStripejs } from '@/utils/get-stripejs'

export default async function ElementsPage() {
  const stripe = await getStripejs()
  
  return (
    <Elements stripe={stripe}>
      <ElementsForm />
    </Elements>
  )
}

3. 处理支付提交

客户端收集支付信息并确认支付意向:

// components/ElementsForm.tsx
'use client'
import { useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js'

export default function ElementsForm() {
  const stripe = useStripe()
  const elements = useElements()
  
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const { error } = await stripe.confirmPayment({
      elements,
      confirmParams: { return_url: '/donate-with-elements/result' }
    })
    
    if (error) alert(error.message)
  }
  
  return (
    <form onSubmit={handleSubmit}>
      <PaymentElement />
      <button disabled={!stripe}>Pay Now</button>
    </form>
  )
}

订单管理:Webhook处理支付回调

支付完成后,Stripe会发送webhook事件到后端,需在Next.js中实现事件处理:

配置webhook端点

  1. 使用Stripe CLI转发事件到本地服务器:
stripe listen --forward-to localhost:3000/api/webhooks
  1. 将终端显示的签名密钥添加到环境变量:
STRIPE_WEBHOOK_SECRET=whsec_xxx

实现webhook处理

// app/api/webhooks/route.ts
import Stripe from 'stripe'
import { headers } from 'next/headers'

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)

export async function POST(req: Request) {
  const body = await req.text()
  const signature = headers().get('Stripe-Signature')!
  
  try {
    const event = stripe.webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!
    )
    
    if (event.type === 'checkout.session.completed') {
      const session = event.data.object as Stripe.Checkout.Session
      // 处理订单完成逻辑:发送邮件/更新数据库
      console.log('Payment completed:', session.id)
    }
    
    return new Response('OK', { status: 200 })
  } catch (error) {
    return new Response('Webhook error', { status: 400 })
  }
}

完整webhook实现:api/webhooks/route.ts

生产环境部署

安全加固清单

  1. 启用HTTPS:所有生产环境必须使用HTTPS协议
  2. 限制webhook IP:在Stripe控制台配置允许的IP地址
  3. 数据加密:敏感订单信息需加密存储
  4. 日志审计:记录所有支付操作日志参考示例

Vercel一键部署

示例项目已优化Vercel部署配置,推送代码后自动完成:

  • 环境变量注入
  • 边缘函数部署
  • 全球CDN加速

部署状态监控:Vercel部署文档

问题排查与优化

常见错误解决

错误类型解决方案参考文档
400 Bad Request检查API密钥是否正确API错误码
支付意图验证失败确认金额单位是否为分Payment Intents文档
Webhook签名错误重新获取签名密钥Webhook验证

性能优化建议

  1. 使用Stripe官方CDN加载客户端库:
// utils/get-stripejs.ts
import { loadStripe } from '@stripe/stripe-js'

export async function getStripejs() {
  return loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!)
}
  1. 实现支付表单懒加载:
// 动态导入Elements组件
const Elements = dynamic(() => import('@stripe/react-stripe-js').then(m => m.Elements), {
  ssr: false
})

扩展阅读与资源


本文示例代码基于Next.js 14和Stripe API v2023-10-16,定期同步官方更新。关注项目更新日志获取最新特性。

需要更多支付场景示例?查看Stripe集成大全

【免费下载链接】next.js The React Framework 【免费下载链接】next.js 项目地址: https://gitcode.com/GitHub_Trending/next/next.js

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值