Files
qnc-server-v3/app/main/api/internal/logic/pay/paymentchecklogic.go
2026-06-07 15:11:33 +08:00

128 lines
4.0 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"
"strings"
"qnc-server/app/main/api/internal/service"
"qnc-server/app/main/api/internal/svc"
"qnc-server/app/main/api/internal/types"
"qnc-server/app/main/model"
"qnc-server/common/ctxdata"
"qnc-server/common/xerr"
"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, findErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if findErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询升级订单失败: %v", findErr)
}
return &types.PaymentCheckResp{Type: "agent_upgrade", Status: order.Status}, nil
}
order, findErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
if findErr != nil {
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", findErr)
}
resp = &types.PaymentCheckResp{Type: "query", Status: order.Status}
// xpay 轮询pending 时主动查微信单并到账(不通知微信发货)
if order.Status == model.OrderStatusPending && model.IsXpayOrder(order) &&
l.svcCtx.XpayService != nil && l.svcCtx.XpayService.Enabled() {
wxInfo, syncErr := l.syncXpayOrderStatus(order)
resp.WxOrderStatus = wxInfo.Status
resp.WxOrderDetail = wxInfo.RawOrder
if syncErr != nil {
resp.WxSyncError = syncErr.Error()
l.Errorf("[xpay] 轮询查单失败 order_no=%s local_status=%s wx_status=%d wx_detail=%s err=%v",
req.OrderNo, order.Status, wxInfo.Status, wxInfo.RawOrder, syncErr)
} else if wxInfo.Status > 0 && !service.IsXpayPaidStatus(wxInfo.Status) {
l.Infof("[xpay] 轮询查单未到账 order_no=%s wx_status=%d wx_detail=%s",
req.OrderNo, wxInfo.Status, wxInfo.RawOrder)
}
order, _ = l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
resp.Status = order.Status
}
return resp, nil
}
type xpaySyncInfo struct {
Status int
RawOrder string
}
func (l *PaymentCheckLogic) syncXpayOrderStatus(order *model.Order) (xpaySyncInfo, error) {
info := xpaySyncInfo{}
userID, err := ctxdata.GetUidFromCtx(l.ctx)
if err != nil {
return info, err
}
if order.UserId != userID {
return info, errors.New("无权查询此订单")
}
openid, err := l.svcCtx.XpayService.GetWxMiniOpenID(l.ctx, l.svcCtx.UserAuthModel, userID)
if err != nil {
return info, err
}
l.Infof("[xpay] check sync start order_no=%s openid=%s env=%d", order.OrderNo, openid, l.svcCtx.XpayService.Env())
status, err := l.svcCtx.XpayService.QueryOrder(l.ctx, openid, order.OrderNo, "")
if err != nil {
return info, err
}
info.Status = status.Status
info.RawOrder = status.RawOrder
if service.IsXpayPaidStatus(status.Status) {
_, fulfillErr := fulfillQueryOrderPaid(l.ctx, l.svcCtx, order, status.WxOrderID, status.PaidFee)
if fulfillErr != nil {
return info, fulfillErr
}
l.Infof("[xpay] check sync paid order_no=%s wx_order_id=%s paid_fee=%d",
order.OrderNo, status.WxOrderID, status.PaidFee)
return info, nil
}
if service.IsXpayRefundedStatus(status.Status) || service.IsXpayAlreadyRefunded(status) {
order.Status = model.OrderStatusRefunded
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
return info, updateErr
}
l.Infof("[xpay] check sync refunded order_no=%s wx_status=%d left_fee=%d", order.OrderNo, status.Status, status.LeftFee)
return info, nil
}
if service.IsXpayClosedStatus(status.Status) {
order.Status = model.OrderStatusClosed
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
return info, updateErr
}
l.Infof("[xpay] check sync closed order_no=%s wx_status=%d", order.OrderNo, status.Status)
return info, nil
}
return info, nil
}