From 163b27ca6ee5a51ca2383a8ac6949ae861bdd903 Mon Sep 17 00:00:00 2001 From: gazebo Date: Fri, 20 Dec 2019 11:19:47 +0800 Subject: [PATCH 1/2] wxpay partner --- business/model/api_config.go | 2 + business/partner/pay/pay.go | 51 ++++++++++++++++++ business/partner/pay/wxpay/callback.go | 60 +++++++++++++++++++++ business/partner/pay/wxpay/wxpay.go | 73 ++++++++++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 business/partner/pay/pay.go create mode 100644 business/partner/pay/wxpay/callback.go create mode 100644 business/partner/pay/wxpay/wxpay.go diff --git a/business/model/api_config.go b/business/model/api_config.go index f5d16debd..1eb9f795c 100644 --- a/business/model/api_config.go +++ b/business/model/api_config.go @@ -18,6 +18,8 @@ const ( VendorIDPurchaseEnd = 11 VendorIDJX = 9 // 这是一个假的京西VendorID + VendorIDWXPay = 51 // 微信支付 + VendorIDDeliveryBegin = 101 VendorIDDada = 101 VendorIDMTPS = 102 diff --git a/business/partner/pay/pay.go b/business/partner/pay/pay.go new file mode 100644 index 000000000..246d86afa --- /dev/null +++ b/business/partner/pay/pay.go @@ -0,0 +1,51 @@ +package pay + +import ( + "time" + + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" +) + +type PayOpStatus int + +const ( + OpStatusFailed PayOpStatus = 0 + OpStatusSuccessed PayOpStatus = 1 +) + +type CreatePayParam struct { + PayOrderID string + VendorPayType string + + VendorOrderID string + ProductDesc string + ProductDetail string + FeeType string + TotalFee int + TimeStart time.Time + TimeExpire time.Time + + UserData string +} + +type PayOpResult struct { + Status PayOpStatus + VendorStatus string + ErrMsg string + + ID string + VendorID string + + OriginalData string +} + +type ResponseHandler interface { + OnCreatePay(vendorID int, result *PayOpResult) (err error) + OnRefundPay(vendorID int, result *PayOpResult) (err error) +} + +type IPayPlatformHandler interface { + CreatePay(ctx *jxcontext.Context, param *CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error) + ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error) + RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error) +} diff --git a/business/partner/pay/wxpay/callback.go b/business/partner/pay/wxpay/callback.go new file mode 100644 index 000000000..e76447652 --- /dev/null +++ b/business/partner/pay/wxpay/callback.go @@ -0,0 +1,60 @@ +package wxpay + +import ( + "git.rosy.net.cn/baseapi/platformapi/wxpayapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner/pay" + "git.rosy.net.cn/jx-callback/globals" +) + +func OnCallback(msg *wxpayapi.CallbackMsg) (err error) { + globals.SugarLogger.Debugf("wxpay OnCallback msg:%s", utils.Format4Output(msg, true)) + switch msg.MsgType { + case wxpayapi.MsgTypePay: + err = onWxpayFinished(msg.Data.(*wxpayapi.PayResultMsg)) + case wxpayapi.MsgTypeRefund: + err = onWxpayRefund(msg.Data.(*wxpayapi.RefundResultMsg)) + } + return err +} + +func onWxpayFinished(msg *wxpayapi.PayResultMsg) (err error) { + opResult := &pay.PayOpResult{ + OriginalData: string(utils.MustMarshal(msg)), + } + if msg.ReturnCode == wxpayapi.ResponseCodeSuccess { + opResult.Status = pay.OpStatusSuccessed + opResult.ID = msg.OutTradeNo + if msg.ResultCode == wxpayapi.ResponseCodeSuccess { + opResult.VendorID = msg.TransactionID + } else { + opResult.VendorStatus = msg.ErrCode + opResult.ErrMsg = msg.ErrCodeDes + } + } else { + opResult.Status = pay.OpStatusFailed + } + err = payHandler.responseHandler.OnCreatePay(model.VendorIDWXPay, opResult) + return err +} + +func onWxpayRefund(msg *wxpayapi.RefundResultMsg) (err error) { + opResult := &pay.PayOpResult{ + OriginalData: string(utils.MustMarshal(msg)), + } + if msg.ReturnCode == wxpayapi.ResponseCodeSuccess { + opResult.Status = pay.OpStatusSuccessed + if msg.ResultCode == wxpayapi.ResponseCodeSuccess { + opResult.ID = msg.ReqInfoObj.OutRefundNo + opResult.VendorID = msg.ReqInfoObj.RefundID + } else { + opResult.VendorStatus = msg.ErrCode + opResult.ErrMsg = msg.ErrCodeDes + } + } else { + opResult.Status = pay.OpStatusFailed + } + err = payHandler.responseHandler.OnRefundPay(model.VendorIDWXPay, opResult) + return err +} diff --git a/business/partner/pay/wxpay/wxpay.go b/business/partner/pay/wxpay/wxpay.go new file mode 100644 index 000000000..ee161d7ed --- /dev/null +++ b/business/partner/pay/wxpay/wxpay.go @@ -0,0 +1,73 @@ +package wxpay + +import ( + "git.rosy.net.cn/baseapi/platformapi/wxpayapi" + "git.rosy.net.cn/jx-callback/business/auth2/authprovider/weixin" + "git.rosy.net.cn/jx-callback/business/jxutils/jxcontext" + "git.rosy.net.cn/jx-callback/business/partner/pay" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) + +type PayHandler struct { + responseHandler pay.ResponseHandler +} + +var ( + payHandler *PayHandler +) + +func New(responseHandler pay.ResponseHandler) (handler *PayHandler) { + return &PayHandler{ + responseHandler: responseHandler, + } +} + +func vendorPayType2WxpayType(vendorPayType string) string { + return vendorPayType +} + +func (p *PayHandler) CreatePay(ctx *jxcontext.Context, createParam *pay.CreatePayParam, isOffline bool) (prepayID, qrCodeURL string, err error) { + param := &wxpayapi.CreateOrderParam{ + OutTradeNo: createParam.PayOrderID, + Body: createParam.ProductDesc, + NotifyURL: globals.WxpayNotifyURL, + SpbillCreateIP: ctx.GetRealRemoteIP(), + TradeType: vendorPayType2WxpayType(createParam.VendorPayType), + TotalFee: createParam.TotalFee, + + TimeStart: wxpayapi.Time2PayTime(createParam.TimeStart), + TimeExpire: wxpayapi.Time2PayTime(createParam.TimeExpire), + } + if isOffline { + param.TradeType = wxpayapi.TradeTypeNative + } + if authInfo, err := ctx.GetV2AuthInfo(); err == nil && authInfo.GetAuthType() == weixin.AuthTypeMini { + param.OpenID = authInfo.GetAuthID() + } + if result, err := api.WxpayAPI.CreateUnifiedOrder(param); err == nil { + prepayID = result.PrepayID + qrCodeURL = result.CodeURL + } + return prepayID, qrCodeURL, err +} + +func (p *PayHandler) ClosePay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID string) (err error) { + return api.WxpayAPI.CloseOrder(payOrderID) +} + +func (p *PayHandler) RefundPay(ctx *jxcontext.Context, payOrderID, vendorPayOrderID, refundID, reason string, totalFee, refundFee int) (vendorRefundID string, err error) { + param := &wxpayapi.PayRefundParam{ + OutTradeNo: payOrderID, + NotifyURL: globals.WxpayNotifyURL, + OutRefundNo: refundID, + TotalFee: totalFee, + RefundFee: refundFee, + RefundDesc: wxpayapi.CData(reason), + } + retVal, err := api.WxpayAPI.PayRefund(param) + if err == nil { + vendorRefundID = retVal.RefundID + } + return vendorRefundID, err +} From 48b6de0a6f864d95358ee5007d29ea727843a8e5 Mon Sep 17 00:00:00 2001 From: gazebo Date: Fri, 20 Dec 2019 11:20:02 +0800 Subject: [PATCH 2/2] +setFakeActualPayPrice --- business/jxcallback/scheduler/defsch/defsch.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/business/jxcallback/scheduler/defsch/defsch.go b/business/jxcallback/scheduler/defsch/defsch.go index b9893143b..4f1c53477 100644 --- a/business/jxcallback/scheduler/defsch/defsch.go +++ b/business/jxcallback/scheduler/defsch/defsch.go @@ -1256,9 +1256,24 @@ func OnDefSchConfChanged(key, value string) { } } +func setFakeActualPayPrice(order *model.GoodsOrder) (newOrder *model.GoodsOrder) { + orderCopy := *order + storeDetail, err := dao.GetStoreDetail(dao.GetDB(), order.JxStoreID, order.VendorID) + if err == nil { + if storeDetail.PayPercentage < 50 { + orderCopy.ActualPayPrice = order.TotalShopMoney * (100 - int64(storeDetail.PayPercentage/2)) * 100 + } else { + orderCopy.ActualPayPrice = order.EarningPrice + } + } + newOrder = &orderCopy + return newOrder +} + func (s *DefScheduler) notifyNewOrder(order *model.GoodsOrder) { if order.Flag&model.OrderFlagMaskFake == 0 { utils.CallFuncAsync(func() { + order = setFakeActualPayPrice(order) netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order) weixinmsg.NotifyNewOrder(order) smsmsg.NotifyNewOrder(order) @@ -1268,6 +1283,7 @@ func (s *DefScheduler) notifyNewOrder(order *model.GoodsOrder) { func (s *DefScheduler) notifyUserApplyCancel(order *model.GoodsOrder, cancelReason string) { utils.CallFuncAsync(func() { + order = setFakeActualPayPrice(order) weixinmsg.NotifyUserApplyCancel(order, cancelReason) }) } @@ -1275,6 +1291,7 @@ func (s *DefScheduler) notifyUserApplyCancel(order *model.GoodsOrder, cancelReas func (s *DefScheduler) notifyOrderCanceled(order *model.GoodsOrder) { if order.Flag&model.OrderFlagMaskFake == 0 { utils.CallFuncAsync(func() { + order = setFakeActualPayPrice(order) weixinmsg.NotifyOrderCanceled(order) smsmsg.NotifyOrderCanceled(order) })