wxpay partner

This commit is contained in:
gazebo
2019-12-20 11:19:47 +08:00
parent 4c698967d0
commit 163b27ca6e
4 changed files with 186 additions and 0 deletions

View File

@@ -18,6 +18,8 @@ const (
VendorIDPurchaseEnd = 11
VendorIDJX = 9 // 这是一个假的京西VendorID
VendorIDWXPay = 51 // 微信支付
VendorIDDeliveryBegin = 101
VendorIDDada = 101
VendorIDMTPS = 102

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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
}