版本: 1.0.0
更新时间: 2026-01-27
适用范围: 微信支付云函数 ↔ 业务后端服务
本项目采用云函数 + 业务后端的混合架构:
- 云函数层:处理微信支付相关操作(下单、回调、退款)
- 业务后端:处理业务逻辑(用户权益、生成任务、订单管理)
- 数据库:共享 MySQL 数据库,双方都可读写
- 数据库优先:云函数直接写入数据库,后端监听数据库变化
- API 备份:数据库不可用时,云函数通过 API 通知后端
- 幂等性:所有接口支持重复调用,不会产生副作用
- 异步处理:支付回调异步通知后端,不阻塞主流程
| 表名 | 用途 | 云函数 | 后端 |
|---|---|---|---|
users |
用户信息 | ✅ 读写 | ✅ 读写 |
payment_orders |
支付订单 | ✅ 读写 | ✅ 读写 |
refunds |
退款记录 | ✅ 读写 | ✅ 读写 |
payment_logs |
支付日志 | ✅ 写入 | ✅ 读取 |
generation_history |
生成历史 | ❌ | ✅ 读写 |
product_orders |
实体产品订单 | ❌ | ✅ 读写 |
greeting_cards |
电子贺卡 | ❌ | ✅ 读写 |
error_logs |
错误日志 | ❌ | ✅ 读写 |
用户基础信息表
CREATE TABLE users (
id VARCHAR(36) PRIMARY KEY COMMENT '用户ID (UUID)',
openid VARCHAR(100) UNIQUE COMMENT '微信OpenID',
unionid VARCHAR(100) COMMENT '微信UnionID',
nickname VARCHAR(100) COMMENT '用户昵称',
avatar_url TEXT COMMENT '头像URL',
phone VARCHAR(20) COMMENT '手机号',
payment_status ENUM('free', 'basic', 'premium') DEFAULT 'free' COMMENT '付费状态',
regenerate_count INT DEFAULT 3 COMMENT '重新生成次数',
last_login_at TIMESTAMP COMMENT '最后登录时间',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_openid (openid),
INDEX idx_payment_status (payment_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';字段说明:
id: 用户唯一标识,格式user-{timestamp}-{random}openid: 微信小程序 OpenID,用于支付和身份识别unionid: 微信 UnionID,用于跨应用用户识别payment_status: 付费状态free: 免费用户(默认)basic: 尝鲜包用户premium: 尊享包用户
regenerate_count: 剩余重新生成次数
云函数操作:
- 创建用户(通过 openid 查找不存在时自动创建)
- 查询用户(验证 user_id 有效性)
后端操作:
- 更新用户权益(支付成功后)
- 查询用户信息
- 更新用户资料
支付订单表(核心表)
CREATE TABLE payment_orders (
id VARCHAR(36) PRIMARY KEY COMMENT '订单ID (UUID)',
user_id VARCHAR(36) NOT NULL COMMENT '用户ID',
generation_id VARCHAR(36) NOT NULL COMMENT '关联的生成记录ID',
out_trade_no VARCHAR(100) UNIQUE NOT NULL COMMENT '商户订单号',
transaction_id VARCHAR(100) COMMENT '微信交易号',
amount DECIMAL(10, 2) NOT NULL COMMENT '订单金额(元)',
package_type ENUM('free', 'basic', 'premium') NOT NULL COMMENT '套餐类型',
payment_method VARCHAR(50) DEFAULT 'wechat' COMMENT '支付方式',
trade_type VARCHAR(20) DEFAULT 'JSAPI' COMMENT '支付类型',
status ENUM('pending', 'paid', 'failed', 'refunded') DEFAULT 'pending' COMMENT '订单状态',
paid_at TIMESTAMP NULL COMMENT '支付完成时间',
refund_reason TEXT COMMENT '退款原因',
remark TEXT COMMENT '备注',
_openid VARCHAR(100) COMMENT '支付用户OpenID(冗余字段)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_out_trade_no (out_trade_no),
INDEX idx_transaction_id (transaction_id),
INDEX idx_status (status),
INDEX idx_trade_type (trade_type),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付订单表';字段说明:
id: 订单唯一标识,格式order-{timestamp}-{random}out_trade_no: 商户订单号,格式{timestamp}{5位随机数},用于微信支付查询transaction_id: 微信交易号,支付成功后由回调更新amount: 订单金额(元),存储格式如0.01,29.90trade_type: 支付类型JSAPI: 小程序支付(默认)NATIVE: PC 扫码支付H5: H5 支付APP: APP 支付
status: 订单状态pending: 待支付(初始状态)paid: 已支付failed: 支付失败refunded: 已退款
_openid: 冗余字段,用于快速查询用户订单
云函数操作:
- 创建订单(下单时)
- 更新订单状态(支付回调时)
- 查询订单(通过 out_trade_no)
后端操作:
- 查询订单列表
- 更新订单备注
- 处理退款
- 导出订单数据
退款记录表
CREATE TABLE refunds (
id VARCHAR(36) PRIMARY KEY COMMENT '退款ID (UUID)',
out_refund_no VARCHAR(100) UNIQUE NOT NULL COMMENT '商户退款单号',
refund_id VARCHAR(100) COMMENT '微信退款单号',
out_trade_no VARCHAR(100) NOT NULL COMMENT '原订单号',
transaction_id VARCHAR(100) COMMENT '微信交易号',
refund_amount DECIMAL(10, 2) NOT NULL COMMENT '退款金额(元)',
total_amount DECIMAL(10, 2) NOT NULL COMMENT '订单总金额(元)',
status ENUM('pending', 'success', 'closed', 'abnormal') DEFAULT 'pending' COMMENT '退款状态',
reason TEXT COMMENT '退款原因',
refunded_at TIMESTAMP NULL COMMENT '退款完成时间',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_out_refund_no (out_refund_no),
INDEX idx_out_trade_no (out_trade_no),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款记录表';字段说明:
out_refund_no: 商户退款单号,唯一标识refund_id: 微信退款单号,退款成功后由回调更新status: 退款状态pending: 退款中success: 退款成功closed: 退款关闭abnormal: 退款异常
云函数操作:
- 创建退款记录
- 更新退款状态(退款回调时)
后端操作:
- 发起退款申请
- 查询退款状态
- 退款失败重试
支付日志表(用于审计和调试)
CREATE TABLE payment_logs (
id VARCHAR(36) PRIMARY KEY COMMENT '日志ID (UUID)',
type VARCHAR(50) NOT NULL COMMENT '日志类型',
out_trade_no VARCHAR(100) COMMENT '商户订单号',
out_refund_no VARCHAR(100) COMMENT '商户退款单号',
event_type VARCHAR(50) COMMENT '事件类型',
amount_total INT COMMENT '金额(分)',
request_data JSON COMMENT '请求数据',
response_data JSON COMMENT '响应数据',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_type (type),
INDEX idx_out_trade_no (out_trade_no),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付日志表';日志类型:
order_create: 创建订单payment_callback: 支付回调refund_create: 创建退款refund_callback: 退款回调
Base URL: 通过环境变量 API_BASE_URL 配置
开发环境: http://localhost:8080
生产环境: https://api.yourdomain.com
认证方式: 内部 API 使用 X-Internal-Secret 请求头
X-Internal-Secret: {INTERNAL_API_SECRET}用途: 数据库不可用时,云函数通过此接口通知后端订单创建
接口: POST /api/payment/internal/order-created
请求头:
Content-Type: application/json
X-Internal-Secret: {INTERNAL_API_SECRET}请求体:
{
"orderId": "order-1706345678901-abc123",
"outTradeNo": "170634567890112345",
"userId": "user-1706345678901-xyz789",
"openid": "oABC123xyz456",
"amount": 2990,
"packageType": "premium",
"tradeType": "JSAPI",
"status": "pending",
"reason": "db_unavailable",
"dbError": "Connection timeout"
}字段说明:
orderId: 订单ID(可选,数据库不可用时可能为空)outTradeNo: 商户订单号(必需)userId: 用户IDopenid: 微信OpenIDamount: 订单金额(分)packageType: 套餐类型basic|premiumtradeType: 支付类型JSAPI|NATIVEstatus: 订单状态,通常为pendingreason: 通知原因db_unavailable: 数据库不可用db_insert_failed: 数据库插入失败db_exception: 数据库异常
dbError: 数据库错误信息(可选)
响应:
{
"success": true,
"message": "订单已备份",
"orderId": "order-1706345678901-abc123"
}后端处理逻辑:
- 验证
X-Internal-Secret - 将订单信息存储到备份表或缓存
- 定期同步到主数据库
- 返回成功响应
用途: 支付成功后,云函数通知后端处理业务逻辑
接口: POST /api/payment/internal/notify
请求头:
Content-Type: application/json
X-Internal-Secret: {INTERNAL_API_SECRET}请求体:
{
"outTradeNo": "170634567890112345",
"transactionId": "4200001234567890123456789012345",
"status": "paid",
"packageType": "premium",
"generationId": "gen-1706345678901-def456",
"openid": "oABC123xyz456"
}字段说明:
outTradeNo: 商户订单号(必需)transactionId: 微信交易号(必需)status: 订单状态,通常为paidpackageType: 套餐类型generationId: 关联的生成任务ID(可选)openid: 支付用户OpenID
响应:
{
"success": true,
"message": "处理成功"
}后端处理逻辑:
- 验证
X-Internal-Secret - 查询订单信息(通过
outTradeNo) - 更新用户权益(
payment_status,regenerate_count) - 触发业务逻辑(如解锁生成任务)
- 发送支付成功通知(可选)
- 返回成功响应
注意事项:
- 接口必须支持幂等性(重复调用不会重复处理)
- 即使数据库已更新订单状态,后端仍需处理业务逻辑
- 建议异步处理,快速返回响应
用途: 云函数获取当前有效的价格配置
接口: GET /api/prices/current
请求头:
Content-Type: application/json响应:
{
"success": true,
"data": {
"packages": {
"basic": 0.01,
"premium": 29.90
},
"effectiveAt": "2026-01-27T00:00:00Z",
"updatedAt": "2026-01-26T10:30:00Z"
}
}字段说明:
packages.basic: 尝鲜包价格(元)packages.premium: 尊享包价格(元)effectiveAt: 价格生效时间updatedAt: 价格更新时间
云函数处理:
- 缓存价格配置 5 分钟
- API 不可用时使用降级价格(basic: 0.01, premium: 29.90)
用户 → 小程序 → 云函数 → 微信支付 → 云函数 → 数据库
↓ ↓
后端API ←────────────── 支付回调
详细步骤:
-
用户发起支付
- 小程序调用云函数
wxpay_order - 传入参数:
packageType,generationId,userId
- 小程序调用云函数
-
云函数创建订单
- 从 API 获取价格配置(带降级)
- 生成
out_trade_no - 调用微信支付 API 下单
- 写入数据库
payment_orders表 - 数据库失败时调用
/api/payment/internal/order-created
-
返回支付参数
- 返回
timeStamp,nonceStr,packageVal,paySign - 小程序调用
wx.requestPayment发起支付
- 返回
-
微信支付回调
- 微信支付成功后回调云函数
wxpay_order_callback - 云函数更新订单状态为
paid - 记录
transaction_id和paid_at - 调用
/api/payment/internal/notify通知后端
- 微信支付成功后回调云函数
-
后端处理业务
- 更新用户权益
- 解锁生成任务
- 发送通知
用户 → Web前端 → 云函数 → 微信支付 → 返回二维码
↓ ↓
数据库 用户扫码支付
↓ ↓
后端API ←────────────── 支付回调
详细步骤:
-
Web 前端发起支付
- 调用云函数
wxpay_order - 传入参数:
packageType,tradeType: 'NATIVE',userId
- 调用云函数
-
云函数创建订单
- 生成
out_trade_no - 调用微信支付 Native API
- 获取
code_url(二维码链接) - 写入数据库
- 生成
-
返回二维码
- 返回
codeUrl - 前端生成二维码展示给用户
- 返回
-
用户扫码支付
- 用户使用微信扫码
- 完成支付
-
支付回调
- 同 JSAPI 流程的步骤 4-5
后端 → 云函数 → 微信支付 → 云函数 → 数据库
↓
退款回调
↓
更新订单
详细步骤:
-
后端发起退款
- 调用云函数
wxpay_refund - 传入参数:
outTradeNo,refundAmount,reason
- 调用云函数
-
云函数处理退款
- 生成
out_refund_no - 调用微信支付退款 API
- 写入
refunds表
- 生成
-
微信退款回调
- 回调云函数
wxpay_refund_callback - 更新退款状态
- 全额退款时更新订单状态为
refunded
- 回调云函数
-
后端处理
- 监听数据库变化
- 更新用户权益(如需要)
在云函数配置中设置以下环境变量:
# 微信支付配置(必需)
WECHAT_APPID=wx1234567890abcdef
WECHAT_MCHID=1234567890
WECHAT_SERIAL_NO=1234567890ABCDEF1234567890ABCDEF12345678
WECHAT_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBg...\n-----END PRIVATE KEY-----
WECHAT_APIV3_KEY=your_apiv3_key_32_characters
# 微信支付公钥(可选,用于验证回调签名)
WECHAT_PUBLIC_KEY=-----BEGIN CERTIFICATE-----\nMIID...\n-----END CERTIFICATE-----
# 回调地址(可选,不配置则使用 API_BASE_URL 生成)
WECHAT_NOTIFY_URL=https://api.yourdomain.com/api/payment/callback
# 后端 API 地址(必需)
API_BASE_URL=https://api.yourdomain.com
# 内部 API 密钥(必需)
INTERNAL_API_SECRET=your_internal_secret_key_here# 数据库配置
DB_HOST=sh-cynosdbmysql-grp-ei51puvy.sql.tencentcdb.com
DB_PORT=22319
DB_USER=art
DB_PASSWORD=artPW192026
DB_NAME=test-1g71tc7eb37627e2
# 内部 API 密钥(与云函数保持一致)
INTERNAL_API_SECRET=your_internal_secret_key_here-
数据库不可用
- 跳过数据库操作
- 调用后端 API 备份订单
- 返回警告但不阻断支付流程
-
微信支付 API 失败
- 返回错误信息给前端
- 记录错误日志
- 不创建订单记录
-
后端 API 不可用
- 记录错误日志
- 不阻断主流程
- 后端可通过轮询数据库获取订单
-
订单重复通知
- 检查订单状态
- 已处理则直接返回成功
- 实现幂等性
-
用户不存在
- 尝试创建用户
- 创建失败则返回错误
-
数据库异常
- 使用事务保证一致性
- 失败时回滚
- 记录错误日志
所有内部 API 必须验证 X-Internal-Secret 请求头:
// 后端验证示例
const internalSecret = req.headers['x-internal-secret'];
if (internalSecret !== process.env.INTERNAL_API_SECRET) {
return res.status(401).json({ error: 'Unauthorized' });
}- 使用专用数据库用户
- 限制 IP 白名单
- 使用 SSL 连接
openid字段仅用于支付,不对外暴露- 私钥和密钥存储在环境变量中
- 日志中不记录完整的敏感信息
- 验证微信支付签名(如果配置了公钥)
- 验证订单金额
- 防止重复处理
Host: sh-cynosdbmysql-grp-ei51puvy.sql.tencentcdb.com
Port: 22319
User: art
Password: artPW192026
Database: test-1g71tc7eb37627e2
| 套餐类型 | 价格 | 权益 |
|---|---|---|
free |
免费 | 标清+水印,最多2人,基础3个模板 |
basic |
0.01元 | 高清无水印,4选1,最多5人,热门10个模板 |
premium |
29.90元 | 超清4K,4选1,无限制,全部模板,微动态视频 |
pending → paid → refunded
↓
failed
pending: 订单创建,等待支付paid: 支付成功failed: 支付失败(超时或取消)refunded: 已退款
Q: 数据库不可用时订单会丢失吗?
A: 不会。云函数会调用后端 API 备份订单,后端可以定期同步到主数据库。
Q: 支付回调失败怎么办?
A: 后端可以通过轮询 payment_orders 表获取新订单,或者通过微信支付查询接口主动查询订单状态。
Q: 如何测试支付流程?
A: 使用微信支付沙箱环境,或者使用 0.01 元的测试金额。
Q: 价格配置如何更新?
A: 在后端管理系统中更新价格配置,云函数会自动获取最新价格(5分钟缓存)。
- ✅ 初始版本
- ✅ 完整的数据库表结构说明
- ✅ API 接口规范
- ✅ 数据流转流程
- ✅ 环境变量配置
- ✅ 错误处理策略
- ✅ 安全规范
文档维护: 开发团队
联系方式: dev@yourdomain.com