package thirdpay_notify import ( "PaymentCenter/app/constants/common" "PaymentCenter/app/constants/errorcode" "PaymentCenter/app/data" "PaymentCenter/app/http/entities" "PaymentCenter/app/models/appmodel" "PaymentCenter/app/models/ordercallbacklogmodel" "PaymentCenter/app/models/ordersmodel" "PaymentCenter/app/services" "PaymentCenter/app/utils" "PaymentCenter/app/utils/httpclient" "github.com/bytedance/sonic" "time" "xorm.io/builder" ) type OrderNotify struct { order *ordersmodel.Orders Code int app *appmodel.App OrderId int64 Status int //订单状态 ActualAmount int Msg string CompleteTime time.Time } type OrderNotifyResp struct { OrderId int64 Send bool ErrCode int SendTime time.Time Content *OrderNotify } type OrderNotifySendContent struct { OrderId int64 `json:"order_id"` OutTreadNo string `json:"out_tread_no"` CompleteTime time.Time `json:"complete_time"` OrderType int `json:"order-type"` Status int `json:"status"` Msg string `json:"msg"` ErrCode int `json:"err_code"` AppId int64 `json:"app_id"` ChannelId int64 `json:"channel_id"` MerchantId int64 `json:"merchant_id"` } func NewOrderNotifyWithHandle(orderId int64, Status int, actualAmount int, msg string) *OrderNotifyResp { orderNotify := &OrderNotify{ OrderId: orderId, Status: Status, ActualAmount: actualAmount, Msg: msg, Code: errorcode.Success, } return orderNotify.Handle() } func (o *OrderNotify) NotifyRespFail(errorCode int) *OrderNotifyResp { return &OrderNotifyResp{ OrderId: o.OrderId, Send: false, ErrCode: errorCode, Content: o, } } func (o *OrderNotify) Handle() (res *OrderNotifyResp) { o.checkOrder() if o.Code != errorcode.Success { return o.NotifyRespFail(o.Code) } o.checkApp() if o.Code != errorcode.Success { return o.NotifyRespFail(o.Code) } o.updateOrder() if o.Code != errorcode.Success { return o.NotifyRespFail(o.Code) } o.sendNotify(o.setBody()) if o.Code != errorcode.Success { return o.NotifyRespFail(o.Code) } return &OrderNotifyResp{ OrderId: o.OrderId, Send: true, ErrCode: o.Code, Content: o, } } // 发送下游回调通知 func (o *OrderNotify) sendNotify(body *OrderNotifySendContent) { var callbackStatus = common.STATUS_ENABLE var response string bodyByte, _ := sonic.Marshal(&body) headers := make(map[string]string, 1) headers["Content-Type"] = "application/json" resByte, err := httpclient.FastHttpPost(o.app.NotifyUrl, headers, bodyByte, 0) if err != nil || string(resByte) != "success" { o.Code = errorcode.NotifySendFail callbackStatus = common.STATUS_DISABLED response = "url=" + o.app.NotifyUrl + "|error=" + err.Error() } response = string(resByte) + response // 记录回调日志 go func(orderId int64, status int, request, response string) { repo := data.NewOrderCallbackLogRepo(ordercallbacklogmodel.GetInstance().GetDb()) log := ordercallbacklogmodel.OrderCallbackLog{ OrderId: orderId, MerchantRequest: string(bodyByte), Status: status, MerchantResponse: response, } _, insertErr := repo.OrderCallbackLogInsertOne(&log) if insertErr != nil { utils.Log(nil, "回调写入日志error", insertErr) } }(o.OrderId, callbackStatus, string(bodyByte), response) return } func (o *OrderNotify) setBody() *OrderNotifySendContent { return &OrderNotifySendContent{ OrderId: o.OrderId, OutTreadNo: o.order.OutTreadNo, CompleteTime: o.CompleteTime, Status: o.order.Status, OrderType: o.order.OrderType, Msg: o.Msg, ErrCode: o.Status, AppId: o.order.AppId, ChannelId: o.order.PayChannelId, MerchantId: o.order.MerchantId, } } func (o *OrderNotify) updateOrder() { if _, ok := common.OrderStatusMap[o.Status]; !ok { o.Code = errorcode.OrderStatusErr return } o.order.Status = o.Status o.Code = services.OrderUpdate(o.order, "status") return } func (o *OrderNotify) checkApp() { o.app, o.Code = services.AppFindOne(entities.IdRequest{Id: o.order.AppId}) if o.Code != errorcode.Success { return } if o.app.NotifyUrl == "" { o.Code = errorcode.AppNotifyUrlNotFound return } return } func (o *OrderNotify) checkOrder() { cond := builder.NewCond() cond = cond.And(builder.Eq{"id": o.OrderId}) o.order, o.Code = services.OrderFindOne(&ordersmodel.Orders{}, cond) if o.Code != errorcode.OrdersExist { return } if o.order.Status != common.ORDER_STATUS_PAYING { o.Code = errorcode.OrderStatusErr return } return }