APE
文章标签归档关于

© 2026 APE.PUB

2026-07-25· 9 分钟

vercel付费方案

vercel

Vercel 轻量付费服务方案

架构图

┌──────────┐    ① 输入邮箱      ┌─────────────────┐
│  前端     │ ───────────────→  │ Vercel Function  │
│ (Vercel)  │                   │ /api/auth/send   │
│           │ ←─────────────── │                  │
│           │    验证码已发送     └────────┬────────┘
│           │                             │ ② 存 KV
│           │    ③ 输入验证码     ┌────────▼────────┐
│           │ ────────────────→  │ Vercel Function  │
│           │                   │ /api/auth/verify │
│           │ ←───────────────  │                  │
│           │   JWT + isPaid    └────────┬────────┘
│           │                             │ ④ 查 Stripe
│           │    ⑤ 请求带 JWT    ┌────────▼────────┐
│           │ ────────────────→  │ Vercel Function  │
│           │                   │ /api/protected   │
│           │ ←───────────────  │                  │
│           │  付费/免费内容      └─────────────────┘
└──────────┘

核心概念

Vercel

前端云平台,托管静态文件(HTML/JS/CSS)+ Serverless Function。

  • 前端文件 → CDN → 浏览器执行,代码公开,不能放 secret key
  • Vercel Function(API Routes) → Vercel 服务器执行,不发给浏览器,可安全存放 secret key(STRIPE_SECRET_KEY、JWT_SECRET 等)

Vercel Function(BFF)

服务端无服务器函数,作为前端和后端服务之间的代理层:

前端 → Vercel Function (BFF) → Stripe / KV / Resend
  • 无服务器,不需要管 nginx/进程管理
  • 按请求付费,没人调用时零成本
  • 自动扩缩容

Vercel KV

基于 Upstash Redis 的 key-value 存储:

  • 宕机不会丢数据(AOF + 快照持久化)
  • 即使 KV 数据丢失,Stripe 永远是源数据源,可从 Stripe 恢复
  • 适合存验证码、OAuth 映射、付费状态缓存

技术选型

| 需求 | 方案 | 成本 |

|------|------|------|

| 认证 | 邮箱验证码(无密码、无注册、无 DB) | 零 |

| 会话 | JWT,存 localStorage | 零 |

| 支付 | Stripe | 2.9% + $0.30/笔 |

| 验证码存储 | Vercel KV (Redis),TTL 10min | 免费层 30 万 reads/月 |

| 发邮件 | Resend | 免费 100 封/天 |

| 实时付费状态 | Stripe Webhook → KV 更新(可选) | 零 |

关于 Resend 发邮件

Resend 是"邮件即服务",你不需要自建邮件服务器。只需:

1. 有一个域名

2. 在 Resend 控制台添加两条 DNS TXT 记录(验证域名 + DKIM)

3. 之后即可用 API 发送邮件

Resend 背后托管了 SMTP 服务器、发信 IP 池、退信处理等一切基础设施。

为什么不需要数据库

  • 无密码 → 不需要存用户凭证
  • 无注册 → 不需要用户表
  • 用户身份 = 邮箱(验证码证明拥有权)
  • 邮箱 → Stripe customer ID 可存在 KV,或直接通过 Stripe API 按邮箱查询

最简路径(不用 KV、不用 Webhook,每次实时查 Stripe):

请求 → JWT 鉴权(含邮箱)→ 实时查 Stripe subscriptions → 返回结果

代价是每次多 200-500ms 延迟,适合低频场景。

JWT 鉴权流程

1. 用户输入邮箱 → 后端生成 6 位验证码 → Resend 发送邮件 → KV 存储验证码(TTL 10 分钟)

2. 用户输入验证码 → 后端比对 KV 中的验证码 → 调 Stripe 查询该邮箱是否有 active subscription

3. 签发 JWT:{ email, isPaid, stripeCustomerId, iat, exp },有效期 24 小时

4. 后续请求带 JWT → 中间件验证签名和过期时间 → 根据 isPaid 放行或拒绝

JWT vs 每次都查 Stripe

| 方案 | 延迟 | Stripe API 调用 | 场景 |

|------|------|----------------|------|

| JWT(本地方验证) | 零 | 仅在签发时 | 高频操作 |

| 每次都查 Stripe | 200-500ms | 每次请求 | 低频操作 |

Stripe Webhook(可选)

如果要求实时付费状态变化立即生效,监听 Stripe 事件:

| Stripe 事件 | KV 操作 |

|-------------|---------|

| checkout.session.completed | 写入 stripe:status:{email} = true |

| customer.subscription.updated | 更新状态 |

| customer.subscription.deleted | 写入 = false |

中间件在验证 JWT 后额外查 KV 覆盖,实现实时性。

如果不做 webhook,接受 JWT 签发时的快照(最长 24h 延迟),可以完全砍掉此部分。

Vercel 项目结构

my-app/
├── app/
│   ├── api/
│   │   ├── auth/
│   │   │   ├── send/route.ts      # 发验证码
│   │   │   └── verify/route.ts    # 验证+签发 JWT
│   │   ├── webhooks/
│   │   │   └── stripe/route.ts    # Stripe webhook(可选)
│   │   └── protected/
│   │       └── route.ts           # 付费用户 API
│   ├── page.tsx                   # 首页(输入邮箱)
│   └── dashboard/
│       └── page.tsx               # 付费仪表盘
├── lib/
│   ├── stripe.ts                  # Stripe 初始化
│   ├── kv.ts                      # Vercel KV 初始化
│   └── jwt.ts                     # JWT 签名/验证
├── middleware.ts                  # 鉴权中间件
├── .env.local
└── package.json

环境变量

STRIPE_SECRET_KEY=sk_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
JWT_SECRET=your-random-256bit-secret
KV_URL=...
KV_REST_TOKEN=...
RESEND_API_KEY=re_xxx

成本估算

| 服务 | 月费 | 免费层限制 |

|------|------|-----------|

| Vercel Hobby | $0 | 10 万次函数调用/天 |

| Vercel KV | $0 | 30 万 reads + 3 万 writes/月 |

| Resend | $0 | 100 封/天 |

| Stripe | 按交易 | 2.9% + $0.30/笔 |

| 域名 | ~$10-15/年 | 用于邮件 + 网站 |

月成本 ≈ $0(不超免费额度)

← 返回首页