Files
sim-server/app/main/api/internal/logic/pay/paymentchecklogic.go
2026-02-08 16:19:37 +08:00

209 lines
7.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package pay
import (
"context"
"sim-server/app/main/api/internal/svc"
"sim-server/app/main/api/internal/types"
"sim-server/common/xerr"
"sim-server/pkg/lzkit/lzUtils"
"strings"
"time"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
)
type PaymentCheckLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewPaymentCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentCheckLogic {
return &PaymentCheckLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *PaymentCheckLogic) PaymentCheck(req *types.PaymentCheckReq) (resp *types.PaymentCheckResp, err error) {
// 根据订单号前缀判断订单类型
if strings.HasPrefix(req.OrderNo, "U_") {
// 升级订单
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询升级订单失败: %v", err)
}
return &types.PaymentCheckResp{
Type: "agent_upgrade",
Status: order.Status,
}, nil
}
// 查询订单(包括代理订单)
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
}
// 如果订单状态是 pending 且支付平台是易支付,主动查询易支付订单状态
if order.Status == "pending" && order.PaymentPlatform == "easypay_alipay" {
// 检查易支付服务是否启用
if l.svcCtx.EasyPayService != nil {
// 主动查询易支付订单状态
queryResp, queryErr := l.svcCtx.EasyPayService.QueryOrderStatus(l.ctx, req.OrderNo)
if queryErr != nil {
logx.Errorf("主动查询易支付订单状态失败,订单号: %s, 错误: %v", req.OrderNo, queryErr)
// 查询失败不影响返回,继续返回当前订单状态
} else {
// 如果易支付返回订单已支付status == 1更新本地订单状态
if queryResp.GetStatusInt() == 1 {
logx.Infof("主动查询发现易支付订单已支付,订单号: %s开始更新订单状态", req.OrderNo)
// 重新查询订单(获取最新版本号)
order, err = l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
logx.Errorf("更新订单状态前重新查询订单失败: %v", err)
} else if order.Status == "pending" {
// 更新订单状态
order.Status = "paid"
order.PayTime = lzUtils.TimeToNullTime(time.Now())
if queryResp.TradeNo != "" {
order.PlatformOrderId = lzUtils.StringToNullString(queryResp.TradeNo)
}
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
logx.Errorf("主动查询后更新订单状态失败: %v", updateErr)
} else {
logx.Infof("主动查询后成功更新订单状态为已支付,订单号: %s", req.OrderNo)
// 发送异步任务处理后续流程
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
logx.Errorf("主动查询后发送异步任务失败: %v", asyncErr)
}
// 返回更新后的状态
return &types.PaymentCheckResp{
Type: "query",
Status: "paid",
}, nil
}
}
}
}
}
}
// 如果订单状态是 pending 且支付平台是云印签支付,主动查询云印签订单状态
if order.Status == "pending" && (order.PaymentPlatform == "yunyinSignPay" || order.PaymentPlatform == "yunyinSignPay_wechat" || order.PaymentPlatform == "yunyinSignPay_alipay") {
// 检查云印签支付服务是否启用
if l.svcCtx.YunYinSignPayService != nil {
// 主动查询云印签订单状态
queryResp, queryErr := l.svcCtx.YunYinSignPayService.QueryPayeeBill(l.ctx, req.OrderNo)
if queryErr != nil {
logx.Errorf("主动查询云印签订单状态失败,订单号: %s, 错误: %v", req.OrderNo, queryErr)
// 查询失败不影响返回,继续返回当前订单状态
} else {
// 根据云印签返回的支付状态更新本地订单状态
// 云印签 payStatus: 0-订单生成, 1-支付中, 2-支付成功, 3-支付失败, 4-已退款
// 我们的订单状态: pending, paid, failed, refunded
var newOrderStatus string
var shouldUpdate bool
switch queryResp.PayStatus {
case 2: // 支付成功
newOrderStatus = "paid"
shouldUpdate = true
case 3: // 支付失败
newOrderStatus = "failed"
shouldUpdate = true
case 4: // 已退款
newOrderStatus = "refunded"
shouldUpdate = true
case 0, 1: // 订单生成或支付中,保持 pending
// 不更新,继续返回 pending
}
if shouldUpdate {
logx.Infof("主动查询发现云印签订单状态已变更,订单号: %s, 支付状态: %d, 新订单状态: %s", req.OrderNo, queryResp.PayStatus, newOrderStatus)
// 重新查询订单(获取最新版本号)
order, err = l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if err != nil {
logx.Errorf("更新订单状态前重新查询订单失败: %v", err)
} else {
// 更新云印签订单表的支付状态(无论订单状态如何,都要同步云印签的状态)
yunyinOrder, findYunyinErr := l.svcCtx.YunyinSignPayOrderModel.FindOneByOrderId(l.ctx, order.Id)
if findYunyinErr == nil && yunyinOrder != nil {
// 更新支付状态
// 云印签 payStatus: 0-订单生成, 1-支付中, 2-支付成功, 3-支付失败, 4-已退款
// 我们的 payStatus: 0-待支付, 1-已支付, 2-已退款
var newPayStatus int64
if queryResp.PayStatus == 2 {
newPayStatus = 1 // 已支付
} else if queryResp.PayStatus == 4 {
newPayStatus = 2 // 已退款
} else if queryResp.PayStatus == 3 {
// 支付失败,保持待支付状态
newPayStatus = 0
}
if newPayStatus != yunyinOrder.PayStatus {
yunyinOrder.PayStatus = newPayStatus
if _, updateYunyinErr := l.svcCtx.YunyinSignPayOrderModel.Update(l.ctx, nil, yunyinOrder); updateYunyinErr != nil {
logx.Errorf("更新云印签订单支付状态失败: %v", updateYunyinErr)
} else {
logx.Infof("成功更新云印签订单支付状态订单ID: %s, 新支付状态: %d", order.Id, newPayStatus)
}
}
}
// 只有在订单状态是 pending 时才更新订单状态
if order.Status == "pending" {
// 更新订单状态
order.Status = newOrderStatus
if newOrderStatus == "paid" {
order.PayTime = lzUtils.TimeToNullTime(time.Now())
if queryResp.ChannelOrderNo != "" {
order.PlatformOrderId = lzUtils.StringToNullString(queryResp.ChannelOrderNo)
}
} else if newOrderStatus == "refunded" {
order.RefundTime = lzUtils.TimeToNullTime(time.Now())
}
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
logx.Errorf("主动查询后更新订单状态失败: %v", updateErr)
} else {
logx.Infof("主动查询后成功更新订单状态,订单号: %s, 新状态: %s", req.OrderNo, newOrderStatus)
// 如果订单已支付,发送异步任务处理后续流程
if newOrderStatus == "paid" {
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
logx.Errorf("主动查询后发送异步任务失败: %v", asyncErr)
}
}
// 返回更新后的状态
return &types.PaymentCheckResp{
Type: "query",
Status: newOrderStatus,
}, nil
}
} else {
// 订单状态已经不是 pending说明可能已经被其他流程处理
// 但仍然返回当前状态
logx.Infof("订单状态已不是 pending当前状态: %s跳过更新", order.Status)
}
}
}
}
}
}
return &types.PaymentCheckResp{
Type: "query",
Status: order.Status,
}, nil
}