wxpay partner
This commit is contained in:
@@ -18,6 +18,8 @@ const (
|
|||||||
VendorIDPurchaseEnd = 11
|
VendorIDPurchaseEnd = 11
|
||||||
VendorIDJX = 9 // 这是一个假的京西VendorID
|
VendorIDJX = 9 // 这是一个假的京西VendorID
|
||||||
|
|
||||||
|
VendorIDWXPay = 51 // 微信支付
|
||||||
|
|
||||||
VendorIDDeliveryBegin = 101
|
VendorIDDeliveryBegin = 101
|
||||||
VendorIDDada = 101
|
VendorIDDada = 101
|
||||||
VendorIDMTPS = 102
|
VendorIDMTPS = 102
|
||||||
|
|||||||
51
business/partner/pay/pay.go
Normal file
51
business/partner/pay/pay.go
Normal 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)
|
||||||
|
}
|
||||||
60
business/partner/pay/wxpay/callback.go
Normal file
60
business/partner/pay/wxpay/callback.go
Normal 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
|
||||||
|
}
|
||||||
73
business/partner/pay/wxpay/wxpay.go
Normal file
73
business/partner/pay/wxpay/wxpay.go
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user