如何用 Next.js 和 Stripe 构建电商网站 - 2026 最新实战指南

Jan 30, 20261658 次浏览82 销量nextjsstripeecommerce
如何用 Next.js 和 Stripe 构建电商网站 - 2026 最新实战指南

如何用 Next.js 和 Stripe 构建电商网站 - 2026 最新实战指南

我花了 3 个月时间,踩了 50+ 个坑,终于用 Next.js 15 和 Stripe 搭建了一个完整的电商网站。月收入从 0 到 $12,000。

这篇文章不讲理论,只讲实战。我会告诉你: • 为什么我放弃了 Shopify,选择自建站 • Stripe 支付集成的 3 个致命坑(官方文档不会告诉你) • 如何用 Next.js 15 的 Server Actions 优化性能 40% • 数据库设计的 5 个关键决策(影响后期扩展)

读完这篇文章,你能学会 80% 的核心技术。 想要完整源码和一键部署脚本?文末有惊喜。

让我们开始吧 👇


目录

  1. 为什么选择 Next.js + Stripe?
  2. 技术栈选型(我的 3 次失败经验)
  3. 项目架构设计(含流程图)
  4. 核心功能实现
  5. 我踩过的 10 个大坑
  6. 性能优化技巧
  7. 部署上线指南
  8. 总结与下一步

1. 为什么选择 Next.js + Stripe?

我的 3 次失败经验

第一次:用 Shopify

  • 优点:快速上线(1天)
  • 缺点:月费 $29,交易手续费 2%,定制困难
  • 结果:3 个月后迁移,浪费 $500

第二次:用 WordPress + WooCommerce

  • 优点:插件丰富
  • 缺点:性能差(加载 5 秒),安全漏洞多
  • 结果:被黑客攻击,数据泄露

第三次:用 Next.js + Stripe(成功)

  • 优点:完全控制,性能极佳(加载 0.8 秒),无月费
  • 缺点:开发周期长(2 周)
  • 结果:月收入 $12,000,利润率 85%

技术栈对比表

方案开发时间月成本性能可定制性推荐度
Shopify1天$29+⭐⭐⭐⭐⭐⭐⭐⭐
WordPress3天$10+⭐⭐⭐⭐⭐⭐⭐
Next.js2周$0⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

关键决策点

如果你符合以下条件,强烈推荐 Next.js: ✅ 有基础的 React 知识 ✅ 需要高度定制化 ✅ 追求极致性能 ✅ 想要完全控制数据 ✅ 长期运营(省月费)

如果你只是测试想法,用 Shopify。


2. 项目架构设计

整体架构

前端(Next.js 15)
  ↓
API 路由(Server Actions)
  ↓
数据库(PostgreSQL)
  ↓
支付网关(Stripe)

数据库设计(5 个关键决策)

决策 1:用户表设计

❌ 错误做法:

CREATE TABLE users (
  id INT,
  email VARCHAR(255),
  password VARCHAR(255)  -- 明文存储,危险!
);

✅ 正确做法:

CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  password_hash TEXT NOT NULL,  -- bcrypt 加密
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

为什么?

  • UUID 比自增 ID 更安全(防止遍历攻击)
  • 密码必须加密(bcrypt,成本因子 12)
  • 时间戳用于审计

决策 2:订单表设计

这是我踩的最大的坑。最初我这样设计:

❌ 错误做法:

CREATE TABLE orders (
  id INT,
  user_id INT,
  product_id INT,  -- 只存 ID,产品信息变了怎么办?
  price DECIMAL(10,2)  -- 价格变了怎么办?
);

问题

  • 产品改名后,历史订单显示错误
  • 价格调整后,财务对不上账

✅ 正确做法:

CREATE TABLE orders (
  id UUID PRIMARY KEY,
  user_id UUID,
  -- 快照产品信息(订单时的状态)
  product_snapshot JSONB NOT NULL,
  price_at_purchase DECIMAL(10,2) NOT NULL,
  stripe_payment_id VARCHAR(255),
  status VARCHAR(50) DEFAULT 'pending',
  created_at TIMESTAMP DEFAULT NOW()
);

为什么?

  • JSONB 存储产品快照(订单时的名称、描述、图片)
  • price_at_purchase 记录购买时的价格
  • stripe_payment_id 用于对账

这个坑让我损失了 $2,000(财务对不上账,税务问题)


3. Stripe 支付集成(3 个致命坑)

坑 1:Webhook 验证失败

我第一次集成 Stripe 时,支付成功了,但订单状态没更新。 查了 2 天日志,发现是 Webhook 签名验证失败。

❌ 错误代码:

// 直接读取 body,签名验证会失败!
export async function POST(req: Request) {
  const body = await req.json();  // ❌ 错误!
  const sig = req.headers.get('stripe-signature');
  
  const event = stripe.webhooks.constructEvent(
    body,  // ❌ 这里应该是原始字符串,不是 JSON
    sig,
    process.env.STRIPE_WEBHOOK_SECRET
  );
}

✅ 正确代码:

export async function POST(req: Request) {
  const body = await req.text();  // ✅ 读取原始字符串
  const sig = req.headers.get('stripe-signature');
  
  try {
    const event = stripe.webhooks.constructEvent(
      body,
      sig!,
      process.env.STRIPE_WEBHOOK_SECRET!
    );
    
    // 处理事件
    if (event.type === 'payment_intent.succeeded') {
      // 更新订单状态
    }
  } catch (err) {
    console.error('Webhook 验证失败:', err);
    return new Response('Webhook Error', { status: 400 });
  }
}

关键点

  • 必须用 req.text() 而不是 req.json()
  • Stripe 需要原始字符串来验证签名
  • 验证失败会导致订单状态不更新

这个坑让我损失了 3 笔订单($450)

坑 2:货币单位错误

Stripe 的金额单位是,不是元!

❌ 错误代码:

const session = await stripe.checkout.sessions.create({
  line_items: [{
    price_data: {
      currency: 'usd',
      unit_amount: 9.99,  // ❌ 错误!应该是 999
      product_data: { name: '教程' }
    },
    quantity: 1
  }]
});

结果:用户支付了 $0.0999(不到 1 美分)

✅ 正确代码:

const session = await stripe.checkout.sessions.create({
  line_items: [{
    price_data: {
      currency: 'usd',
      unit_amount: 999,  // ✅ 9.99 美元 = 999 美分
      product_data: { name: '教程' }
    },
    quantity: 1
  }]
});

这个坑让我白送了 20 份教程($200)

坑 3:测试环境和生产环境混用

永远不要在生产环境使用测试密钥!

我曾经不小心在生产环境用了测试密钥,结果:

  • 用户支付成功,但钱没到账
  • 订单状态显示"已支付"
  • 客服电话被打爆

解决方案

// 使用环境变量区分
const stripeKey = process.env.NODE_ENV === 'production'
  ? process.env.STRIPE_LIVE_SECRET_KEY
  : process.env.STRIPE_TEST_SECRET_KEY;

const stripe = new Stripe(stripeKey!);

4. 性能优化技巧(加载速度从 3.2s 到 0.8s)

优化 1:图片懒加载

❌ 优化前:

  • 首页加载 20 张产品图(每张 500KB)
  • 总大小:10MB
  • 加载时间:3.2 秒

✅ 优化后:

import Image from 'next/image';

<Image
  src="/product.jpg"
  alt="产品"
  width={300}
  height={300}
  loading="lazy"  // 懒加载
  placeholder="blur"  // 模糊占位
/>

结果:

  • 首屏只加载 3 张图
  • 总大小:1.5MB
  • 加载时间:0.8 秒

性能提升 75%

优化 2:使用 Server Components

Next.js 15 的 Server Components 可以大幅减少客户端 JavaScript。

❌ 优化前(Client Component):

'use client';

export default function ProductList() {
  const [products, setProducts] = useState([]);
  
  useEffect(() => {
    fetch('/api/products')
      .then(res => res.json())
      .then(setProducts);
  }, []);
  
  return <div>{/* 渲染产品 */}</div>;
}

✅ 优化后(Server Component):

export default async function ProductList() {
  const products = await getProducts();  // 服务端获取
  
  return <div>{/* 渲染产品 */}</div>;
}

JavaScript 体积减少 60%

优化 3:数据库查询优化

❌ 优化前(N+1 查询问题):

const products = await db.products.findMany();

for (const product of products) {
  product.category = await db.categories.findUnique({
    where: { id: product.categoryId }
  });
}

✅ 优化后(使用 JOIN):

const products = await db.products.findMany({
  include: {
    category: true  // 一次查询搞定
  }
});

查询时间从 500ms 降到 50ms


5. 部署上线指南

步骤 1:准备环境变量

# .env.production
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_xxx
STRIPE_SECRET_KEY=sk_live_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
DATABASE_URL=postgresql://xxx
NEXT_PUBLIC_URL=https://yourdomain.com

步骤 2:配置 Vercel

  1. 连接 GitHub 仓库
  2. 添加环境变量
  3. 点击部署

步骤 3:配置 Stripe Webhook

  1. 登录 Stripe Dashboard
  2. 进入 Developers → Webhooks
  3. 添加端点:https://yourdomain.com/api/webhooks/stripe
  4. 选择事件:payment_intent.succeeded
  5. 复制 Webhook 密钥到环境变量

步骤 4:测试支付流程

使用 Stripe 测试卡号:

  • 成功:4242 4242 4242 4242
  • 失败:4000 0000 0000 0002
  • 需要 3D 验证:4000 0025 0000 3155

6. 总结

通过这篇文章,你学会了: ✅ Next.js + Stripe 的完整架构 ✅ 数据库设计的 5 个关键决策 ✅ Stripe 支付集成的 3 个致命坑 ✅ 性能优化的 3 个技巧 ✅ 部署上线的完整流程

你现在可以自己搭建一个电商网站了!

但是,从 0 到 1 搭建还是需要时间的:

  • 写代码:2 周
  • 调试:1 周
  • 部署:3 天
  • 总计:约 1 个月

如果你想节省这 1 个月时间,直接获取:

  • 价值上万的完整源码(15,000+ 行)
  • 一键部署脚本
  • 完整配置文件
  • 详细技术文档

👇 继续往下看,解锁完整项目资源包

解锁完整内容

查看完整教程、源码链接和配置脚本

$9.99一次性付费
永久访问完整内容
包含源码链接和配置脚本
详细的踩坑指南

支付后,解锁链接将发送到此邮箱

已有账号?登录后购买可在用户中心查看