wechat_params.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package gopay
  2. import (
  3. "crypto/hmac"
  4. "crypto/md5"
  5. "crypto/sha256"
  6. "encoding/hex"
  7. "encoding/xml"
  8. "errors"
  9. "strings"
  10. )
  11. type Country int
  12. //设置支付国家(默认:中国国内)
  13. // 根据支付地区情况设置国家
  14. // country:<China:中国国内,China2:中国国内(冗灾方案),SoutheastAsia:东南亚,Other:其他国家>
  15. func (this *weChatClient) SetCountry(country Country) (client *weChatClient) {
  16. switch country {
  17. case China:
  18. this.baseURL = wx_base_url_ch
  19. case China2:
  20. this.baseURL = wx_base_url_ch2
  21. case SoutheastAsia:
  22. this.baseURL = wx_base_url_hk
  23. case Other:
  24. this.baseURL = wx_base_url_us
  25. default:
  26. this.baseURL = wx_base_url_ch
  27. }
  28. return this
  29. }
  30. //获取微信支付正式环境Sign值
  31. func getWeChatReleaseSign(apiKey string, signType string, bm BodyMap) (sign string) {
  32. signStr := bm.EncodeWeChatSignParams(apiKey)
  33. //fmt.Println("signStr:", signStr)
  34. var hashSign []byte
  35. if signType == SignType_HMAC_SHA256 {
  36. hash := hmac.New(sha256.New, []byte(apiKey))
  37. hash.Write([]byte(signStr))
  38. hashSign = hash.Sum(nil)
  39. } else {
  40. hash := md5.New()
  41. hash.Write([]byte(signStr))
  42. hashSign = hash.Sum(nil)
  43. }
  44. sign = strings.ToUpper(hex.EncodeToString(hashSign))
  45. return
  46. }
  47. //获取微信支付沙箱环境Sign值
  48. func getWeChatSignBoxSign(mchId, apiKey string, bm BodyMap) (sign string, err error) {
  49. //从微信接口获取SanBox的ApiKey
  50. sanBoxApiKey, err := getSanBoxKey(mchId, GetRandomString(32), apiKey, SignType_MD5)
  51. if err != nil {
  52. return null, err
  53. }
  54. signStr := bm.EncodeWeChatSignParams(sanBoxApiKey)
  55. //fmt.Println("signStr:", signStr)
  56. hash := md5.New()
  57. hash.Write([]byte(signStr))
  58. hashSign := hash.Sum(nil)
  59. sign = strings.ToUpper(hex.EncodeToString(hashSign))
  60. return sign, nil
  61. }
  62. //从微信提供的接口获取:SandboxSignKey
  63. func getSanBoxKey(mchId, nonceStr, apiKey, signType string) (key string, err error) {
  64. body := make(BodyMap)
  65. body.Set("mch_id", mchId)
  66. body.Set("nonce_str", nonceStr)
  67. //计算沙箱参数Sign
  68. sanboxSign := getWeChatReleaseSign(apiKey, signType, body)
  69. //沙箱环境:获取沙箱环境ApiKey
  70. key, err = getSanBoxSignKey(mchId, nonceStr, sanboxSign)
  71. if err != nil {
  72. return null, err
  73. }
  74. return
  75. }
  76. //从微信提供的接口获取:SandboxSignkey
  77. func getSanBoxSignKey(mchId, nonceStr, sign string) (key string, err error) {
  78. reqs := make(BodyMap)
  79. reqs.Set("mch_id", mchId)
  80. reqs.Set("nonce_str", nonceStr)
  81. reqs.Set("sign", sign)
  82. reqXml := generateXml(reqs)
  83. //fmt.Println("req:::", reqXml)
  84. _, byteList, errorList := HttpAgent().
  85. Post(wx_SanBox_GetSignKey).
  86. Type("xml").
  87. SendString(reqXml).EndBytes()
  88. if len(errorList) > 0 {
  89. return null, errorList[0]
  90. }
  91. keyResponse := new(getSignKeyResponse)
  92. err = xml.Unmarshal(byteList, keyResponse)
  93. if err != nil {
  94. return null, err
  95. }
  96. if keyResponse.ReturnCode == "FAIL" {
  97. return null, errors.New(keyResponse.ReturnMsg)
  98. }
  99. return keyResponse.SandboxSignkey, nil
  100. }
  101. //生成请求XML的Body体
  102. func generateXml(bm BodyMap) (reqXml string) {
  103. var buffer strings.Builder
  104. buffer.WriteString("<xml>")
  105. for key := range bm {
  106. buffer.WriteByte('<')
  107. buffer.WriteString(key)
  108. buffer.WriteString("><![CDATA[")
  109. buffer.WriteString(bm.Get(key))
  110. buffer.WriteString("]]></")
  111. buffer.WriteString(key)
  112. buffer.WriteByte('>')
  113. }
  114. buffer.WriteString("</xml>")
  115. reqXml = buffer.String()
  116. return
  117. }