Files
qnc-server-v3/app/main/api/internal/logic/pay/xpaypushlogic.go
2026-06-07 14:47:50 +08:00

102 lines
2.8 KiB
Go

package pay
import (
"encoding/json"
"io"
"net/http"
"qnc-server/app/main/api/internal/service"
"qnc-server/app/main/api/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type XpayPushLogic struct {
logx.Logger
svcCtx *svc.ServiceContext
}
func NewXpayPushLogic(svcCtx *svc.ServiceContext) *XpayPushLogic {
return &XpayPushLogic{svcCtx: svcCtx}
}
// HandleGET mp 后台配置消息推送时的验签
func (l *XpayPushLogic) HandleGET(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
signature := q.Get("signature")
timestamp := q.Get("timestamp")
nonce := q.Get("nonce")
echostr := q.Get("echostr")
if l.svcCtx.XpayService.VerifyPushSignature(signature, timestamp, nonce) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(echostr))
return
}
w.WriteHeader(http.StatusForbidden)
}
// HandlePOST 接收 xpay_goods_deliver_notify
func (l *XpayPushLogic) HandlePOST(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
l.writePushResp(w, 1, "read body failed")
return
}
var notify service.XpayDeliverNotify
if err := json.Unmarshal(body, &notify); err != nil {
l.writePushResp(w, 1, "parse failed")
return
}
if notify.Event != "" && notify.Event != "xpay_goods_deliver_notify" {
l.writePushResp(w, 0, "ignored")
return
}
orderNo := notify.OutTradeNo
if orderNo == "" {
l.writePushResp(w, 1, "missing OutTradeNo")
return
}
ctx := r.Context()
logx.WithContext(ctx).Infof("[xpay:push] recv event=%s order_no=%s openid=%s env=%d body=%s",
notify.Event, orderNo, notify.OpenId, notify.Env, string(body))
already, _ := l.svcCtx.XpayService.AlreadyNotified(ctx, orderNo)
if already {
l.writePushResp(w, 0, "already notified")
return
}
order, findErr := l.svcCtx.OrderModel.FindOneByOrderNo(ctx, orderNo)
if findErr != nil {
logx.WithContext(ctx).Errorf("[xpay push] 订单不存在 order_no=%s err=%v", orderNo, findErr)
l.writePushResp(w, 1, "order not found")
return
}
wxOrderID := notify.WeChatPayInfo.TransactionId
credited, fulfillErr := fulfillQueryOrderPaid(ctx, l.svcCtx, order, wxOrderID, notify.GoodsInfo.ActualPrice)
if fulfillErr != nil {
logx.WithContext(ctx).Errorf("[xpay push] 到账失败 order_no=%s err=%v", orderNo, fulfillErr)
l.writePushResp(w, 1, fulfillErr.Error())
return
}
_ = l.svcCtx.XpayService.MarkNotified(ctx, orderNo)
logx.WithContext(ctx).Infof("[xpay push] event=xpay_goods_deliver_notify order_no=%s credited=%v", orderNo, credited)
l.writePushResp(w, 0, "success")
}
func (l *XpayPushLogic) writePushResp(w http.ResponseWriter, errCode int, errMsg string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(map[string]interface{}{
"ErrCode": errCode,
"ErrMsg": errMsg,
})
}