| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- package wx
- import (
- "encoding/xml"
- "errors"
- "fmt"
- "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
- "git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
- "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
- "github.com/silenceper/wechat/js"
- "github.com/silenceper/wechat/oauth"
- "github.com/silenceper/wechat/pay"
- "github.com/silenceper/wechat/util"
- "io"
- "io/ioutil"
- "net/http"
- "net/url"
- "os"
- "strconv"
- "strings"
- )
- // 微信回调处理器
- var _wxPayCallbackHandler func(result *pay.NotifyResult)models.SysReturn = nil
- // 微信通用登录回调处理器
- var _wxLoginCallbackHandler func(ctx *entitys.CtrlContext, body []byte, info *oauth.UserInfo)models.SysReturn = nil
- // 注册微信支付回调处理函数
- func RegisterWxPayCallbackHandler(handler func(result *pay.NotifyResult)models.SysReturn){
- _wxPayCallbackHandler = handler
- }
- // 调用微信支付回调处理函数
- func CallWxPayCallbackHandler(c *entitys.CtrlContext)models.SysReturn{
- if _wxPayCallbackHandler == nil{
- return models.SysReturn{500, "微信支付回调处理函数为空", nil}
- }
- data, err := ioutil.ReadAll(c.Ctx.Request.Body)
- if err != nil{
- fmt.Println("******************----》微信支付回调read request body错误", err.Error())
- return models.SysReturn{500, err.Error(), nil}
- }
- notifyRet := pay.NotifyResult{}
- err = xml.Unmarshal(data, ¬ifyRet)
- //err = c.Ctx.BindXML(¬ifyRet)
- if err != nil{
- fmt.Println("******************----》微信支付回调bindxml错误", err.Error())
- return models.SysReturn{500, err.Error(), nil}
- }
- if notifyRet.ResultCode == "SUCCESS" && notifyRet.ReturnCode == "SUCCESS"{
- ok, err := VerifyResponseData(data, wxConfig.PayKey)
- if err != nil{
- fmt.Println("*****************---->微信支付回调验证错误", err.Error())
- return models.SysReturn{500, err.Error(), nil}
- }
- if !ok{
- fmt.Println("*****************---->微信支付回调验证错误, ok is false")
- return models.SysReturn{500, "", nil}
- }
- return _wxPayCallbackHandler(¬ifyRet)
- }else{
- fmt.Println("------------------>微信支付失败", notifyRet)
- return models.SysReturn{500, "", ""}
- }
- }
- // 注册微信登录回调处理函数
- func RegisterWxLoginCallbackHandler(handler func(ctx *entitys.CtrlContext, body []byte, info *oauth.UserInfo)models.SysReturn){
- _wxLoginCallbackHandler = handler
- }
- // 调用微信登录处理函数
- func CallWxLoginCallbackHandler(ctx *entitys.CtrlContext, body []byte, info *oauth.UserInfo)models.SysReturn{
- if _wxLoginCallbackHandler == nil{
- return models.SysReturn{500, "微信登录回调处理函数为空", nil}
- }else{
- return _wxLoginCallbackHandler(ctx, body, info)
- }
- }
- // 扫码支付
- func PayNative(params *PayParams)(*pay.PayResult, error){
- ip := utils.GetIP(params.Ctx)
- attach := params.Attach
- if attach == ""{
- attach = params.Ctx.Ctx.GetString("user_id")
- if attach == ""{
- attach = "attach"
- }
- }
- body := params.Body
- if body == ""{
- body = "body"
- }
- if params.OutTradeNo == ""{
- return nil, errors.New("交易单号为空")
- }
- parParams := pay.Params{strconv.Itoa(params.TotalFee), ip, body, attach, params.OutTradeNo, ""}
- return wc.GetPay().PreNative(&parParams)
- }
- // jsapi 支付
- func PayJSAPI(params *PayParams)(*JSAPIPayConfig, error){
- openId := params.OpenId
- if openId == ""{
- return nil, errors.New("openid 为空")
- }
- if params.OutTradeNo == ""{
- return nil, errors.New("交易单号为空")
- }
- attach := params.Attach
- if attach == ""{
- fmt.Println("--------------------->1")
- attach = params.Ctx.Ctx.GetString("user_id")
- if attach == ""{
- fmt.Println("--------------------->2")
- attach = "attach"
- }
- }
- body := params.Body
- if body == ""{
- body = "body"
- }
- ip := utils.GetIP(params.Ctx)
- fmt.Println("params.Attach", params.Attach, "attach", attach)
- payParams := pay.Params{
- strconv.Itoa(params.TotalFee),
- ip,
- body,
- attach,
- params.OutTradeNo,
- params.OpenId,
- }
- payObj := wc.GetPay()
- prePayID, err := payObj.PrePayID(&payParams)
- if err != nil{
- fmt.Println("----------------->prepayid error", err.Error())
- return nil, err
- }
- nonceStr := util.RandomStr(32)
- timestamp := util.GetCurrTs()
- pack := "prepay_id=" + prePayID
- template := "appId=%s&nonceStr=%s&package=%s&signType=MD5&timeStamp=%s&key=%s"
- str := fmt.Sprintf(template, payObj.AppID, nonceStr, pack, strconv.FormatInt(timestamp, 10), payObj.PayKey)
- sign := util.MD5Sum(str)
- payCfg := pay.Config{timestamp, nonceStr, prePayID, "MD5", sign}
- exPayConfig := JSAPIPayConfig{}
- exPayConfig.AppId = wxConfig.AppId
- exPayConfig.NonceStr = payCfg.NonceStr
- exPayConfig.OutTradeNo = params.OutTradeNo
- exPayConfig.Package = "prepay_id=" + payCfg.PrePayID
- exPayConfig.PaySign = payCfg.Sign
- exPayConfig.SignType = payCfg.SignType
- exPayConfig.Timestamp = strconv.Itoa(int(payCfg.Timestamp))
- if err==nil {
- return &exPayConfig, nil
- }else{
- return nil, err
- }
- }
- // 关闭订单
- func CloseOrder(outTradeNo string)(*pay.CloseOrderResult, error){
- return wc.GetPay().CloseOrder(outTradeNo)
- }
- // 获取微信OAuth认证参数
- func GetOAuthParams(paramMap map[string]string)(*WxOAuthConfig, error){
- config := WxOAuthConfig{}
- urlstr := wxConfig.RedirectUrl
- paramstr := ""
- for k, v := range paramMap{
- paramstr += fmt.Sprintf("%s=%s", k, url.QueryEscape(v))
- }
- if strings.Index(urlstr, "%s") > 0{
- urlstr = fmt.Sprintf(urlstr, paramstr)
- }
- url, err := wxoauth.GetRedirectURL(urlstr, wxConfig.Scope, url.QueryEscape(wxConfig.State))
- if err != nil{
- return nil, err
- }
- config.OAuthRedirectUrl = url
- config.AppId = wxConfig.AppId
- config.State = wxConfig.State
- config.Scope = wxConfig.Scope
- config.ResponseType = wxConfig.ResponseType
- config.AuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"
- config.RedirectUrl = wxConfig.RedirectUrl
- return &config, nil
- }
- // 获取jssdk配置参数
- func GetJSSDKRarams(url string)(*js.Config, error){
- return wc.GetJs().GetConfig(url)
- }
- // 获取token
- func GetOpenId(code string)(string, error){
- resToken, err := wxoauth.GetUserAccessToken(code)
- if err == nil{
- addToken(resToken.OpenID, &resToken)
- }
- return resToken.OpenID, err
- }
- // 根据code获取用户信息(需scope为 snsapi_userinfo)
- func GetUserInfoByCode(code string)(*oauth.UserInfo, error){
- openId, err := GetOpenId(code)
- if err != nil{
- return nil, err
- }
- return GetUserInfo(openId)
- }
- // 获取用户信息(需scope为 snsapi_userinfo)
- func GetUserInfo(openId string)(*oauth.UserInfo, error){
- token := getToken(openId)
- if token == nil{
- return nil, errors.New("token of openid " + openId + "does not exist")
- }
- userInfo, err := wxoauth.GetUserInfo(token.AccessToken, openId)
- return &userInfo, err
- }
- /**
- * @brief: 根据资源id从微信下载
- * @param1 resId: 资源id
- * @param2 tagFile: 目标文件
- * @return: 错误信息
- */
- func Download(resId, tagFile string)error{
- token, err := wc.GetAccessToken()
- if err != nil{
- fmt.Println("wc.GetAccessToken()错误", err.Error())
- return err
- }
- mediaUrl := "https://api.weixin.qq.com/cgi-bin/media/get"
- downloadUrl := mediaUrl + "?access_token=" + token + "&media_id=" + resId
- res, err := http.Get(downloadUrl)
- if err != nil{
- fmt.Println("请求资源错误:" + err.Error())
- return err
- }
- f, err := os.Create(tagFile)
- if err != nil {
- fmt.Println("本地创建资源文件:" + err.Error())
- return err
- }
- _, err = io.Copy(f, res.Body)
- if err != nil{
- fmt.Println("写入本地资源文件:" + err.Error())
- return err
- }else{
- return nil
- }
- }
|