微信支付支持退款

This commit is contained in:
gazebo
2019-11-21 09:36:37 +08:00
parent 12fda0dd48
commit 39c5845b2f
4 changed files with 164 additions and 38 deletions

View File

@@ -3,6 +3,7 @@ package wxpay
import (
"bytes"
"crypto/md5"
"crypto/tls"
"encoding/xml"
"fmt"
"net/http"
@@ -16,8 +17,8 @@ import (
)
const (
prodURL = "https://api.mch.weixin.qq.com/pay"
sandboxURL = "https://api.mch.weixin.qq.com/sandboxnew/pay"
prodURL = "https://api.mch.weixin.qq.com"
sandboxURL = "https://api.mch.weixin.qq.com/sandboxnew"
)
const (
@@ -169,6 +170,46 @@ type CreateOrderResult struct {
CodeURL string `json:"code_url"`
}
type PayRefundParam struct {
RequestBase
TransactionID string `json:"transaction_id,omitempty" xml:"transaction_id,omitempty"`
OutTradeNo string `json:"out_trade_no,omitempty" xml:"out_trade_no,omitempty"`
OutRefundNo string `json:"out_refund_no" xml:"out_refund_no"`
TotalFee int `json:"total_fee" xml:"total_fee"`
RefundFee int `json:"refund_fee" xml:"refund_fee"`
RefundFeeType string `json:"refund_fee_type,omitempty" xml:"refund_fee_type,omitempty"`
RefundDesc CData `json:"refund_desc,omitempty" xml:"refund_desc,omitempty"`
NotifyURL string `json:"notify_url,omitempty" xml:"notify_url,omitempty"`
}
type PayRefundResult struct {
ReturnCode string `json:"return_code" xml:"return_code"`
ReturnMsg string `json:"return_msg" xml:"return_msg"`
AppID string `json:"appid" xml:"appid"`
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
MchID string `json:"mch_id" xml:"mch_id"`
NonceStr string `json:"nonce_str" xml:"nonce_str"`
Sign string `json:"sign" xml:"sign"`
ResultCode string `json:"result_code" xml:"result_code"`
ErrCode string `json:"err_code,omitempty" xml:"err_code,omitempty"`
ErrCodeDes string `json:"err_code_des,omitempty" xml:"err_code_des,omitempty"`
CashFee string `json:"cash_fee"`
CashRefundFee string `json:"cash_refund_fee"`
CouponRefundCount string `json:"coupon_refund_count"`
CouponRefundFee string `json:"coupon_refund_fee"`
OutRefundNo string `json:"out_refund_no"`
OutTradeNo string `json:"out_trade_no"`
RefundChannel string `json:"refund_channel"`
RefundFee string `json:"refund_fee"`
RefundID string `json:"refund_id"`
TotalFee string `json:"total_fee"`
TransactionID string `json:"transaction_id"`
}
func New(appID, appKey, mchID string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
@@ -183,6 +224,19 @@ func New(appID, appKey, mchID string, config ...*platformapi.APIConfig) *API {
}
}
func NewWithCertificate(appID, appKey, mchID string, certPEMBlock, keyPEMBlock []byte, config ...*platformapi.APIConfig) (a *API) {
certs, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err == nil {
a = New(appID, appKey, mchID, config...)
a.client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{certs},
},
}
}
return a
}
func (a *API) GetAppID() string {
return a.appID
}
@@ -237,6 +291,12 @@ func (a *API) AccessAPI(action string, requestParam IRequestBase) (retVal map[st
retVal, errLevel, err = a.checkResultAsMap(jsonResult1[platformapi.KeyData].(string))
return errLevel, err
})
if err == nil {
if utils.Interface2String(retVal["result_code"]) != ResponseCodeSuccess {
err = utils.NewErrorCode(utils.Interface2String(retVal["err_code_des"]), utils.Interface2String(retVal["err_code"]))
retVal = nil
}
}
return retVal, err
}
@@ -251,13 +311,6 @@ func (a *API) checkResultAsMap(xmlStr string) (result map[string]interface{}, er
errLevel = platformapi.ErrLevelGeneralFail
err = utils.NewErrorCode(utils.Interface2String(result["return_msg"]), returnCode)
result = nil
} else {
// if utils.Interface2String(result["result_code"]) != ResponseCodeSuccess {
// errLevel = platformapi.ErrLevelGeneralFail
// err = utils.NewErrorCode(utils.Interface2String(result["err_code_desc"]), utils.Interface2String(result["err_code"]))
// result = nil
// } else {
// }
}
}
return result, errLevel, err
@@ -281,7 +334,7 @@ func (a *API) OrderQuery(transactionID, outTradeNo string) (orderInfo *OrderInfo
TransactionID: transactionID,
OutTradeNo: outTradeNo,
}
retVal, err := a.AccessAPI("orderquery", param)
retVal, err := a.AccessAPI("pay/orderquery", param)
if err == nil {
err = utils.Map2StructByJson(retVal, &orderInfo, false)
}
@@ -289,9 +342,20 @@ func (a *API) OrderQuery(transactionID, outTradeNo string) (orderInfo *OrderInfo
}
func (a *API) CreateUnifiedOrder(param *CreateOrderParam) (createOrderResult *CreateOrderResult, err error) {
retVal, err := a.AccessAPI("unifiedorder", param)
retVal, err := a.AccessAPI("pay/unifiedorder", param)
if err == nil {
err = utils.Map2StructByJson(retVal, &createOrderResult, false)
}
return createOrderResult, err
}
func (a *API) PayRefund(param *PayRefundParam) (refundResult *PayRefundResult, err error) {
if a.client.Transport == nil {
return nil, fmt.Errorf("没有配置证书,不能退款")
}
retVal, err := a.AccessAPI("secapi/pay/refund", param)
if err == nil {
err = utils.Map2StructByJson(retVal, &refundResult, false)
}
return refundResult, err
}