互动
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.

272 lines
6.6 KiB

5 years ago
  1. package wx
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "crypto/x509"
  6. "encoding/xml"
  7. "fmt"
  8. "io/ioutil"
  9. "net/http"
  10. )
  11. func SwitchHost(host string) {
  12. UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", host)
  13. QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", host)
  14. CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", host)
  15. RefundURL = fmt.Sprintf("%s/pay/refund", host)
  16. RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", host)
  17. TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", host)
  18. }
  19. type cdata string
  20. func (c cdata) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  21. return e.EncodeElement(struct {
  22. string `xml:",cdata"`
  23. }{string(c)}, start)
  24. }
  25. var _tlsConfig *tls.Config
  26. //var WxClient = NewClient()
  27. func getTLSConfig() (*tls.Config, error) {
  28. if _tlsConfig != nil {
  29. return _tlsConfig, nil
  30. }
  31. // load cert
  32. cert, err := tls.LoadX509KeyPair(WxCertPath, WxKeyPath)
  33. if err != nil {
  34. return nil, err
  35. }
  36. // load root ca
  37. caData, err := ioutil.ReadFile(WxCaPath)
  38. if err != nil {
  39. return nil, err
  40. }
  41. pool := x509.NewCertPool()
  42. pool.AppendCertsFromPEM(caData)
  43. _tlsConfig = &tls.Config{
  44. Certificates: []tls.Certificate{cert},
  45. RootCAs: pool,
  46. }
  47. return _tlsConfig, nil
  48. }
  49. type Client struct {
  50. AppId string
  51. MchId string
  52. secureClient *http.Client
  53. }
  54. //func NewClient() *Client {
  55. // tlsConfig, err := getTLSConfig()
  56. // if err != nil {
  57. // panic(err) // 出现错误
  58. // }
  59. // tr := &http.Transport{TLSClientConfig: tlsConfig}
  60. // client := &http.Client{Transport: tr}
  61. // return &Client{
  62. // AppId: Appid,
  63. // MchId: Mchid,
  64. // secureClient: client,
  65. // }
  66. //}
  67. func (w *Client) Post(url string, xmlRes []byte) (*http.Response, error) {
  68. return w.secureClient.Post(url, "application/xml", bytes.NewBuffer(xmlRes))
  69. }
  70. // ======= 支付回调
  71. func (w *Client) Callback() {
  72. }
  73. // ======= 统一下单
  74. func (w *Client) UnifiedOrder(param *UnifiedOrderParam) (*UnifiedOrderResult, error) {
  75. param.Appid = w.AppId
  76. param.MchId = w.MchId
  77. xmlParam, err := xml.MarshalIndent(param, "", "")
  78. if err != nil {
  79. return nil, err
  80. }
  81. resp, err := w.Post(UnifiedOrderURL, xmlParam)
  82. if err != nil {
  83. return nil, err
  84. }
  85. body, err := ioutil.ReadAll(resp.Body)
  86. if err != nil {
  87. return nil, err
  88. }
  89. res := new(UnifiedOrderResult)
  90. err = xml.Unmarshal(body, res)
  91. if err != nil {
  92. return nil, err
  93. }
  94. if res.ReturnCode != CODE_SUCCESS {
  95. return res, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  96. }
  97. if res.ResultCode != CODE_SUCCESS {
  98. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  99. }
  100. return res, nil
  101. }
  102. // ======= 查询订单
  103. func (w *Client) QueryOrder(param *QueryOrderParam) (*QueryOrderResult, error) {
  104. param.Appid = w.AppId
  105. param.MchId = w.MchId
  106. xmlParam, err := xml.MarshalIndent(param, "", "")
  107. if err != nil {
  108. return nil, err
  109. }
  110. resp, err := w.Post(QueryOrderURL, xmlParam)
  111. if err != nil {
  112. return nil, err
  113. }
  114. body, err := ioutil.ReadAll(resp.Body)
  115. if err != nil {
  116. return nil, err
  117. }
  118. res := new(QueryOrderResult)
  119. err = xml.Unmarshal(body, res)
  120. if err != nil {
  121. return nil, err
  122. }
  123. if res.ReturnCode != CODE_SUCCESS {
  124. return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  125. }
  126. if res.ResultCode != CODE_SUCCESS {
  127. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  128. }
  129. return res, nil
  130. }
  131. // ======= 关闭订单
  132. func (w *Client) CloseOrder(param *CloseOrderParam) (*CloseOrderResult, error) {
  133. param.Appid = w.AppId
  134. param.MchId = w.MchId
  135. xmlParam, err := xml.MarshalIndent(param, "", "")
  136. if err != nil {
  137. return nil, err
  138. }
  139. resp, err := w.Post(CloseOrderURL, xmlParam)
  140. if err != nil {
  141. return nil, err
  142. }
  143. body, err := ioutil.ReadAll(resp.Body)
  144. if err != nil {
  145. return nil, err
  146. }
  147. res := new(CloseOrderResult)
  148. err = xml.Unmarshal(body, res)
  149. if err != nil {
  150. return nil, err
  151. }
  152. if res.ReturnCode != CODE_SUCCESS {
  153. return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  154. }
  155. if res.ResultCode != CODE_SUCCESS {
  156. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  157. }
  158. return res, nil
  159. }
  160. // ======= 申请退款
  161. func (w *Client) Refund(param *RefundParam) (*RefundResult, error) {
  162. param.Appid = w.AppId
  163. param.MchId = w.MchId
  164. xmlParam, err := xml.MarshalIndent(param, "", "")
  165. if err != nil {
  166. return nil, err
  167. }
  168. resp, err := w.Post(RefundURL, xmlParam)
  169. if err != nil {
  170. return nil, err
  171. }
  172. body, err := ioutil.ReadAll(resp.Body)
  173. if err != nil {
  174. return nil, err
  175. }
  176. res := new(RefundResult)
  177. err = xml.Unmarshal(body, res)
  178. if err != nil {
  179. return nil, err
  180. }
  181. if res.ReturnCode != CODE_SUCCESS {
  182. return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  183. }
  184. if res.ResultCode != CODE_SUCCESS {
  185. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  186. }
  187. return nil, nil
  188. }
  189. // ======= 查询退款
  190. func (w *Client) RefundQuery(param *RefundQueryParam) (*RefundQueryResult, error) {
  191. param.Appid = w.AppId
  192. param.MchId = w.MchId
  193. xmlParam, err := xml.MarshalIndent(param, "", "")
  194. if err != nil {
  195. return nil, err
  196. }
  197. resp, err := w.Post(RefundQueryURL, xmlParam)
  198. if err != nil {
  199. return nil, err
  200. }
  201. body, err := ioutil.ReadAll(resp.Body)
  202. if err != nil {
  203. return nil, err
  204. }
  205. res := new(RefundQueryResult)
  206. err = xml.Unmarshal(body, res)
  207. if err != nil {
  208. return nil, err
  209. }
  210. if res.ReturnCode != CODE_SUCCESS {
  211. return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  212. }
  213. if res.ResultCode != CODE_SUCCESS {
  214. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  215. }
  216. return res, nil
  217. }
  218. // 支付结果通知
  219. // 支付给用户零钱
  220. // 公众号发送红包
  221. func (w *Client) SendRedPack(param *RedPackParam) (*RedPackResult, error) {
  222. param.Appid = w.AppId
  223. param.MchId = w.MchId
  224. xmlParam, err := xml.MarshalIndent(param, "", "")
  225. if err != nil {
  226. return nil, err
  227. }
  228. resp, err := w.Post(SendRedPackURL, xmlParam)
  229. if err != nil {
  230. return nil, err
  231. }
  232. body, err := ioutil.ReadAll(resp.Body)
  233. if err != nil {
  234. return nil, err
  235. }
  236. res := new(RedPackResult)
  237. err = xml.Unmarshal(body, res)
  238. if err != nil {
  239. return nil, err
  240. }
  241. if res.ReturnCode != CODE_SUCCESS {
  242. return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg)
  243. }
  244. if res.ResultCode != CODE_SUCCESS {
  245. return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes)
  246. }
  247. return res, nil
  248. }