网站 📝 60 条提示词 ⏱ 14 天可完成 2026/6/1

SaaS 订阅付费工具站

带用户注册登录、订阅付费、功能权限控制的完整 SaaS 框架,集成 Stripe 支付,可套用到任意工具产品。

Next.jsPrismaPostgreSQLStripeNextAuth.js

项目概述

这是一个可复用的 SaaS 基础框架,包含所有 SaaS 产品必备的基础设施:

  • 认证系统:邮箱注册、Google/GitHub OAuth
  • 订阅管理:免费版、Pro 版、企业版三档
  • 支付集成:Stripe 订阅、Webhook 处理
  • 权限控制:基于订阅计划的功能限制
  • 用户仪表盘:使用量统计、账单管理

订阅计划设计

const PLANS = {
  free: {
    name: '免费版',
    price: 0,
    limits: {
      apiCalls: 100,      // 每月 API 调用次数
      projects: 3,         // 最多项目数
      storage: 100,        // MB
    },
    features: ['基础功能', '社区支持'],
  },
  pro: {
    name: 'Pro 版',
    price: 29,             // 美元/月
    stripePriceId: 'price_xxx',
    limits: {
      apiCalls: 10000,
      projects: 50,
      storage: 10240,      // 10GB
    },
    features: ['全部功能', '优先支持', 'API 访问'],
  },
  enterprise: {
    name: '企业版',
    price: 99,
    stripePriceId: 'price_yyy',
    limits: {
      apiCalls: -1,        // 无限制
      projects: -1,
      storage: -1,
    },
    features: ['无限使用', '专属客服', 'SLA 保障', '自定义集成'],
  },
};

核心功能实现

权限中间件

// middleware/checkPlan.ts
export function requirePlan(minPlan: 'free' | 'pro' | 'enterprise') {
  return async (req: Request, res: Response, next: NextFunction) => {
    const user = await prisma.user.findUnique({
      where: { id: req.user.id },
      include: { subscription: true },
    });

    const planOrder = { free: 0, pro: 1, enterprise: 2 };
    const userPlan = user?.subscription?.plan ?? 'free';

    if (planOrder[userPlan] < planOrder[minPlan]) {
      return res.status(403).json({
        error: 'PLAN_REQUIRED',
        message: `此功能需要 ${minPlan} 及以上套餐`,
        upgradeUrl: '/pricing',
      });
    }

    next();
  };
}

// 使用示例
router.post('/api/export', requirePlan('pro'), exportHandler);

Stripe Webhook 处理

app.post('/api/webhooks/stripe',
  express.raw({ type: 'application/json' }),
  async (req, res) => {
    const sig = req.headers['stripe-signature']!;
    let event: Stripe.Event;

    try {
      event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
    } catch {
      return res.status(400).send('Webhook signature verification failed');
    }

    switch (event.type) {
      case 'customer.subscription.created':
      case 'customer.subscription.updated':
        await handleSubscriptionChange(event.data.object as Stripe.Subscription);
        break;
      case 'customer.subscription.deleted':
        await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
        break;
      case 'invoice.payment_failed':
        await handlePaymentFailed(event.data.object as Stripe.Invoice);
        break;
    }

    res.json({ received: true });
  }
);

关键提示词

提示词:使用量限制检查

实现一个使用量检查中间件:

1. 每次 API 调用时,检查用户本月已使用次数
2. 如果超过当前套餐限制,返回 429 错误和升级提示
3. 使用 Redis 缓存计数,key 格式:usage:{userId}:{year}:{month}
4. 每月 1 日自动重置计数
5. 在响应头中返回剩余次数:X-RateLimit-Remaining

技术栈:Express + Redis (ioredis) + Prisma