支付集成指南.md 9.1 KB

AI语音应用 - 订阅支付系统集成指南

📋 功能概述

已实现的订阅支付系统包含:

  • ✅ 4个套餐等级(免费、基础、专业、旗舰)
  • ✅ Token配额系统
  • ✅ 订阅API和前端页面
  • ✅ 支付订单管理
  • ✅ Token使用记录
  • ✅ 模拟支付(开发环境)
  • ⏳ 真实支付宝支付(需配置)
  • ⏳ 真实微信支付(需配置)

💰 套餐定价

套餐 月付 年付 Token配额 主要功能
免费版 ¥0 ¥0 10,000/月 每天3次,每次2000字
基础版 ¥9.9 ¥99 50,000/月 全部音色,高清音质
专业版 ¥29.9 ¥299 200,000/月 无损音质,API访问
旗舰版 ¥99 ¥999 1,000,000/年 批量处理,团队管理

🔧 支付宝支付集成

1. 注册支付宝开放平台账号

访问:支付宝开放平台

2. 创建应用

  1. 登录开放平台
  2. 点击「创建应用」
  3. 选择「自研应用」
  4. 填写应用信息
  5. 添加能力:
    • 手机网站支付
    • APP支付
    • 当面付

3. 配置密钥

# 1. 生成RSA2密钥对
openssl genrsa -out app_private_key.pem 2048
openssl rsa -in app_private_key.pem -pubout -out app_public_key.pem

# 2. 在支付宝开放平台配置公钥
# 将 app_public_key.pem 内容上传到支付宝

# 3. 获取支付宝公钥

4. 配置环境变量

创建 .env 文件:

# 支付宝配置
ALIPAY_APP_ID=your_app_id
ALIPAY_GATEWAY=https://openapi.alipay.com/gateway.do
ALIPAY_PRIVATE_KEY=your_private_key
ALIPAY_PUBLIC_KEY=alipay_public_key
ALIPAY_NOTIFY_URL=https://your-domain.com/api/payment/alipay/callback

5. 安装SDK

npm install alipay-sdk

6. 更新支付服务

编辑 server/src/modules/payment/payment.service.ts

import Alipay from 'alipay-sdk'; // 添加

const alipay = new Alipay({
  appId: process.env.ALIPAY_APP_ID,
  privateKey: process.env.ALIPAY_PRIVATE_KEY,
  alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY,
});

async function generateAlipayUrl(orderNo: string, amount: number, subject: string): Promise<string> {
  const result = await alipay.exec('alipay.trade.page.pay', {
    outTradeNo: orderNo,
    productCode: 'FAST_INSTANT_TRADE_PAY',
    totalAmount: amount.toString(),
    subject: `AI语音应用-${subject}-订阅`,
    body: `订阅${subject}套餐`,
  });
  
  return result as string;
}

💚 微信支付集成

1. 注册微信商户平台账号

访问:微信商户平台

2. 申请接入

  1. 完成商户资质认证
  2. 选择接入方式:Native支付 / JSAPI支付 / APP支付
  3. 配置支付密钥

3. 获取API密钥

  1. 登录微信商户平台
  2. 进入「账户中心」→「API安全」
  3. 设置API密钥(32位)

4. 安装SDK

npm install wechat-pay

5. 配置环境变量

# 微信支付配置
WECHAT_APP_ID=your_app_id
WECHAT_MCH_ID=your_mch_id
WECHAT_API_KEY=your_api_key
WECHAT_NOTIFY_URL=https://your-domain.com/api/payment/wechat/callback

6. 更新支付服务

编辑 server/src/modules/payment/payment.service.ts

import { WechatPay } from 'wechat-pay';

const wechatPay = new WechatPay({
  mchId: process.env.WECHAT_MCH_ID,
  privateKey: process.env.WECHAT_API_KEY,
  appId: process.env.WECHAT_APP_ID,
});

async function generateWechatPay(orderNo: string, amount: number) {
  const result = await wechatPay.unifiedOrder({
    out_trade_no: orderNo,
    body: 'AI语音应用-套餐订阅',
    total_fee: Math.round(amount * 100), // 转换为分
    trade_type: 'NATIVE',
    notify_url: process.env.WECHAT_NOTIFY_URL,
  });
  
  return {
    qrcode: result.code_url,
  };
}

🌐 支付回调处理

支付宝回调

router.post('/alipay/callback', async (ctx: Context) => {
  const alipaySignature = ctx.get('sign');
  // 验证签名
  const signVerified = alipay.checkSignature(ctx.request.body);
  
  if (signVerified) {
    const { out_trade_no, trade_status, trade_no } = ctx.request.body;
    
    if (trade_status === 'TRADE_SUCCESS') {
      await PaymentService.handlePaymentCallback(out_trade_no, trade_no, 'success');
    }
  }
  
  ctx.body = 'success';
});

微信支付回调

router.post('/wechat/callback', async (ctx: Context) => {
  const xml = ctx.request.body;
  // 解析XML并验证签名
  
  if (result.return_code === 'SUCCESS' && result.result_code === 'SUCCESS') {
    await PaymentService.handlePaymentCallback(
      result.out_trade_no,
      result.transaction_id,
      'success'
    );
  }
  
  ctx.body = '<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>';
});

📱 前端支付流程

1. 选择套餐

// pages/member/index.vue
const selectedPlan = ref<Plan>(null);

function selectPlan(plan: Plan) {
  selectedPlan.value = plan;
}

2. 选择支付方式

const paymentMethod = ref<'alipay' | 'wechat'>('alipay');

3. 创建订单

async function createOrder() {
  const result = await post('/payment/create', {
    planId: selectedPlan.value.id,
    paymentMethod: paymentMethod.value
  });
  
  return result;
}

4. 跳转支付

支付宝:

if (result.paymentUrl) {
  window.location.href = result.paymentUrl;
}

微信支付:

if (result.qrcode) {
  // 显示二维码
  showQRCode(result.qrcode);
}

5. 轮询订单状态

async function pollOrderStatus(orderNo: string) {
  const interval = setInterval(async () => {
    const order = await get(`/payment/orders/${orderNo}`);
    if (order.status === 'paid') {
      clearInterval(interval);
      uni.showToast({ title: '支付成功', icon: 'success' });
      // 更新用户状态
    }
  }, 2000);
  
  // 30秒后停止轮询
  setTimeout(() => clearInterval(interval), 30000);
}

📊 数据库模型

SubscriptionPlan(套餐计划)

model SubscriptionPlan {
  id              Int       @id @default(autoincrement())
  name            String    // 套餐名称
  level           Int       // 套餐等级
  priceMonthly    Decimal   // 月付价格
  priceYearly     Decimal   // 年付价格
  monthlyTokens   Int       // 月Token配额
  yearlyTokens    Int?      // 年Token配额
  dailyGenerations Int      // 每日生成次数
  perGenerationLimit Int    // 单次生成限制
  voiceOptions    Int       // 可用音色数
  audioQuality    String    // 音质标准
  apiAccess       Boolean   // API权限
  batchProcessing Boolean   // 批量处理
  teamManagement  Boolean   // 团队管理
}

Subscription(订阅记录)

model Subscription {
  id        Int       @id @default(autoincrement())
  userId    Int
  planId    Int
  startDate DateTime
  endDate   DateTime
  status    String    // active, expired, cancelled
  autoRenew Boolean   // 自动续费
}

TokenUsage(Token使用记录)

model TokenUsage {
  id            Int       @id @default(autoincrement())
  userId        Int
  type          String    // text_to_speech, api_call
  amount        Int       // 消耗数量
  contentLength Int       // 内容长度
  description   String?
}

TokenBalance(Token余额)

model TokenBalance {
  id          Int       @id @default(autoincrement())
  userId      Int       @unique
  totalTokens Int       // 总配额
  usedTokens  Int       // 已使用
  resetDate   DateTime? // 重置日期
}

🔒 Token消耗计算

文本转语音

Token消耗 = 文本字数 × 1 Token/字

示例

  • 1000字文本 → 消耗 1000 Token
  • 5000字文本 → 消耗 5000 Token

扣费时机

  1. 用户提交TTS生成请求
  2. 检查Token余额
  3. 余额充足 → 扣除Token → 开始生成
  4. 余额不足 → 返回错误提示

🧪 测试支付

开发环境模拟支付

# 1. 创建订单
curl -X POST http://localhost:3000/api/payment/create \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"planId": 2, "paymentMethod": "mock"}'

# 2. 模拟支付成功
curl -X POST http://localhost:3000/api/payment/mock \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"orderNo": "PAY20260412XXXXXX"}'

📝 注意事项

1. 安全要点

  • ✅ 回调URL必须使用HTTPS
  • ✅ 验证支付回调签名
  • ✅ 防止订单重复处理
  • ✅ 使用环境变量存储密钥

2. 费用结算

  • 支付宝:T+1 结算
  • 微信:T+1 结算

3. 退款处理

  • 用户申请退款 → 后台审核 → 调用退款API
  • 退款后更新订阅状态和Token余额

4. 自动续费

  • 可选功能,用户同意后开启
  • 订阅到期前7天自动扣款

📞 技术支持

如遇问题,请检查:

  1. 环境变量配置是否正确
  2. 支付宝/微信商户平台配置
  3. 回调URL是否可访问
  4. 日志输出查看错误信息

🚀 下一步

  1. 配置真实的支付宝和微信支付
  2. 实现自动续费功能
  3. 添加退款功能
  4. 集成客服系统
  5. 添加数据分析报表