wx.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. "strconv"
  13. )
  14. var wxPayCallbackHandler func(result *pay.NotifyResult)models.SysReturn = nil
  15. // 注册微信支付回调处理函数
  16. func RegisterWxPayCallbackHandler(handler func(result *pay.NotifyResult)models.SysReturn){
  17. wxPayCallbackHandler = handler
  18. }
  19. func CallWxPayCallbackHandler(c *entitys.CtrlContext)models.SysReturn{
  20. if wxPayCallbackHandler == nil{
  21. return models.SysReturn{500, "微信支付回调处理函数为空", nil}
  22. }
  23. notifyRet := pay.NotifyResult{}
  24. err := c.Ctx.BindXML(&notifyRet)
  25. if err != nil{
  26. fmt.Println("******************----》微信支付回调bindxml错误", err.Error())
  27. return models.SysReturn{500, err.Error(), nil}
  28. }
  29. return wxPayCallbackHandler(&notifyRet)
  30. }
  31. // 扫码支付
  32. func PayNative(params *PayParams)(*pay.PayResult, error){
  33. ip := utils.GetIP(params.Ctx)
  34. attach := params.Attach
  35. if attach == ""{
  36. attach = params.Ctx.Ctx.GetString("user_id")
  37. if attach == ""{
  38. attach = "attach"
  39. }
  40. }
  41. body := params.Body
  42. if body == ""{
  43. body = "body"
  44. }
  45. if params.OutTradeNo == ""{
  46. return nil, errors.New("交易单号为空")
  47. }
  48. parParams := pay.Params{strconv.Itoa(params.TotalFee), ip, body, attach, params.OutTradeNo, ""}
  49. return wc.GetPay().PreNative(&parParams)
  50. }
  51. // jsapi 支付
  52. func PayJSAPI(params *PayParams)(*JSAPIPayConfig, error){
  53. openId := params.OpenId
  54. if openId == ""{
  55. return nil, errors.New("openid 为空")
  56. }
  57. if params.OutTradeNo == ""{
  58. return nil, errors.New("交易单号为空")
  59. }
  60. attach := params.Attach
  61. if attach == ""{
  62. attach = params.Ctx.Ctx.GetString("user_id")
  63. if attach == ""{
  64. attach = "attach"
  65. }
  66. }
  67. body := params.Body
  68. if body == ""{
  69. body = "body"
  70. }
  71. ip := utils.GetIP(params.Ctx)
  72. payParams := pay.Params{strconv.Itoa(params.TotalFee), ip, body, attach, params.OutTradeNo, params.OpenId}
  73. payObj := wc.GetPay()
  74. prePayID, err := payObj.PrePayID(&payParams)
  75. if err != nil{
  76. fmt.Println("----------------->prepayid error", err.Error())
  77. return nil, err
  78. }
  79. nonceStr := util.RandomStr(32)
  80. timestamp := util.GetCurrTs()
  81. pack := "prepay_id=" + prePayID
  82. template := "appId=%s&nonceStr=%s&package=%s&signType=MD5&timeStamp=%s&key=%s"
  83. str := fmt.Sprintf(template, payObj.AppID, nonceStr, pack, strconv.FormatInt(timestamp, 10), payObj.PayKey)
  84. sign := util.MD5Sum(str)
  85. payCfg := pay.Config{timestamp, nonceStr, prePayID, "MD5", sign}
  86. exPayConfig := JSAPIPayConfig{}
  87. exPayConfig.NonceStr = payCfg.NonceStr
  88. exPayConfig.OutTradeNo = params.OutTradeNo
  89. exPayConfig.Package = "prepay_id=" + payCfg.PrePayID
  90. exPayConfig.PaySign = payCfg.Sign
  91. exPayConfig.SignType = payCfg.SignType
  92. exPayConfig.Timestamp = strconv.Itoa(int(payCfg.Timestamp))
  93. if err==nil {
  94. return &exPayConfig, nil
  95. }else{
  96. return nil, err
  97. }
  98. }
  99. // 获取微信OAuth认证参数
  100. func GetOAuthParams()(*WxOAuthConfig, error){
  101. config := WxOAuthConfig{}
  102. url, err := wxoauth.GetRedirectURL(wxConfig.RedirectUrl, wxConfig.Scope, wxConfig.State)
  103. if err != nil{
  104. return nil, err
  105. }
  106. config.OAuthRedirectUrl = url
  107. config.AppId = wxConfig.AppId
  108. config.State = wxConfig.State
  109. config.Scope = wxConfig.Scope
  110. config.ResponseType = wxConfig.ResponseType
  111. config.AuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
  112. config.RedirectUrl = wxConfig.RedirectUrl
  113. return &config, nil
  114. }
  115. // 获取jssdk配置参数
  116. func GetJSSDKRarams(url string)(*js.Config, error){
  117. return wc.GetJs().GetConfig(url)
  118. }
  119. // 获取token
  120. func GetOpenId(code string)(string, error){
  121. resToken, err := wxoauth.GetUserAccessToken(code)
  122. if err == nil{
  123. addToken(resToken.OpenID, &resToken)
  124. }
  125. return resToken.OpenID, err
  126. }
  127. // 根据code获取用户信息(需scope为 snsapi_userinfo)
  128. func GetUserInfoByCode(code string)(*oauth.UserInfo, error){
  129. openId, err := GetOpenId(code)
  130. if err != nil{
  131. return nil, err
  132. }
  133. return GetUserInfo(openId)
  134. }
  135. // 获取用户信息(需scope为 snsapi_userinfo)
  136. func GetUserInfo(openId string)(*oauth.UserInfo, error){
  137. token := getToken(openId)
  138. if token == nil{
  139. return nil, errors.New("token of openid " + openId + "does not exist")
  140. }
  141. userInfo, err := wxoauth.GetUserInfo(token.AccessToken, openId)
  142. return &userInfo, err
  143. }