wx.go 4.2 KB

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