From 7a887833ad7073e14529cad835047bf4edb0fa63 Mon Sep 17 00:00:00 2001 From: Rzy <465386466@qq.com> Date: Tue, 6 Aug 2024 18:46:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/constants/errorcode/error_code.go | 13 +- app/services/order.go | 11 ++ app/services/thirdpay/notify/notify.go | 164 +++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 app/services/thirdpay/notify/notify.go diff --git a/app/constants/errorcode/error_code.go b/app/constants/errorcode/error_code.go index 7285e91..2f1a82c 100644 --- a/app/constants/errorcode/error_code.go +++ b/app/constants/errorcode/error_code.go @@ -35,6 +35,7 @@ const ( AppIpNotAllow = 1202 AppRsaDecryptKeyNotFound = 1203 AppDecryptDataDiscrepancy = 1204 + AppNotifyUrlNotFound = 1205 AppRsaDecryptFail = 1210 AppRsaEncryptKeyNotFound = 1211 AppRsaEncryptFail = 1212 @@ -56,11 +57,16 @@ const ( OrdersNotFound = 1401 OrdersExist = 1402 OrderTypeNotFount = 1403 + OrderIsDelete = 1405 + OrderStatusErr = 1406 //请求日志 RequestLogErrors = 1500 RequestLogNotFound = 1501 RequestResponseValid = 1502 + + //回调 + NotifySendFail = 1600 ) var MsgEN = map[int]string{ @@ -84,7 +90,8 @@ var MsgZH = map[int]string{ AppDisabled: "app通道关闭", AppIpNotAllow: "ip不在白名单内", AppDecryptDataDiscrepancy: "解密数据不一致", - SystemError: "系统错误", + SystemError: "系统错误", + AppNotifyUrlNotFound: "未设置回调地址", AppRsaDecryptKeyNotFound: "密匙缺失,无法进行Rsa解密", AppRsaDecryptFail: "Rsa解密失败", @@ -112,6 +119,10 @@ var MsgZH = map[int]string{ OrdersNotFound: "未找到订单", OrdersExist: "订单已存在", OrderTypeNotFount: "未知的支付方式", + OrderIsDelete: "订单已删除", + OrderStatusErr: "订单状态错误", + + NotifySendFail: "回调发送失败", } var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH} diff --git a/app/services/order.go b/app/services/order.go index 82b4fe4..18c43a5 100644 --- a/app/services/order.go +++ b/app/services/order.go @@ -82,6 +82,17 @@ func OrderCreate(orderIn *ordersmodel.Orders) (orderOut *ordersmodel.Orders, cod return orderIn, code } +func OrderUpdate(order *ordersmodel.Orders, col ...string) (code int) { + repo := data.NewOrderRepo(ordersmodel.GetInstance().GetDb()) + // 拼接查询条件 + conn := builder.NewCond() + conn = conn.And(builder.Eq{"Id": order.Id}) + _, err := repo.OrderUpdate(order, conn, col...) + + code = handErr(err) + return +} + func OrderFindOne(order *ordersmodel.Orders, conn builder.Cond, col ...string) (merchantInfo *ordersmodel.Orders, code int) { repo := data.NewOrderRepo(ordersmodel.GetInstance().GetDb()) // 拼接查询条件 diff --git a/app/services/thirdpay/notify/notify.go b/app/services/thirdpay/notify/notify.go new file mode 100644 index 0000000..8cad419 --- /dev/null +++ b/app/services/thirdpay/notify/notify.go @@ -0,0 +1,164 @@ +package notify + +import ( + "PaymentCenter/app/constants/common" + "PaymentCenter/app/constants/errorcode" + "PaymentCenter/app/http/entities" + "PaymentCenter/app/models/appmodel" + "PaymentCenter/app/models/ordersmodel" + "PaymentCenter/app/services" + "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 + ErrCode 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"` + 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, errCode int, actualAmount int, msg string) *OrderNotifyResp { + orderNotify := &OrderNotify{ + OrderId: orderId, + ErrCode: errCode, + 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.ErrCode, + Content: o, + } +} + +func (o *OrderNotify) sendNotify(body *OrderNotifySendContent) { + + 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 + } + return +} + +func (o *OrderNotify) setBody() *OrderNotifySendContent { + return &OrderNotifySendContent{ + OrderId: o.OrderId, + OutTreadNo: o.order.OutTreadNo, + CompleteTime: o.CompleteTime, + Status: o.order.Status, + Msg: o.Msg, + ErrCode: o.ErrCode, + AppId: o.order.AppId, + ChannelId: o.order.PayChannelId, + MerchantId: o.order.MerchantId, + } +} + +func (o *OrderNotify) updateOrder() { + if o.ErrCode == errorcode.Success { + o.order.Status = common.ORDER_STATUS_FAILED + } else { + o.order.Status = common.ORDER_STATUS_PAYED + } + 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.DeleteTime.IsZero() { + o.code = errorcode.AppDisabled + 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.Success { + return + } + if o.order.DeleteTime.IsZero() { + o.code = errorcode.OrderIsDelete + return + } + if o.order.Status != common.ORDER_STATUS_PAYING { + o.code = errorcode.OrderStatusErr + return + } + return +}