支付系统

HappyShip 内置完整的双支付系统:Stripe 和 Creem。本文档将详细介绍两套支付系统的代码架构、支付流程、监听逻辑以及用户可自定义的部分。

双支付系统架构

🌐Stripe 支付

  • • 国际主流支付方案
  • • 完善的前端SDK集成
  • • 强大的Webhook事件系统
  • • 支持全球多种支付方式

🚀Creem 支付

  • • 简化的支付集成方案
  • • 直接URL重定向模式
  • • 轻量级API设计
  • • 适合快速部署

支付系统概述

HappyShip 模板支持两套完整的支付系统:

🌐 Stripe 支付系统

  • 完整的 Stripe Checkout 集成
  • 前端SDK + 后端API架构
  • 复杂的Webhook事件处理
  • 国际化支付体验

🚀 Creem 支付系统

  • 轻量级直接重定向模式
  • 简化的API接口设计
  • 自动化积分发放机制
  • 快速集成部署

💡 选择建议:如果需要复杂的支付功能和国际化支持,推荐使用 Stripe; 如果追求快速部署和简化流程,推荐使用 Creem。

1
代码架构对比

模板同时支持 Stripe 和 Creem 两套支付系统,两套系统在架构设计上各有特色。

S📁 Stripe 架构 - 复杂但功能强大

templates/ai-image-temp/src/
├── lib/
│ ├── stripe.ts ← Stripe 服务端配置
│ └── stripe-client.ts ← Stripe 客户端SDK
├── app/api/stripe/
│ ├── create-checkout-session/
│ │ └── route.ts ← 创建支付会话
│ └── webhooks/
│ └── route.ts ← Webhook 事件处理
└── .env.local ← Stripe 环境变量

C📁 Creem 架构 - 简洁高效

templates/ai-image-temp/src/
├── lib/
│ ├── creem.ts ← Creem 核心配置 + API封装
│ └── creem-client.ts ← 轻量级重定向函数
├── app/api/creem/
│ ├── create-checkout-session/
│ │ └── route.ts ← 创建支付会话
│ └── webhooks/
│ └── route.ts ← Webhook 事件处理
└── .env.local ← Creem 环境变量

🔧 架构对比分析

Stripe 特点
  • • 前端SDK复杂但功能丰富
  • • 需要处理多种Webhook事件
  • • 支持复杂的支付场景
  • • 更多的配置项和环境变量
Creem 特点
  • • 直接URL重定向,无需前端SDK
  • • 事件类型简单,处理逻辑清晰
  • • 专注于订阅场景
  • • 配置简单,集成快速
双支付系统架构对比图

Stripe vs Creem 双支付系统架构对比

2
API 实现对比

两套支付系统在 API 设计和实现方式上有显著差异,下面详细对比核心实现代码。

S📄 Stripe API 实现

// 复杂的支付会话创建
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{
price: priceId, // 使用复杂的 price_id
quantity: 1,
}],
metadata: { userId, planName },
subscription_data: { metadata: { userId } },
success_url: `${origin}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${origin}/pricing`,
});

C📄 Creem API 实现

// 简洁的支付会话创建
const response = await creem.createCheckoutSession({
productId: planId, // 直接使用产品ID
metadata: { userId, plan: planName },
successUrl: `${origin}/success`,
cancelUrl: `${origin}/pricing`,
});

🔀 客户端重定向实现对比

Stripe 客户端
// 需要加载 Stripe SDK
const stripe = await loadStripe();
await stripe.redirectToCheckout({
sessionId: session.id
});
Creem 客户端
// 直接重定向,无需SDK
window.location.href =
response.checkoutUrl;

🔔 Webhook 事件对比

Stripe Webhook 事件
// 复杂的事件类型
switch (event.type) {
case 'checkout.session.completed':
case 'invoice.payment_succeeded':
case 'customer.subscription.deleted':
}
Creem Webhook 事件
// 简化的事件类型
switch (eventType) {
case 'checkout.completed':
case 'subscription.active':
case 'subscription.cancelled':
}
API 实现对比图

双支付系统 API 实现流程对比

3
Pricing组件详解

Pricing.tsx 组件是整个支付系统的前端核心,负责展示价格套餐、处理用户支付交互和管理支付状态。

🎯 组件核心功能

价格展示:动态展示 Pro 和 Premium 套餐的价格和功能
用户状态:检查用户登录状态和当前订阅情况
支付触发:处理支付按钮点击事件
错误处理:捕获和显示支付过程中的错误
加载状态:显示支付处理过程中的加载动画
响应式设计:适配桌面端和移动端显示

💻 关键代码实现

// Pricing.tsx 中的支付处理函数
const handleSubscribe = async (planType: string) => {
if (!session) {
setLoginModal(true);
return;
}
setLoading(true);
try {
// 创建 Stripe Checkout 会话
const response = await fetch('/api/stripe/create-checkout-session', {
method: 'POST',
body: JSON.stringify({ planType })
});
// 重定向到 Stripe Checkout
const stripe = await getStripe();
await stripe.redirectToCheckout({ sessionId });
} catch (error) {
setError('支付处理失败,请重试');
}
};

🎨 UI组件结构

1
套餐卡片设计

使用渐变背景和阴影效果,突出显示推荐套餐

2
功能列表展示

清晰列出每个套餐包含的功能和积分数量

3
动态按钮状态

根据用户登录和订阅状态显示不同的按钮文字

4
加载和错误提示

支付过程中显示loading状态和错误信息反馈

Pricing组件界面截图

Pricing组件界面效果展示

4
Stripe配置文件

了解核心配置文件的结构,掌握如何修改价格计划和积分设置。

📄 stripe.ts 核心配置

// templates/ai-video-temp/src/lib/stripe.ts
export const STRIPE_PLANS = {
pro: {
priceId: process.env.STRIPE_PRO_PRICE_ID || '',
credits: 200, ← 可自定义积分数量
name: 'Pro', ← 可自定义套餐名称
price: 999, ← 显示价格(分)
},
premium: {
priceId: process.env.STRIPE_PREMIUM_PRICE_ID || '',
credits: 500, ← 可自定义积分数量
name: 'Premium', ← 可自定义套餐名称
price: 1999, ← 显示价格(分)
}
} as const;

🔧 环境变量配置

# .env.local 必需的 Stripe 配置
STRIPE_SECRET_KEY=sk_test_... ← Stripe 密钥
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... ← 公开密钥
STRIPE_WEBHOOK_SECRET=whsec_... ← Webhook 密钥
STRIPE_PRO_PRICE_ID=price_... ← Pro 套餐价格 ID
STRIPE_PREMIUM_PRICE_ID=price_... ← Premium 套餐价格 ID
Stripe配置文件示例

Stripe配置文件代码示例

5
Creem配置文件

Creem 配置相比 Stripe 更加简洁,采用产品ID而非价格ID,简化了配置过程。

📄 creem.ts 核心配置

// templates/ai-image-temp/src/lib/creem.ts
export const CREEM_PLANS = {
pro: {
productId: process.env.CREEM_PRO_PRODUCT_ID || '',
credits: 200, ← 可自定义积分数量
name: 'Pro', ← 可自定义套餐名称
price: 999, ← 显示价格(分)
},
premium: {
productId: process.env.CREEM_PREMIUM_PRODUCT_ID || '',
credits: 500, ← 可自定义积分数量
name: 'Premium', ← 可自定义套餐名称
price: 1999, ← 显示价格(分)
}
} as const;

🔧 Creem环境变量配置

# .env.local 必需的 Creem 配置
CREEM_SECRET_KEY=sk_test_... ← Creem 密钥
CREEM_WEBHOOK_SECRET=whsec_... ← Webhook 密钥
CREEM_PRO_PRODUCT_ID=prod_... ← Pro 套餐产品 ID
CREEM_PREMIUM_PRODUCT_ID=prod_... ← Premium 套餐产品 ID

🆚 配置对比分析

Stripe 配置特点
  • • 使用 price_id 而非产品ID
  • • 需要配置更多环境变量
  • • 支持复杂的定价模型
  • • 需要单独配置订阅数据
Creem 配置特点
  • • 直接使用产品ID,配置简单
  • • 环境变量数量更少
  • • 专注于订阅场景
  • • 配置即可使用,无需额外设置
Creem配置文件示例

Creem配置文件代码示例

6
支付流程详解

从用户点击支付按钮到积分到账的完整流程,包含前端交互、API 调用和后端处理。

🔄 支付流程步骤

1
用户点击订阅按钮

Pricing.tsx 组件处理按钮点击,验证用户登录状态

2
调用创建支付会话 API

POST /api/stripe/create-checkout-session 创建 Stripe Checkout 会话

3
重定向到 Stripe Checkout

用户在 Stripe 安全页面完成支付流程

4
Webhook 处理支付结果

Stripe 发送事件到 /api/stripe/webhooks,自动发放积分

5
显示支付结果

PaymentSuccessModal 组件显示支付成功/失败状态

📋 关键代码片段

// Pricing.tsx 中的支付处理逻辑
const response = await fetch('/api/stripe/create-checkout-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ planType });
});
// 重定向到 Stripe Checkout
const stripe = await getStripe();
await stripe.redirectToCheckout({ sessionId });

7
双Webhook监听系统

模板支持 Stripe 和 Creem 两套 Webhook 系统,分别负责监听各自的支付事件,自动处理订阅创建、支付成功、订阅取消等关键事件。

S🎯 Stripe Webhook 监听事件

customer.subscription.created:订阅创建时,在数据库中记录订阅信息并发放积分
invoice.payment_succeeded:支付成功时,自动发放当月积分到用户账户
customer.subscription.updated:订阅更新时,同步订阅状态和周期信息
customer.subscription.deleted:订阅取消时,将状态标记为已取消

C🎯 Creem Webhook 监听事件

checkout.completed:支付完成时,创建订阅记录并发放积分
subscription.active:订阅激活时,更新用户订阅状态
subscription.cancelled:订阅取消时,将状态标记为已取消
payment.failed:支付失败时,记录失败原因并通知用户

⚙️ Webhook 处理逻辑对比

Stripe Webhook 实现
// 复杂的签名验证
const signature = headers.get('stripe-signature');
const event = stripe.webhooks.constructEvent(
body, signature, webhookSecret
);
Creem Webhook 实现
// 简化的HMAC验证
const signature = creem.verifyWebhook(
body, headers, webhookSecret
);

💻 Webhook 代码示例

// 通用 Webhook 事件处理框架
switch (eventType) {
case 'checkout.completed': {
// 获取订阅信息和用户 ID
const userId = metadata.userId;
const credits = metadata.credits;
// 更新用户积分
await supabaseAdmin.from('users_profile')
.update({ credits }).eq('id', userId);
break;
}
}
双Webhook事件处理流程图

双支付系统 Webhook 事件处理流程对比

🎨
自定义配置指南

根据您的业务需求,可以灵活自定义价格计划、积分数量、套餐名称等关键配置。

🔧 常见自定义场景

1. 修改套餐价格和积分

stripe.ts 中调整价格和积分配置:

pro: {
credits: 300, ← 从 200 改为 300 积分
name: '基础版', ← 自定义中文名称
price: 1599, ← 调整显示价格为 $15.99
}
2. 添加新的套餐类型

扩展 STRIPE_PLANS 配置,添加更多套餐选项:

export const STRIPE_PLANS = {
basic: { priceId: 'price_basic', credits: 100, name: '基础版' },
pro: { priceId: 'price_pro', credits: 300, name: '专业版' },
premium: { priceId: 'price_premium', credits: 800, name: '高级版' },
enterprise: { priceId: 'price_enterprise', credits: 2000, name: '企业版' }
} as const;
3. 自定义支付成功页面

修改 PaymentSuccessModal.tsx 中的成功页面内容:

success_url: "${process.env.NEXTAUTH_URL}/?success=true&plan=${planType}"
cancel_url: "${process.env.NEXTAUTH_URL}/?canceled=true"
4. 自定义积分发放逻辑

在 Webhook 处理中添加自定义的积分计算逻辑:

// 可以添加积分加成、首次订阅奖励等逻辑
let finalCredits = credits;
if (isFirstSubscription) {
finalCredits += 100; // 首次订阅奖励 100 积分
}

✅ 自定义检查清单

在 Stripe Dashboard 中创建对应的价格产品
更新环境变量中的 PRICE_ID 配置
测试 Webhook 事件处理是否正常
验证积分发放和数据库更新逻辑

💡
最佳实践

🚀 开发和部署建议

测试环境配置:使用 Stripe 测试密钥,通过 4242 4242 4242 4242 测试卡进行完整支付流程测试
Webhook 安全:确保在生产环境中正确配置 STRIPE_WEBHOOK_SECRET,验证所有事件签名
错误处理:在支付失败时提供清晰的错误信息,引导用户重试或联系客服
日志监控:记录关键支付事件,便于调试和客服支持
用户体验:提供清晰的价格说明,支持多种支付方式,简化结账流程

⚡ 性能优化建议

客户端优化:懒加载 Stripe.js,只在用户准备支付时加载
数据库优化:为 subscriptions 表添加适当的索引,优化查询性能
缓存策略:缓存 Stripe 价格信息,减少 API 调用次数

💳 双支付系统总结

模板提供了完整的 Stripe 和 Creem 双支付解决方案,包含前端组件、API 接口、Webhook 处理和数据库集成。通过理解核心代码架构,您可以轻松选择适合的支付系统并自定义价格计划、积分规则和用户体验。

🏗️ 双系统架构

Stripe 和 Creem 并行支持,架构清晰易维护

🎨 灵活选择

根据需求选择复杂功能的 Stripe 或简洁高效的 Creem

🔒 安全可靠

双 Webhook 验证和完整的错误处理机制

🎯 选择适合您的支付系统,开始构建强大的 AI 应用吧!

目录