package platApi import ( "bytes" "crypto/hmac" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "game/base/util" "io/ioutil" "net/http" "net/url" "time" "game/base/log" ) type QQTokenRes struct { AccessToken string `json:"access_token"` ExpiresIn uint32 `json:"expires_in"` ErrCode uint32 `json:"errcode"` ErrMsg string `json:"errmsg"` } func QQAccessToken(appID string, secret string) (key string, expire uint32, err error) { url1 := "https://api.q.qq.com/api/getToken?grant_type=client_credential&appid=" + appID + "&secret=" + secret resp, err := http.Get(url1) if err != nil { return } body, err := ioutil.ReadAll(resp.Body) if err != nil { return } resp.Body.Close() ret := &QQTokenRes{} err = json.Unmarshal(body, &ret) if err != nil || ret.ErrCode != 0 { return } key = ret.AccessToken expire = ret.ExpiresIn return } type QQPrePayRes struct { Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` PrepayId string `json:"prepayId"` } type QQPrePayReq struct { OpenId string `json:"openid"` AppId string `json:"appid"` Ts int `json:"ts"` ZoneId string `json:"zone_id"` Pf string `json:"pf"` Amt int `json:"amt"` GoodId string `json:"goodid"` GoodNum string `json:"good_num"` AppRemark string `json:"app_remark"` BillNo string `json:"bill_no"` Sig string `json:"sig"` } func QQPrePay(openid string, appid string, zone string, amt string, goodId string, goodNum uint32, token string, sessionKey string) (*QQPrePayRes, error) { u := "https://api.q.qq.com/api/json/openApiPay/GamePrePay?access_token=" + token value := url.Values{} value.Add("openid", openid) value.Add("appid", appid) value.Add("ts", util.Int64ToString(time.Now().Unix())) value.Add("zone_id", zone) value.Add("pf", "qq_m_qq-2001-android-2011") value.Add("amt", amt) value.Add("goodid", "31b654ce0caeda34ad583d069551481c") //value.Add("goodid", goodId) value.Add("good_nun", util.Uint32ToString(goodNum)) value.Add("app_remark", zone + "-" + goodId + "-" + openid) billNo, _ := util.NextId() value.Add("bill_no", util.Int64ToString(billNo)) param := "POST&" + url.PathEscape("/api/json/openApiPay/GamePrePay") + "&" + value.Encode() + "&session_key=" + sessionKey h := hmac.New(sha256.New, []byte(sessionKey)) h.Write([]byte(param)) sign := hex.EncodeToString(h.Sum(nil)) value.Set("sig", sign) req := &QQPrePayReq{}; raw_data, _ := json.Marshal(util.UrlValuesToMap(value)) err := json.Unmarshal(raw_data, &req) data, _ := json.Marshal(req) resp, err := http.Post(u, "application/json;charset=UTF-8", bytes.NewReader(data)) if err != nil { log.Error("Post error ", err) return nil, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Error("Read Body Error ", err) return nil, err } res := &QQPrePayRes{} if e := json.Unmarshal(body, res); e != nil { log.Error("Recv Result Error ", e) return nil, e } if res.Errcode != 0 { log.Error(res.Errmsg) } return res, nil } type QQSessionRet struct { Openid string `json:"openid"` SessionKey string `json:"session_key"` UinionId string `json:"uinionid"` Errcode int `json:"errcode"` ErrMsg string `json:"errMsg"` } func QQCode2Session(code string, appID string, secret string) *QQSessionRet { client := http.Client{} param := url.Values{} param.Set("appid", appID) param.Set("secret", secret) param.Set("js_code", code) param.Set("grant_type", "authorization_code") urlStr := "https://api.q.qq.com/sns/jscode2session?" + param.Encode() res, err := client.Get(urlStr) if err != nil { log.Error("Get Access Token Error ", urlStr, err) return nil } body, bodyErr := ioutil.ReadAll(res.Body) if bodyErr != nil { log.Error("Get Access Token Error ", bodyErr) return nil } res.Body.Close() ret := &QQSessionRet{} e := json.Unmarshal(body, ret) if e != nil { log.Error("Get Access Token Error ", e) return nil } if ret.Errcode != 0 { log.Error("Get Access Token Error ", ret.Errcode, ret.ErrMsg) return nil } return ret } type QQPayCallBack struct { Openid string `json:"openid"` BillNo string `json:"bill_no"` Amt int `json:"amt"` Ts int64 `json:"ts"` AppRemark string `json:"app_remark"` Sig string `json:"sig"` } func QQCallBackVerify(req *QQPayCallBack, urlPath string, secret string) bool { var str string if req.AppRemark == "" { str = fmt.Sprintf("POST&%s&amt=%d&bill_no=%s&openid=%s&ts=%d&AppSecret=%s", url.QueryEscape(urlPath), req.Amt, req.BillNo, req.Openid, req.Ts, secret) } else { str = fmt.Sprintf("POST&%s&amt=%d&app_remark=%s&bill_no=%s&openid=%s&ts=%d&AppSecret=%s", url.QueryEscape(urlPath), req.Amt, req.AppRemark, req.BillNo, req.Openid, req.Ts, secret) } h := hmac.New(sha256.New, []byte(secret)) h.Write([]byte(str)) sign := hex.EncodeToString(h.Sum(nil)) if sign != req.Sig { return false } return true } type QQPayCallBackRet struct { Code int `json:"code"` Msg string `json:"msg"` }