Files
jnc-server/app/main/api/internal/logic/pay/easypaycallbacklogic.go
2025-12-31 16:54:17 +08:00

123 lines
3.7 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"
"jnc-server/app/main/api/internal/service"
"jnc-server/pkg/lzkit/lzUtils"
"net/http"
"strings"
"time"
"jnc-server/app/main/api/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type EasyPayCallbackLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewEasyPayCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EasyPayCallbackLogic {
return &EasyPayCallbackLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *EasyPayCallbackLogic) EasyPayCallback(w http.ResponseWriter, r *http.Request) error {
// 检查易支付服务是否启用
if l.svcCtx.EasyPayService == nil {
logx.Errorf("易支付服务未启用")
w.WriteHeader(http.StatusInternalServerError)
return nil
}
notification, err := l.svcCtx.EasyPayService.HandleEasyPayNotification(r)
if err != nil {
logx.Errorf("易支付回调处理失败: %v", err)
w.WriteHeader(http.StatusBadRequest)
return nil
}
// 根据订单号前缀判断订单类型
orderNo := notification.OutTradeNo
if strings.HasPrefix(orderNo, "Q_") {
// 查询订单处理
return l.handleQueryOrderPayment(w, notification)
} else if strings.HasPrefix(orderNo, "A_") {
// 旧系统会员充值订单(已废弃,新系统使用升级功能)
// 直接返回成功,避免旧订单影响
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
} else if strings.HasPrefix(orderNo, "U_") {
// 系统简化:移除升级功能,直接返回成功
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
} else {
// 兼容旧订单,假设没有前缀的是查询订单
return l.handleQueryOrderPayment(w, notification)
}
}
// 处理查询订单支付
func (l *EasyPayCallbackLogic) handleQueryOrderPayment(w http.ResponseWriter, notification *service.EasyPayNotification) error {
order, findOrderErr := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, notification.OutTradeNo)
if findOrderErr != nil {
logx.Errorf("易支付回调,查找订单失败: %+v", findOrderErr)
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}
if order.Status != "pending" {
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}
// 验证支付状态
if !l.svcCtx.EasyPayService.IsPaymentSuccess(notification) {
logx.Infof("易支付回调,订单未支付成功,订单号: %s, 状态: %s", notification.OutTradeNo, notification.TradeStatus)
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}
// 验证金额(转换为字符串比较)
amountStr := lzUtils.ToAlipayAmount(order.Amount)
if amountStr != notification.Money {
logx.Errorf("易支付回调,金额不一致,订单号: %s, 订单金额: %s, 回调金额: %s", notification.OutTradeNo, amountStr, notification.Money)
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}
// 更新订单状态
order.Status = "paid"
order.PayTime = lzUtils.TimeToNullTime(time.Now())
order.PlatformOrderId = lzUtils.StringToNullString(notification.TradeNo)
if updateErr := l.svcCtx.OrderModel.UpdateWithVersion(l.ctx, nil, order); updateErr != nil {
logx.Errorf("易支付回调,修改订单信息失败: %+v", updateErr)
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}
// 发送异步任务处理后续流程
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
logx.Errorf("异步任务调度失败: %v", asyncErr)
// 不返回错误,因为订单已经更新成功
}
// 返回success易支付要求返回纯字符串success
w.WriteHeader(http.StatusOK)
w.Write([]byte("success"))
return nil
}