7.2 KiB
7.2 KiB
云印签支付流程完整性检查
一、支付创建流程
1. 前端流程 ✅
- 位置:
jnc-webview/src/components/Payment.vue - 步骤:
- 用户选择
yunyinSignPay_wechat或yunyinSignPay_alipay - 调用
/pay/payment接口 - 获取
prepay_id或prepay_data(支付链接) - 直接跳转到支付链接:
window.location.href = prepayUrl
- 用户选择
2. 后端流程 ✅
- 位置:
jnc-server/app/main/api/internal/logic/pay/paymentlogic.go - 步骤:
- 接收支付请求
- 从查询缓存获取用户姓名和手机号
- 查询是否有未完成的签署(复用逻辑)
- 如果有未完成签署:
- 复用
task_id和participant_id - 获取新的支付链接
- 复用
- 如果没有未完成签署:
- 获取 token 和操作ID(带缓存)
- 发起签署流程
- 获取支付链接
- 创建订单记录(
order表) - 创建云印签订单记录(
yunyin_sign_pay_order表) - 返回支付链接(字符串类型,使用
PrepayId字段)
3. 数据存储 ✅
-
订单表 (
order):order_no: 订单号payment_platform:yunyinSignPay_wechat或yunyinSignPay_alipaystatus:pending- 注意: 不再在
remark中存储云印签信息
-
云印签订单表 (
yunyin_sign_pay_order):order_id: 关联订单IDuser_id: 用户ID(用于查询未完成签署)task_id: 任务ID/流程ID(唯一索引)participant_id: 参与者IDsource_order_code: 源订单号(用于查询支付状态)amount: 支付金额pay_type: 支付类型(0=微信,1=支付宝)sign_status: 签署状态(0=待签署)pay_status: 支付状态(0=待支付)user_mobile: 用户手机号(冗余字段)user_name: 用户姓名(冗余字段)
二、支付状态查询流程
1. 前端轮询 ✅
- 位置:
jnc-webview/src/views/PaymentResult.vue - 步骤:
- 用户从支付页面返回后,进入支付结果页面
- 从 URL 参数获取
order_no或out_trade_no - 首次调用
/pay/check接口 - 如果状态是
pending,开始轮询(每3秒一次,最多30次) - 如果状态变为
paid或refunded,停止轮询并跳转到结果页面
2. 后端主动查询 ✅
- 位置:
jnc-server/app/main/api/internal/logic/pay/paymentchecklogic.go - 步骤:
- 查询订单状态
- 如果订单状态是
pending且支付平台是云印签:- 调用
QueryPayeeBill查询云印签平台 - 使用
sourceOrderCode(订单号)查询
- 调用
- 根据云印签返回的
payStatus更新订单状态:2(支付成功) →paid3(支付失败) →failed4(已退款) →refunded0, 1(订单生成/支付中) → 保持pending
- 同步更新
yunyin_sign_pay_order表的支付状态 - 如果支付成功,发送异步任务处理后续流程
3. 状态映射 ✅
-
云印签 payStatus:
0: 订单生成1: 支付中2: 支付成功3: 支付失败4: 已退款
-
我们的订单状态:
pending: 待支付paid: 已支付failed: 支付失败refunded: 已退款
-
我们的支付状态 (
yunyin_sign_pay_order.pay_status):0: 待支付1: 已支付2: 已退款
三、前后端数据字段一致性 ✅
1. 支付创建接口 (/pay/payment)
-
请求字段:
pay_method(支持yunyinSignPay_wechat,yunyinSignPay_alipay) -
响应字段:
prepay_id: 支付链接(字符串类型)prepay_data: 备用字段(对象类型)order_no: 订单号
-
前端读取:
data.value.data.prepay_id || data.value.data.prepay_data✅
2. 支付状态查询接口 (/pay/check)
-
请求字段:
order_no -
响应字段:
type:"query"status:"pending"|"paid"|"failed"|"refunded"
-
前端处理: 根据
status判断是否继续轮询 ✅
四、潜在问题和改进建议
⚠️ 问题1: 支付完成后用户可能不会自动跳转
现状: 云印签支付完成后,用户可能不会自动跳转回我们的页面 解决方案:
- ✅ 已实现:前端通过轮询主动查询支付状态
- ✅ 已实现:用户手动返回后,支付结果页面会自动轮询
⚠️ 问题2: 订单状态更新需要检查并发
现状: 使用乐观锁更新订单状态,但需要确保不会重复更新
检查: ✅ 已实现:使用 UpdateWithVersion 和检查 order.Status == "pending"
⚠️ 问题3: 查询失败时的处理
现状: 如果查询云印签平台失败,会记录错误但继续返回当前状态 检查: ✅ 已实现:错误处理完善,不影响正常流程
⚠️ 问题4: 未找到收款单记录的处理
现状: 如果订单刚创建,云印签平台可能还没有记录
检查: ✅ 已实现:返回错误但不影响,继续返回 pending 状态,前端会继续轮询
五、完整流程验证
场景1: 首次支付(创建新签署流程)✅
- 用户选择云印签支付
- 后端查询无未完成签署
- 创建新签署流程
- 创建订单和云印签订单记录
- 返回支付链接
- 前端跳转到支付页面
- 用户完成支付
- 前端轮询查询状态
- 后端主动查询云印签平台
- 更新订单状态为
paid - 发送异步任务处理后续流程
- 前端跳转到结果页面
场景2: 复用未完成签署 ✅
- 用户之前创建了签署但未支付
- 用户再次选择云印签支付
- 后端查询到未完成签署
- 复用
task_id和participant_id - 获取新的支付链接
- 创建新订单和云印签订单记录(关联新的订单)
- 返回支付链接
- 后续流程同场景1
场景3: 支付失败 ✅
- 用户支付失败
- 前端轮询查询状态
- 后端查询到
payStatus = 3 - 更新订单状态为
failed - 前端显示支付失败提示
场景4: 退款 ✅
- 订单已支付
- 发生退款
- 前端轮询查询状态
- 后端查询到
payStatus = 4 - 更新订单状态为
refunded - 更新退款时间
- 前端显示退款状态
六、总结
✅ 已完成的流程
- 支付创建流程(包括复用逻辑)
- 支付状态主动查询
- 订单状态自动更新
- 云印签订单表数据同步
- 前后端数据字段一致性
- 错误处理和边界情况
✅ 代码质量
- 使用了事务保证数据一致性
- 使用了乐观锁避免并发问题
- 错误处理完善
- 日志记录详细
✅ 前后端联调
- API 接口定义清晰
- 数据字段命名一致
- 状态映射正确
- 轮询机制完善
七、建议测试点
- 首次支付流程: 验证创建新签署流程是否正常
- 复用签署流程: 验证复用逻辑是否正常工作
- 支付成功: 验证状态更新和后续流程是否正常
- 支付失败: 验证失败状态是否正确处理
- 退款: 验证退款状态是否正确处理
- 网络异常: 验证查询失败时的容错处理
- 并发支付: 验证同一用户多次支付的场景
- 订单状态一致性: 验证订单表和云印签订单表的状态是否同步