Просмотр исходного кода

fix 去掉第三方http请求库

Jerry 6 лет назад
Родитель
Сommit
b8add786e4
12 измененных файлов с 429 добавлено и 286 удалено
  1. 13 16
      alipay_client.go
  2. 1 2
      alipay_params.go
  3. 7 9
      alipay_service_api.go
  4. 153 0
      body_map.go
  5. 0 9
      go.mod
  6. 0 26
      go.sum
  7. 188 0
      http_client.go
  8. 0 157
      util.go
  9. 24 29
      wechat_client.go
  10. 9 0
      wechat_client_test.go
  11. 6 13
      wechat_params.go
  12. 28 25
      wechat_service_api.go

+ 13 - 16
alipay_client.go

@@ -7,8 +7,6 @@ import (
 	"strings"
 	"sync"
 	"time"
-
-	"github.com/parnurzeal/gorequest"
 )
 
 type AliPayClient struct {
@@ -520,12 +518,10 @@ func (a *AliPayClient) AliPayUserCertifyOpenQuery(body BodyMap) (aliRsp *AliPayU
 }
 
 // 向支付宝发送请求
-func (a *AliPayClient) doAliPay(body BodyMap, method string) (bytes []byte, err error) {
+func (a *AliPayClient) doAliPay(body BodyMap, method string) (bs []byte, err error) {
 	var (
-		bodyStr, sign, url, urlParam string
-		bodyBs                       []byte
-		res                          gorequest.Response
-		errs                         []error
+		bodyStr, sign, url string
+		bodyBs             []byte
 	)
 	if body != nil {
 		if bodyBs, err = json.Marshal(body); err != nil {
@@ -590,31 +586,32 @@ func (a *AliPayClient) doAliPay(body BodyMap, method string) (bytes []byte, err
 		return
 	}
 	pubBody.Set("sign", sign)
-	urlParam = FormatAliPayURLParam(pubBody)
+	param := FormatAliPayURLParam(pubBody)
 	if method == "alipay.trade.app.pay" {
-		return []byte(urlParam), nil
+		return []byte(param), nil
 	}
 	if method == "alipay.user.certify.open.certify" {
 		if !a.IsProd {
-			return []byte(zfbSandboxBaseUrl + "?" + urlParam), nil
+			return []byte(zfbSandboxBaseUrl + "?" + param), nil
 		} else {
-			return []byte(zfbBaseUrl + "?" + urlParam), nil
+			return []byte(zfbBaseUrl + "?" + param), nil
 		}
 	}
 	if method == "alipay.trade.page.pay" {
 		if !a.IsProd {
-			return []byte(zfbSandboxBaseUrl + "?" + urlParam), nil
+			return []byte(zfbSandboxBaseUrl + "?" + param), nil
 		} else {
-			return []byte(zfbBaseUrl + "?" + urlParam), nil
+			return []byte(zfbBaseUrl + "?" + param), nil
 		}
 	}
-	agent := HttpAgent()
+	httpClient := NewHttpClient()
 	if !a.IsProd {
 		url = zfbSandboxBaseUrlUtf8
 	} else {
 		url = zfbBaseUrlUtf8
 	}
-	if res, bytes, errs = agent.Post(url).Type("form-data").SendString(urlParam).EndBytes(); len(errs) > 0 {
+	res, bs, errs := httpClient.Type(TypeForm).Post(url).SendString(param).EndBytes()
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
 	if res.StatusCode != 200 {
@@ -626,7 +623,7 @@ func (a *AliPayClient) doAliPay(body BodyMap, method string) (bytes []byte, err
 		}
 		return []byte(res.Request.URL.String()), nil
 	}
-	return
+	return bs, nil
 }
 
 func getSignData(bs []byte) (signData string) {

+ 1 - 2
alipay_params.go

@@ -202,6 +202,5 @@ func FormatAliPayURLParam(body BodyMap) (urlParam string) {
 	for key, value := range body {
 		v.Add(key, value.(string))
 	}
-	urlParam = v.Encode()
-	return
+	return v.Encode()
 }

+ 7 - 9
alipay_service_api.go

@@ -438,7 +438,7 @@ func AliPaySystemOauthToken(appId, privateKey, grantType, codeOrToken string) (r
 }
 
 // aliPaySystemOauthToken 向支付宝发送请求
-func aliPaySystemOauthToken(appId, privateKey string, body BodyMap, method string, isProd bool) (bytes []byte, err error) {
+func aliPaySystemOauthToken(appId, privateKey string, body BodyMap, method string, isProd bool) (bs []byte, err error) {
 	body.Set("app_id", appId)
 	body.Set("method", method)
 	body.Set("format", "JSON")
@@ -447,22 +447,20 @@ func aliPaySystemOauthToken(appId, privateKey string, body BodyMap, method strin
 	body.Set("timestamp", time.Now().Format(TimeLayout))
 	body.Set("version", "1.0")
 	var (
-		sign, url string
-		errs      []error
+		sign string
+		url  = zfbBaseUrlUtf8
 	)
 	pKey := FormatPrivateKey(privateKey)
 	if sign, err = getRsaSign(body, "RSA2", pKey); err != nil {
-		return
+		return nil, err
 	}
 	body.Set("sign", sign)
-	agent := HttpAgent()
 	if !isProd {
 		url = zfbSandboxBaseUrlUtf8
-	} else {
-		url = zfbBaseUrlUtf8
 	}
-	if _, bytes, errs = agent.Post(url).Type("form-data").SendString(FormatAliPayURLParam(body)).EndBytes(); len(errs) > 0 {
+	_, bs, errs := NewHttpClient().Type(TypeForm).Post(url).SendString(FormatAliPayURLParam(body)).EndBytes()
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return bs, nil
 }

+ 153 - 0
body_map.go

@@ -0,0 +1,153 @@
+package gopay
+
+import (
+	"encoding/json"
+	"encoding/xml"
+	"io"
+	"reflect"
+	"sort"
+	"strings"
+)
+
+type BodyMap map[string]interface{}
+
+// 设置参数
+func (bm BodyMap) Set(key string, value interface{}) {
+	bm[key] = value
+}
+
+// 获取参数
+func (bm BodyMap) Get(key string) string {
+	if bm == nil {
+		return null
+	}
+	var (
+		value interface{}
+		ok    bool
+		v     string
+	)
+	if value, ok = bm[key]; !ok {
+		return null
+	}
+	if v, ok = value.(string); ok {
+		return v
+	}
+	return convertToString(value)
+}
+
+func convertToString(v interface{}) (str string) {
+	if v == nil {
+		return null
+	}
+	var (
+		bs  []byte
+		err error
+	)
+	if bs, err = json.Marshal(v); err != nil {
+		return null
+	}
+	str = string(bs)
+	return
+}
+
+// 删除参数
+func (bm BodyMap) Remove(key string) {
+	delete(bm, key)
+}
+
+type xmlMapEntry struct {
+	XMLName xml.Name
+	Value   string `xml:",chardata"`
+}
+
+func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
+	if len(bm) == 0 {
+		return nil
+	}
+	var (
+		value string
+		vKind reflect.Kind
+	)
+	if err = e.EncodeToken(start); err != nil {
+		return
+	}
+	for k, v := range bm {
+		vKind = reflect.ValueOf(v).Kind()
+		switch vKind {
+		case reflect.String:
+			value = v.(string)
+		case reflect.Int:
+			value = Int2String(v.(int))
+		case reflect.Int64:
+			value = Int642String(v.(int64))
+		case reflect.Float32:
+			value = Float32ToString(v.(float32))
+		case reflect.Float64:
+			value = Float64ToString(v.(float64))
+		default:
+			value = ""
+		}
+		e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: value})
+	}
+	return e.EncodeToken(start.End())
+}
+
+func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
+	for {
+		var e xmlMapEntry
+		err = d.Decode(&e)
+		if err == io.EOF {
+			break
+		} else if err != nil {
+			return
+		}
+		bm.Set(e.XMLName.Local, e.Value)
+	}
+	return
+}
+
+// ("bar=baz&foo=quux") sorted by key.
+func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
+	var (
+		buf     strings.Builder
+		keyList []string
+	)
+	for k := range bm {
+		keyList = append(keyList, k)
+	}
+	sort.Strings(keyList)
+	for _, k := range keyList {
+		if v := bm.Get(k); v != null {
+			buf.WriteString(k)
+			buf.WriteByte('=')
+			buf.WriteString(v)
+			buf.WriteByte('&')
+		}
+	}
+	buf.WriteString("key")
+	buf.WriteByte('=')
+	buf.WriteString(apiKey)
+	return buf.String()
+}
+
+// ("bar=baz&foo=quux") sorted by key.
+func (bm BodyMap) EncodeAliPaySignParams() string {
+	var (
+		buf     strings.Builder
+		keyList []string
+	)
+	keyList = make([]string, 0, len(bm))
+	for k := range bm {
+		keyList = append(keyList, k)
+	}
+	sort.Strings(keyList)
+	for _, k := range keyList {
+		if v := bm.Get(k); v != null {
+			buf.WriteString(k)
+			buf.WriteByte('=')
+			buf.WriteString(v)
+			buf.WriteByte('&')
+		}
+	}
+	return buf.String()[:buf.Len()-1]
+}

+ 0 - 9
go.mod

@@ -1,12 +1,3 @@
 module github.com/iGoogle-ink/gopay
 
 go 1.13
-
-require (
-	github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 // indirect
-	github.com/parnurzeal/gorequest v0.2.16
-	github.com/pkg/errors v0.8.1 // indirect
-	github.com/smartystreets/goconvey v1.6.4 // indirect
-	golang.org/x/net v0.0.0-20191109021931-daa7c04131f5 // indirect
-	moul.io/http2curl v1.0.0 // indirect
-)

+ 0 - 26
go.sum

@@ -1,26 +0,0 @@
-github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8=
-github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
-github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
-github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
-github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
-github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20191109021931-daa7c04131f5 h1:bHNaocaoJxYBo5cw41UyTMLjYlb8wPY7+WFrnklbHOM=
-golang.org/x/net v0.0.0-20191109021931-daa7c04131f5/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
-moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=

+ 188 - 0
http_client.go

@@ -0,0 +1,188 @@
+package gopay
+
+import (
+	"crypto/tls"
+	"encoding/json"
+	"encoding/xml"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"strings"
+	"sync"
+)
+
+const (
+	POST           = "POST"
+	GET            = "GET"
+	TypeJSON       = "json"
+	TypeXML        = "xml"
+	TypeUrlencoded = "urlencoded"
+	TypeForm       = "form"
+	TypeFormData   = "form-data"
+	TypeHTML       = "html"
+	TypeText       = "text"
+	TypeMultipart  = "multipart"
+)
+
+var Types = map[string]string{
+	TypeJSON:       "application/json",
+	TypeXML:        "application/xml",
+	TypeForm:       "application/x-www-form-urlencoded",
+	TypeFormData:   "application/x-www-form-urlencoded",
+	TypeUrlencoded: "application/x-www-form-urlencoded",
+	TypeHTML:       "text/html",
+	TypeText:       "text/plain",
+	TypeMultipart:  "multipart/form-data",
+}
+
+type Client struct {
+	HttpClient    *http.Client
+	Transport     *http.Transport
+	Url           string
+	Method        string
+	ForceType     string
+	FormString    string
+	ContentType   string
+	UnmarshalType string
+	Types         map[string]string
+	JsonByte      []byte
+	Errors        []error
+	mu            sync.RWMutex
+}
+
+// NewHttpClient , default tls.Config{InsecureSkipVerify: true}
+func NewHttpClient() (client *Client) {
+	c := new(Client)
+	c.HttpClient = new(http.Client)
+	c.Transport = &http.Transport{}
+	c.Transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+	c.ForceType = TypeUrlencoded
+	c.UnmarshalType = TypeJSON
+	c.Errors = make([]error, 0)
+	return c
+}
+
+func (c *Client) SetTLSConfig(tlsCfg *tls.Config) (client *Client) {
+	c.mu.Lock()
+	c.Transport.TLSClientConfig = tlsCfg
+	c.mu.Unlock()
+	return c
+}
+
+func (c *Client) Post(url string) (client *Client) {
+	c.mu.Lock()
+	c.Method = POST
+	c.Url = url
+	c.mu.Unlock()
+	return c
+}
+
+func (c *Client) Type(typeStr string) (client *Client) {
+	if _, ok := Types[typeStr]; ok {
+		c.ForceType = typeStr
+	} else {
+		c.Errors = append(c.Errors, errors.New("Type func: incorrect type \""+typeStr+"\""))
+	}
+	return c
+}
+
+func (c *Client) Get(url string) (client *Client) {
+	c.mu.Lock()
+	c.Method = GET
+	c.Url = url
+	c.mu.Unlock()
+	return c
+}
+
+func (c *Client) SendStruct(v interface{}) (client *Client) {
+	bs, err := json.Marshal(v)
+	if err != nil {
+		c.Errors = append(c.Errors, err)
+		return c
+	}
+	c.JsonByte = bs
+	return c
+}
+
+func (c *Client) SendString(v string) (client *Client) {
+	c.mu.Lock()
+	c.FormString = v
+	c.mu.Unlock()
+	return c
+}
+
+func (c *Client) EndStruct(v interface{}) (res *http.Response, errs []error) {
+	res, bs, errs := c.EndBytes()
+	if errs != nil && len(errs) > 0 {
+		c.Errors = append(c.Errors, errs...)
+		return nil, c.Errors
+	}
+	switch c.UnmarshalType {
+	case TypeJSON:
+		err := json.Unmarshal(bs, &v)
+		if err != nil {
+			c.Errors = append(c.Errors, fmt.Errorf("json.Unmarshal:%s", err.Error()))
+			return nil, c.Errors
+		}
+		return res, nil
+	case TypeXML:
+		err := xml.Unmarshal(bs, &v)
+		if err != nil {
+			c.Errors = append(c.Errors, fmt.Errorf("xml.Unmarshal:%s", err.Error()))
+			return nil, c.Errors
+		}
+		return res, nil
+	default:
+		c.Errors = append(c.Errors, errors.New("UnmarshalType Type Wrong"))
+		return nil, c.Errors
+	}
+}
+func (c *Client) EndBytes() (res *http.Response, bs []byte, errs []error) {
+	if len(c.Errors) > 0 {
+		return nil, nil, c.Errors
+	}
+	var reader *strings.Reader
+	switch c.Method {
+	case GET:
+		reader = strings.NewReader(null)
+	case POST:
+		switch c.ForceType {
+		case TypeJSON:
+			if c.JsonByte != nil {
+				reader = strings.NewReader(string(c.JsonByte))
+			}
+			c.ContentType = Types[TypeJSON]
+		case TypeForm, TypeFormData, TypeUrlencoded:
+			reader = strings.NewReader(c.FormString)
+			c.ContentType = Types[TypeForm]
+		case TypeXML:
+			reader = strings.NewReader(c.FormString)
+			c.ContentType = Types[TypeXML]
+			c.UnmarshalType = TypeXML
+		default:
+			c.Errors = append(c.Errors, errors.New("Request type Error "))
+		}
+	default:
+		reader = strings.NewReader(null)
+	}
+	req, err := http.NewRequest(c.Method, c.Url, reader)
+	if err != nil {
+		c.Errors = append(c.Errors, err)
+		return nil, nil, c.Errors
+	}
+	req.Header.Set("Content-Type", c.ContentType)
+	c.HttpClient.Transport = c.Transport
+	res, err = c.HttpClient.Do(req)
+	if err != nil {
+		c.Errors = append(c.Errors, err)
+		return nil, nil, c.Errors
+	}
+	defer res.Body.Close()
+	bs, err = ioutil.ReadAll(res.Body)
+	if err != nil {
+		c.Errors = append(c.Errors, err)
+		return nil, nil, c.Errors
+	}
+	return res, bs, nil
+}

+ 0 - 157
util.go

@@ -1,168 +1,11 @@
 package gopay
 
 import (
-	"crypto/tls"
-	"encoding/json"
-	"encoding/xml"
-	"io"
 	"math/rand"
-	"reflect"
-	"sort"
 	"strconv"
-	"strings"
 	"time"
-
-	"github.com/parnurzeal/gorequest"
 )
 
-type BodyMap map[string]interface{}
-
-// 设置参数
-func (bm BodyMap) Set(key string, value interface{}) {
-	bm[key] = value
-}
-
-// 获取参数
-func (bm BodyMap) Get(key string) string {
-	if bm == nil {
-		return null
-	}
-	var (
-		value interface{}
-		ok    bool
-		v     string
-	)
-	if value, ok = bm[key]; !ok {
-		return null
-	}
-	if v, ok = value.(string); ok {
-		return v
-	}
-	return convertToString(value)
-}
-
-func convertToString(v interface{}) (str string) {
-	if v == nil {
-		return null
-	}
-	var (
-		bs  []byte
-		err error
-	)
-	if bs, err = json.Marshal(v); err != nil {
-		return null
-	}
-	str = string(bs)
-	return
-}
-
-// 删除参数
-func (bm BodyMap) Remove(key string) {
-	delete(bm, key)
-}
-
-type xmlMapEntry struct {
-	XMLName xml.Name
-	Value   string `xml:",chardata"`
-}
-
-func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
-	if len(bm) == 0 {
-		return nil
-	}
-	var (
-		value string
-		vKind reflect.Kind
-	)
-	if err = e.EncodeToken(start); err != nil {
-		return
-	}
-	for k, v := range bm {
-		vKind = reflect.ValueOf(v).Kind()
-		switch vKind {
-		case reflect.String:
-			value = v.(string)
-		case reflect.Int:
-			value = Int2String(v.(int))
-		case reflect.Int64:
-			value = Int642String(v.(int64))
-		case reflect.Float32:
-			value = Float32ToString(v.(float32))
-		case reflect.Float64:
-			value = Float64ToString(v.(float64))
-		default:
-			value = ""
-		}
-		e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: value})
-	}
-	return e.EncodeToken(start.End())
-}
-
-func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
-	for {
-		var e xmlMapEntry
-		err = d.Decode(&e)
-		if err == io.EOF {
-			break
-		} else if err != nil {
-			return
-		}
-		bm.Set(e.XMLName.Local, e.Value)
-	}
-	return
-}
-
-// ("bar=baz&foo=quux") sorted by key.
-func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
-	var (
-		buf     strings.Builder
-		keyList []string
-	)
-	for k := range bm {
-		keyList = append(keyList, k)
-	}
-	sort.Strings(keyList)
-	for _, k := range keyList {
-		if v := bm.Get(k); v != null {
-			buf.WriteString(k)
-			buf.WriteByte('=')
-			buf.WriteString(v)
-			buf.WriteByte('&')
-		}
-	}
-	buf.WriteString("key")
-	buf.WriteByte('=')
-	buf.WriteString(apiKey)
-	return buf.String()
-}
-
-// ("bar=baz&foo=quux") sorted by key.
-func (bm BodyMap) EncodeAliPaySignParams() string {
-	var (
-		buf     strings.Builder
-		keyList []string
-	)
-	keyList = make([]string, 0, len(bm))
-	for k := range bm {
-		keyList = append(keyList, k)
-	}
-	sort.Strings(keyList)
-	for _, k := range keyList {
-		if v := bm.Get(k); v != null {
-			buf.WriteString(k)
-			buf.WriteByte('=')
-			buf.WriteString(v)
-			buf.WriteByte('&')
-		}
-	}
-	return buf.String()[:buf.Len()-1]
-}
-
-// HttpAgent
-func HttpAgent() (agent *gorequest.SuperAgent) {
-	return gorequest.New().TLSClientConfig(&tls.Config{InsecureSkipVerify: true})
-}
-
 // 获取随机字符串
 //    length:字符串长度
 func GetRandomString(length int) string {

+ 24 - 29
wechat_client.go

@@ -7,8 +7,6 @@ import (
 	"fmt"
 	"strings"
 	"sync"
-
-	"github.com/parnurzeal/gorequest"
 )
 
 type WeChatClient struct {
@@ -257,33 +255,29 @@ func (w *WeChatClient) Transfer(body BodyMap, certFilePath, keyFilePath, pkcs12F
 	body.Set("mch_appid", w.AppId)
 	body.Set("mchid", w.MchId)
 	var (
-		bs        []byte
 		tlsConfig *tls.Config
-		agent     *gorequest.SuperAgent
-		errs      []error
-		res       gorequest.Response
+		url       = wxBaseUrlCh + wxTransfers
 	)
 	if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil {
 		return nil, err
 	}
 	body.Set("sign", getWeChatReleaseSign(w.ApiKey, SignType_MD5, body))
-	agent = HttpAgent().TLSClientConfig(tlsConfig)
+
+	httpClient := NewHttpClient().SetTLSConfig(tlsConfig).Type(TypeXML)
 	if w.BaseURL != null {
-		agent.Post(w.BaseURL + wxTransfers)
-	} else {
-		agent.Post(wxBaseUrlCh + wxTransfers)
+		w.mu.RLock()
+		url = w.BaseURL + wxTransfers
+		w.mu.RUnlock()
 	}
-	if res, bs, errs = agent.Type("xml").SendString(generateXml(body)).EndBytes(); len(errs) > 0 {
+	wxRsp = new(WeChatTransfersResponse)
+	res, errs := httpClient.Post(url).SendString(generateXml(body)).EndStruct(wxRsp)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
 	if res.StatusCode != 200 {
 		return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
 	}
-	wxRsp = new(WeChatTransfersResponse)
-	if err = xml.Unmarshal(bs, wxRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
-	}
-	return
+	return wxRsp, nil
 }
 
 // 公众号纯签约(未完成)
@@ -295,13 +289,12 @@ func (w *WeChatClient) EntrustPublic(body BodyMap) (bs []byte, err error) {
 }
 
 // 向微信发送请求
-func (w *WeChatClient) doWeChat(body BodyMap, path string, tlsConfig ...*tls.Config) (bytes []byte, err error) {
+func (w *WeChatClient) doWeChat(body BodyMap, path string, tlsConfig ...*tls.Config) (bs []byte, err error) {
 	body.Set("appid", w.AppId)
 	body.Set("mch_id", w.MchId)
 	var (
 		sign string
-		errs []error
-		res  gorequest.Response
+		url  = wxBaseUrlCh + path
 	)
 	if body.Get("sign") != null {
 		goto GoRequest
@@ -309,32 +302,34 @@ func (w *WeChatClient) doWeChat(body BodyMap, path string, tlsConfig ...*tls.Con
 	if !w.IsProd {
 		body.Set("sign_type", SignType_MD5)
 		if sign, err = getWeChatSignBoxSign(w.MchId, w.ApiKey, body); err != nil {
-			return
+			return nil, err
 		}
 	} else {
 		sign = getWeChatReleaseSign(w.ApiKey, body.Get("sign_type"), body)
 	}
 	body.Set("sign", sign)
+
 GoRequest:
-	agent := HttpAgent()
+	httpClient := NewHttpClient()
 	if w.IsProd && tlsConfig != nil {
-		agent.TLSClientConfig(tlsConfig[0])
+		httpClient.SetTLSConfig(tlsConfig[0])
 	}
+
 	if w.BaseURL != null {
 		w.mu.RLock()
-		agent.Post(w.BaseURL + path)
+		url = w.BaseURL + path
 		w.mu.RUnlock()
-	} else {
-		agent.Post(wxBaseUrlCh + path)
 	}
-	if res, bytes, errs = agent.Type("xml").SendString(generateXml(body)).EndBytes(); len(errs) > 0 {
+
+	res, bs, errs := httpClient.Type(TypeXML).Post(url).SendString(generateXml(body)).EndBytes()
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
 	if res.StatusCode != 200 {
 		return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
 	}
-	if strings.Contains(string(bytes), "HTML") {
-		return nil, errors.New(string(bytes))
+	if strings.Contains(string(bs), "HTML") {
+		return nil, errors.New(string(bs))
 	}
-	return
+	return bs, nil
 }

+ 9 - 0
wechat_client_test.go

@@ -160,3 +160,12 @@ func TestBodyMap_Set_Get(t *testing.T) {
 	fmt.Println("Get2:", bm.Get("student"))
 
 }
+
+func TestGetWeChatAppletAccessToken(t *testing.T) {
+	token, err := GetWeChatAppletAccessToken("wxdaa2ab9ef87b5497", "AppSecret")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+	fmt.Println("token:", token)
+}

+ 6 - 13
wechat_params.go

@@ -7,7 +7,6 @@ import (
 	"crypto/tls"
 	"crypto/x509"
 	"encoding/hex"
-	"encoding/xml"
 	"errors"
 	"fmt"
 	"hash"
@@ -150,23 +149,17 @@ func getSanBoxKey(mchId, nonceStr, apiKey, signType string) (key string, err err
 	return
 }
 
-// 从微信提供的接口获取:SandboxSignkey
+// 从微信提供的接口获取:SandboxSignKey
 func getSanBoxSignKey(mchId, nonceStr, sign string) (key string, err error) {
 	reqs := make(BodyMap)
 	reqs.Set("mch_id", mchId)
 	reqs.Set("nonce_str", nonceStr)
 	reqs.Set("sign", sign)
-	var (
-		byteList    []byte
-		errorList   []error
-		keyResponse *getSignKeyResponse
-	)
-	if _, byteList, errorList = HttpAgent().Post(wxSandboxGetsignkey).Type("xml").SendString(generateXml(reqs)).EndBytes(); len(errorList) > 0 {
-		return null, errorList[0]
-	}
-	keyResponse = new(getSignKeyResponse)
-	if err = xml.Unmarshal(byteList, keyResponse); err != nil {
-		return
+
+	keyResponse := new(getSignKeyResponse)
+	_, errs := NewHttpClient().Type(TypeXML).Post(wxSandboxGetsignkey).SendString(generateXml(reqs)).EndStruct(keyResponse)
+	if len(errs) > 0 {
+		return null, errs[0]
 	}
 	if keyResponse.ReturnCode == "FAIL" {
 		return null, errors.New(keyResponse.ReturnMsg)

+ 28 - 25
wechat_service_api.go

@@ -394,10 +394,12 @@ func DecryptWeChatOpenDataToBodyMap(encryptedData, iv, sessionKey string) (bm Bo
 func GetAppWeChatLoginAccessToken(appId, appSecret, code string) (accessToken *AppWeChatLoginAccessToken, err error) {
 	accessToken = new(AppWeChatLoginAccessToken)
 	url := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code"
-	if _, _, errs := HttpAgent().Get(url).EndStruct(accessToken); len(errs) > 0 {
+
+	_, errs := NewHttpClient().Get(url).EndStruct(accessToken)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return accessToken, nil
 }
 
 // 刷新App应用微信第三方登录后,获取的 access_token
@@ -407,10 +409,12 @@ func GetAppWeChatLoginAccessToken(appId, appSecret, code string) (accessToken *A
 func RefreshAppWeChatLoginAccessToken(appId, refreshToken string) (accessToken *RefreshAppWeChatLoginAccessTokenRsp, err error) {
 	accessToken = new(RefreshAppWeChatLoginAccessTokenRsp)
 	url := "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" + appId + "&grant_type=refresh_token&refresh_token=" + refreshToken
-	if _, _, errs := HttpAgent().Get(url).EndStruct(accessToken); len(errs) > 0 {
+
+	_, errs := NewHttpClient().Get(url).EndStruct(accessToken)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return accessToken, nil
 }
 
 // 获取微信小程序用户的OpenId、SessionKey、UnionId
@@ -421,10 +425,11 @@ func RefreshAppWeChatLoginAccessToken(appId, refreshToken string) (accessToken *
 func Code2Session(appId, appSecret, wxCode string) (sessionRsp *Code2SessionRsp, err error) {
 	sessionRsp = new(Code2SessionRsp)
 	url := "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + wxCode + "&grant_type=authorization_code"
-	if _, _, errs := HttpAgent().Get(url).EndStruct(sessionRsp); len(errs) > 0 {
+	_, errs := NewHttpClient().Get(url).EndStruct(sessionRsp)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return sessionRsp, nil
 }
 
 // 获取微信小程序全局唯一后台接口调用凭据(AccessToken:157字符)
@@ -434,10 +439,11 @@ func Code2Session(appId, appSecret, wxCode string) (sessionRsp *Code2SessionRsp,
 func GetWeChatAppletAccessToken(appId, appSecret string) (accessToken *AccessToken, err error) {
 	accessToken = new(AccessToken)
 	url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret
-	if _, _, errs := HttpAgent().Get(url).EndStruct(accessToken); len(errs) > 0 {
+	_, errs := NewHttpClient().Get(url).EndStruct(accessToken)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return accessToken, nil
 }
 
 // 授权码查询openid(AccessToken:157字符)
@@ -449,10 +455,8 @@ func GetWeChatAppletAccessToken(appId, appSecret string) (accessToken *AccessTok
 //    文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
 func GetOpenIdByAuthCode(appId, mchId, apiKey, authCode, nonceStr string) (openIdRsp *OpenIdByAuthCodeRsp, err error) {
 	var (
-		url  string
-		bm   BodyMap
-		bs   []byte
-		errs []error
+		url string
+		bm  BodyMap
 	)
 	url = "https://api.mch.weixin.qq.com/tools/authcodetoopenid"
 	bm = make(BodyMap)
@@ -461,14 +465,13 @@ func GetOpenIdByAuthCode(appId, mchId, apiKey, authCode, nonceStr string) (openI
 	bm.Set("auth_code", authCode)
 	bm.Set("nonce_str", nonceStr)
 	bm.Set("sign", getWeChatReleaseSign(apiKey, SignType_MD5, bm))
-	if _, bs, errs = HttpAgent().Post(url).Type("xml").SendString(generateXml(bm)).EndBytes(); len(errs) > 0 {
-		return nil, errs[0]
-	}
+
 	openIdRsp = new(OpenIdByAuthCodeRsp)
-	if err = xml.Unmarshal(bs, openIdRsp); err != nil {
-		return nil, fmt.Errorf("xml.Unmarshal:%s", err.Error())
+	_, errs := NewHttpClient().Type(TypeXML).Post(url).SendString(generateXml(bm)).EndStruct(openIdRsp)
+	if len(errs) > 0 {
+		return nil, errs[0]
 	}
-	return
+	return openIdRsp, nil
 }
 
 // 微信小程序用户支付完成后,获取该用户的 UnionId,无需用户授权。
@@ -479,10 +482,11 @@ func GetOpenIdByAuthCode(appId, mchId, apiKey, authCode, nonceStr string) (openI
 func GetWeChatAppletPaidUnionId(accessToken, openId, transactionId string) (unionId *PaidUnionId, err error) {
 	unionId = new(PaidUnionId)
 	url := "https://api.weixin.qq.com/wxa/getpaidunionid?access_token=" + accessToken + "&openid=" + openId + "&transaction_id=" + transactionId
-	if _, _, errs := HttpAgent().Get(url).EndStruct(unionId); len(errs) > 0 {
+	_, errs := NewHttpClient().Get(url).EndStruct(unionId)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return unionId, nil
 }
 
 // 获取用户基本信息(UnionID机制)
@@ -492,14 +496,13 @@ func GetWeChatAppletPaidUnionId(accessToken, openId, transactionId string) (unio
 //    获取用户基本信息(UnionID机制)文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839
 func GetWeChatUserInfo(accessToken, openId string, lang ...string) (userInfo *WeChatUserInfo, err error) {
 	userInfo = new(WeChatUserInfo)
-	var url string
+	url := "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN"
 	if len(lang) > 0 {
 		url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=" + lang[0]
-	} else {
-		url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN"
 	}
-	if _, _, errs := HttpAgent().Get(url).EndStruct(userInfo); len(errs) > 0 {
+	_, errs := NewHttpClient().Get(url).EndStruct(userInfo)
+	if len(errs) > 0 {
 		return nil, errs[0]
 	}
-	return
+	return userInfo, nil
 }