wx.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package wx
  2. import (
  3. "errors"
  4. "fmt"
  5. "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
  6. "git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
  7. "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
  8. "github.com/silenceper/wechat/js"
  9. "github.com/silenceper/wechat/oauth"
  10. "github.com/silenceper/wechat/pay"
  11. "github.com/silenceper/wechat/util"
  12. "io/ioutil"
  13. "net/url"
  14. "strconv"
  15. "strings"
  16. )
  17. var wxPayCallbackHandler func(result *pay.NotifyResult)models.SysReturn = nil
  18. // 注册微信支付回调处理函数
  19. func RegisterWxPayCallbackHandler(handler func(result *pay.NotifyResult)models.SysReturn){
  20. wxPayCallbackHandler = handler
  21. }
  22. func CallWxPayCallbackHandler(c *entitys.CtrlContext)models.SysReturn{
  23. if wxPayCallbackHandler == nil{
  24. return models.SysReturn{500, "微信支付回调处理函数为空", nil}
  25. }
  26. notifyRet := pay.NotifyResult{}
  27. err := c.Ctx.BindXML(&notifyRet)
  28. if err != nil{
  29. fmt.Println("******************----》微信支付回调bindxml错误", err.Error())
  30. return models.SysReturn{500, err.Error(), nil}
  31. }
  32. if notifyRet.ResultCode == "SUCCESS" && notifyRet.ReturnCode == "SUCCESS"{
  33. var data, _ = ioutil.ReadAll(c.Ctx.Request.Body)
  34. ok, err := VerifyResponseData(data, wxConfig.PayKey)
  35. if err != nil{
  36. fmt.Println("*****************---->微信支付回调验证错误", err.Error())
  37. return models.SysReturn{500, err.Error(), nil}
  38. }
  39. if !ok{
  40. fmt.Println("*****************---->微信支付回调验证错误, ok is false")
  41. return models.SysReturn{500, "", nil}
  42. }
  43. return wxPayCallbackHandler(&notifyRet)
  44. }else{
  45. fmt.Println("------------------>微信支付失败", notifyRet)
  46. return models.SysReturn{500, "", ""}
  47. }
  48. }
  49. // 扫码支付
  50. func PayNative(params *PayParams)(*pay.PayResult, error){
  51. ip := utils.GetIP(params.Ctx)
  52. attach := params.Attach
  53. if attach == ""{
  54. attach = params.Ctx.Ctx.GetString("user_id")
  55. if attach == ""{
  56. attach = "attach"
  57. }
  58. }
  59. body := params.Body
  60. if body == ""{
  61. body = "body"
  62. }
  63. if params.OutTradeNo == ""{
  64. return nil, errors.New("交易单号为空")
  65. }
  66. parParams := pay.Params{strconv.Itoa(params.TotalFee), ip, body, attach, params.OutTradeNo, ""}
  67. return wc.GetPay().PreNative(&parParams)
  68. }
  69. // jsapi 支付
  70. func PayJSAPI(params *PayParams)(*JSAPIPayConfig, error){
  71. openId := params.OpenId
  72. if openId == ""{
  73. return nil, errors.New("openid 为空")
  74. }
  75. if params.OutTradeNo == ""{
  76. return nil, errors.New("交易单号为空")
  77. }
  78. attach := params.Attach
  79. if attach == ""{
  80. fmt.Println("--------------------->1")
  81. attach = params.Ctx.Ctx.GetString("user_id")
  82. if attach == ""{
  83. fmt.Println("--------------------->2")
  84. attach = "attach"
  85. }
  86. }
  87. body := params.Body
  88. if body == ""{
  89. body = "body"
  90. }
  91. ip := utils.GetIP(params.Ctx)
  92. fmt.Println("params.Attach", params.Attach, "attach", attach)
  93. payParams := pay.Params{
  94. strconv.Itoa(params.TotalFee),
  95. ip,
  96. body,
  97. attach,
  98. params.OutTradeNo,
  99. params.OpenId,
  100. }
  101. payObj := wc.GetPay()
  102. prePayID, err := payObj.PrePayID(&payParams)
  103. if err != nil{
  104. fmt.Println("----------------->prepayid error", err.Error())
  105. return nil, err
  106. }
  107. nonceStr := util.RandomStr(32)
  108. timestamp := util.GetCurrTs()
  109. pack := "prepay_id=" + prePayID
  110. template := "appId=%s&nonceStr=%s&package=%s&signType=MD5&timeStamp=%s&key=%s"
  111. str := fmt.Sprintf(template, payObj.AppID, nonceStr, pack, strconv.FormatInt(timestamp, 10), payObj.PayKey)
  112. sign := util.MD5Sum(str)
  113. payCfg := pay.Config{timestamp, nonceStr, prePayID, "MD5", sign}
  114. exPayConfig := JSAPIPayConfig{}
  115. exPayConfig.AppId = wxConfig.AppId
  116. exPayConfig.NonceStr = payCfg.NonceStr
  117. exPayConfig.OutTradeNo = params.OutTradeNo
  118. exPayConfig.Package = "prepay_id=" + payCfg.PrePayID
  119. exPayConfig.PaySign = payCfg.Sign
  120. exPayConfig.SignType = payCfg.SignType
  121. exPayConfig.Timestamp = strconv.Itoa(int(payCfg.Timestamp))
  122. if err==nil {
  123. return &exPayConfig, nil
  124. }else{
  125. return nil, err
  126. }
  127. }
  128. // 获取微信OAuth认证参数
  129. func GetOAuthParams(paramMap map[string]string)(*WxOAuthConfig, error){
  130. config := WxOAuthConfig{}
  131. urlstr := wxConfig.RedirectUrl
  132. paramstr := ""
  133. for k, v := range paramMap{
  134. paramstr += fmt.Sprintf("%s=%s", k, url.QueryEscape(v))
  135. }
  136. if strings.Index(urlstr, "%s") > 0{
  137. urlstr = fmt.Sprintf(urlstr, paramstr)
  138. }
  139. url, err := wxoauth.GetRedirectURL(urlstr, wxConfig.Scope, url.QueryEscape(wxConfig.State))
  140. if err != nil{
  141. return nil, err
  142. }
  143. config.OAuthRedirectUrl = url
  144. config.AppId = wxConfig.AppId
  145. config.State = wxConfig.State
  146. config.Scope = wxConfig.Scope
  147. config.ResponseType = wxConfig.ResponseType
  148. config.AuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
  149. config.RedirectUrl = wxConfig.RedirectUrl
  150. return &config, nil
  151. }
  152. // 获取jssdk配置参数
  153. func GetJSSDKRarams(url string)(*js.Config, error){
  154. return wc.GetJs().GetConfig(url)
  155. }
  156. // 获取token
  157. func GetOpenId(code string)(string, error){
  158. resToken, err := wxoauth.GetUserAccessToken(code)
  159. if err == nil{
  160. addToken(resToken.OpenID, &resToken)
  161. }
  162. return resToken.OpenID, err
  163. }
  164. // 根据code获取用户信息(需scope为 snsapi_userinfo)
  165. func GetUserInfoByCode(code string)(*oauth.UserInfo, error){
  166. openId, err := GetOpenId(code)
  167. if err != nil{
  168. return nil, err
  169. }
  170. return GetUserInfo(openId)
  171. }
  172. // 获取用户信息(需scope为 snsapi_userinfo)
  173. func GetUserInfo(openId string)(*oauth.UserInfo, error){
  174. token := getToken(openId)
  175. if token == nil{
  176. return nil, errors.New("token of openid " + openId + "does not exist")
  177. }
  178. userInfo, err := wxoauth.GetUserInfo(token.AccessToken, openId)
  179. return &userInfo, err
  180. }