You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
6.1 KiB
249 lines
6.1 KiB
package wx
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"hudongzhuanjia/utils/define"
|
|
"io/ioutil"
|
|
"net/http"
|
|
)
|
|
|
|
type cdata string
|
|
|
|
func (c cdata) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|
return e.EncodeElement(struct {
|
|
string `xml:",cdata"`
|
|
}{string(c)}, start)
|
|
}
|
|
|
|
var _tlsConfig *tls.Config
|
|
|
|
//var WxClient = NewClient()
|
|
|
|
//func getTLSConfig() (*tls.Config, error) {
|
|
// if _tlsConfig != nil {
|
|
// return _tlsConfig, nil
|
|
// }
|
|
// // load cert
|
|
// cert, err := tls.LoadX509KeyPair(WxCertPath, WxKeyPath)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// // load root ca
|
|
// caData, err := ioutil.ReadFile(WxCaPath)
|
|
// if err != nil {
|
|
// return nil, err
|
|
// }
|
|
// pool := x509.NewCertPool()
|
|
// pool.AppendCertsFromPEM(caData)
|
|
// _tlsConfig = &tls.Config{
|
|
// Certificates: []tls.Certificate{cert},
|
|
// RootCAs: pool,
|
|
// }
|
|
// return _tlsConfig, nil
|
|
//}
|
|
|
|
type Client struct {
|
|
AppId string
|
|
MchId string
|
|
secureClient *http.Client
|
|
}
|
|
|
|
func (w *Client) Post(url string, xmlRes []byte) (*http.Response, error) {
|
|
return w.secureClient.Post(url, "application/xml", bytes.NewBuffer(xmlRes))
|
|
}
|
|
|
|
// ======= 支付回调
|
|
func (w *Client) Callback() {
|
|
|
|
}
|
|
|
|
// ======= 统一下单
|
|
func (w *Client) UnifiedOrder(param *UnifiedOrderParam) (*UnifiedOrderResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(UnifiedOrderURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(UnifiedOrderResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// ======= 查询订单
|
|
func (w *Client) QueryOrder(param *QueryOrderParam) (*QueryOrderResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(QueryOrderURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(QueryOrderResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// ======= 关闭订单
|
|
func (w *Client) CloseOrder(param *CloseOrderParam) (*CloseOrderResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(CloseOrderURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(CloseOrderResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// ======= 申请退款
|
|
func (w *Client) Refund(param *RefundParam) (*RefundResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(RefundURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(RefundResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
// ======= 查询退款
|
|
func (w *Client) RefundQuery(param *RefundQueryParam) (*RefundQueryResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(RefundQueryURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(RefundQueryResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
return res, nil
|
|
|
|
}
|
|
|
|
// 支付结果通知
|
|
// 支付给用户零钱
|
|
|
|
// 公众号发送红包
|
|
func (w *Client) SendRedPack(param *RedPackParam) (*RedPackResult, error) {
|
|
param.Appid = w.AppId
|
|
param.MchId = w.MchId
|
|
xmlParam, err := xml.MarshalIndent(param, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp, err := w.Post(SendRedPackURL, xmlParam)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res := new(RedPackResult)
|
|
err = xml.Unmarshal(body, res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if res.ReturnCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
|
|
}
|
|
if res.ResultCode != define.CODE_SUCCESS {
|
|
return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
|
|
}
|
|
return res, nil
|
|
}
|