Files
jnc-server/云印签支付流程检查.md
2026-01-16 03:33:02 +08:00

7.2 KiB
Raw Permalink Blame History

云印签支付流程完整性检查

一、支付创建流程

1. 前端流程

  • 位置: jnc-webview/src/components/Payment.vue
  • 步骤:
    1. 用户选择 yunyinSignPay_wechatyunyinSignPay_alipay
    2. 调用 /pay/payment 接口
    3. 获取 prepay_idprepay_data(支付链接)
    4. 直接跳转到支付链接:window.location.href = prepayUrl

2. 后端流程

  • 位置: jnc-server/app/main/api/internal/logic/pay/paymentlogic.go
  • 步骤:
    1. 接收支付请求
    2. 从查询缓存获取用户姓名和手机号
    3. 查询是否有未完成的签署(复用逻辑)
    4. 如果有未完成签署:
      • 复用 task_idparticipant_id
      • 获取新的支付链接
    5. 如果没有未完成签署:
      • 获取 token 和操作ID带缓存
      • 发起签署流程
      • 获取支付链接
    6. 创建订单记录(order 表)
    7. 创建云印签订单记录(yunyin_sign_pay_order 表)
    8. 返回支付链接(字符串类型,使用 PrepayId 字段)

3. 数据存储

  • 订单表 (order):

    • order_no: 订单号
    • payment_platform: yunyinSignPay_wechatyunyinSignPay_alipay
    • status: pending
    • 注意: 不再在 remark 中存储云印签信息
  • 云印签订单表 (yunyin_sign_pay_order):

    • order_id: 关联订单ID
    • user_id: 用户ID用于查询未完成签署
    • task_id: 任务ID/流程ID唯一索引
    • participant_id: 参与者ID
    • source_order_code: 源订单号(用于查询支付状态)
    • amount: 支付金额
    • pay_type: 支付类型0=微信1=支付宝)
    • sign_status: 签署状态0=待签署)
    • pay_status: 支付状态0=待支付)
    • user_mobile: 用户手机号(冗余字段)
    • user_name: 用户姓名(冗余字段)

二、支付状态查询流程

1. 前端轮询

  • 位置: jnc-webview/src/views/PaymentResult.vue
  • 步骤:
    1. 用户从支付页面返回后,进入支付结果页面
    2. 从 URL 参数获取 order_noout_trade_no
    3. 首次调用 /pay/check 接口
    4. 如果状态是 pending开始轮询每3秒一次最多30次
    5. 如果状态变为 paidrefunded,停止轮询并跳转到结果页面

2. 后端主动查询

  • 位置: jnc-server/app/main/api/internal/logic/pay/paymentchecklogic.go
  • 步骤:
    1. 查询订单状态
    2. 如果订单状态是 pending 且支付平台是云印签:
      • 调用 QueryPayeeBill 查询云印签平台
      • 使用 sourceOrderCode(订单号)查询
    3. 根据云印签返回的 payStatus 更新订单状态:
      • 2 (支付成功) → paid
      • 3 (支付失败) → failed
      • 4 (已退款) → refunded
      • 0, 1 (订单生成/支付中) → 保持 pending
    4. 同步更新 yunyin_sign_pay_order 表的支付状态
    5. 如果支付成功,发送异步任务处理后续流程

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: 首次支付(创建新签署流程)

  1. 用户选择云印签支付
  2. 后端查询无未完成签署
  3. 创建新签署流程
  4. 创建订单和云印签订单记录
  5. 返回支付链接
  6. 前端跳转到支付页面
  7. 用户完成支付
  8. 前端轮询查询状态
  9. 后端主动查询云印签平台
  10. 更新订单状态为 paid
  11. 发送异步任务处理后续流程
  12. 前端跳转到结果页面

场景2: 复用未完成签署

  1. 用户之前创建了签署但未支付
  2. 用户再次选择云印签支付
  3. 后端查询到未完成签署
  4. 复用 task_idparticipant_id
  5. 获取新的支付链接
  6. 创建新订单和云印签订单记录(关联新的订单)
  7. 返回支付链接
  8. 后续流程同场景1

场景3: 支付失败

  1. 用户支付失败
  2. 前端轮询查询状态
  3. 后端查询到 payStatus = 3
  4. 更新订单状态为 failed
  5. 前端显示支付失败提示

场景4: 退款

  1. 订单已支付
  2. 发生退款
  3. 前端轮询查询状态
  4. 后端查询到 payStatus = 4
  5. 更新订单状态为 refunded
  6. 更新退款时间
  7. 前端显示退款状态

六、总结

已完成的流程

  1. 支付创建流程(包括复用逻辑)
  2. 支付状态主动查询
  3. 订单状态自动更新
  4. 云印签订单表数据同步
  5. 前后端数据字段一致性
  6. 错误处理和边界情况

代码质量

  • 使用了事务保证数据一致性
  • 使用了乐观锁避免并发问题
  • 错误处理完善
  • 日志记录详细

前后端联调

  • API 接口定义清晰
  • 数据字段命名一致
  • 状态映射正确
  • 轮询机制完善

七、建议测试点

  1. 首次支付流程: 验证创建新签署流程是否正常
  2. 复用签署流程: 验证复用逻辑是否正常工作
  3. 支付成功: 验证状态更新和后续流程是否正常
  4. 支付失败: 验证失败状态是否正确处理
  5. 退款: 验证退款状态是否正确处理
  6. 网络异常: 验证查询失败时的容错处理
  7. 并发支付: 验证同一用户多次支付的场景
  8. 订单状态一致性: 验证订单表和云印签订单表的状态是否同步