package kuaishou_mini import ( "crypto/md5" "errors" "fmt" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" "net/http" "sort" "strings" "sync" ) const ( // KuaiShouBashUrl 基础域名 KuaiShouBashUrl = "http://open.kuaishou.com" // 域名 KuaiShouAuthLogin = KuaiShouBashUrl + "/oauth2/mp/code2session" // 授权登录 KuaiShouGetToken = KuaiShouBashUrl + "/oauth2/access_token" // 获取授权token KuaiShouPreCreateOrder = KuaiShouBashUrl + "/openapi/mp/developer/epay/create_order" // 预下单接口 KuaiShouGetOrderDetail = KuaiShouBashUrl + "/openapi/mp/developer/epay/query_order" // 获取订单详情接口 KuaiShouRefundOrder = KuaiShouBashUrl + "/openapi/mp/developer/epay/apply_refund" // 订单退款 KuaiShouRefundOrderDetail = KuaiShouBashUrl + "/openapi/mp/developer/epay/query_refund" // 订单退款详情 KuaiShouGetSettleOrder = KuaiShouBashUrl + "/openapi/mp/developer/epay/settle" // 刷新订单结算信息 KuaiShouQuerySettleOrder = KuaiShouBashUrl + "/openapi/mp/developer/epay/query_settle" // 查询订单的结算信息 ) type API struct { appSecret string // 应用唯一标识对应的密钥 appId string // 应用唯一标识 client *http.Client config *platformapi.APIConfig locker sync.RWMutex accessToken string // accessToken expiresIn int64 // 过期时间 } func (a *API) GetAppID() string { return a.appId } func (a *API) GetSecret() string { return a.appSecret } // New 初始化 func New(appSecret, appId string, config ...*platformapi.APIConfig) *API { curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } return &API{ appSecret: appSecret, appId: appId, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, } } // GetToken 获取快手token func (a *API) GetToken() error { if a.appId == "" || a.appSecret == "" { return errors.New("快手appId为空或appSecret为空") } result, err := a.AccessAPI2(KuaiShouGetToken, map[string]interface{}{"app_id": a.appId, "app_secret": a.appSecret, "grant_type": "client_credentials"}) if err != nil { return err } var data *GetAutoTokenRes if err := utils.Map2StructByJson(result, &data, false); err != nil { return err } if data.Result != 1 { return errors.New(utils.Int64ToStr(data.Result)) } a.expiresIn = data.ExpiresIn a.accessToken = data.AccessToken return nil } // AccessAPI1 发送请求(支付) func (a *API) AccessAPI1(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodPost, url, strings.NewReader(utils.Format4Output(params, false))) request.Header.Set("Content-Type", "application/json") return request }, a.config, func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { if jsonResult1 == nil { return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") } retVal = jsonResult1 return platformapi.ErrLevelSuccess, nil }) return retVal, err } // AccessAPI2 发送请求(登录) func (a *API) AccessAPI2(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodPost, url, strings.NewReader(utils.Map2URLValues(params).Encode())) request.Header.Add("Content-Type", "application/x-www-form-urlencoded") return request }, a.config, func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { if jsonResult1 == nil { return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") } retVal = jsonResult1 return platformapi.ErrLevelSuccess, nil }) return retVal, err } // sign 签名 func (a *API) sign(param map[string]interface{}) string { param["app_id"] = a.appId var paramsArr []string for k, v := range param { if k == "sign" || k == "access_token" { continue } value := strings.TrimSpace(fmt.Sprintf("%v", v)) if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") && len(value) > 1 { value = value[1 : len(value)-1] } value = strings.TrimSpace(value) if value == "" || value == "nil" { continue } paramsArr = append(paramsArr, k) } sort.Strings(paramsArr) signParma := make([]string, len(paramsArr)) for k, v := range paramsArr { if !utils.IsNil(param[v]) { signParma[k] = v + "=" + fmt.Sprintf("%v", param[v]) } } sign := strings.Join(signParma, "&") + a.appSecret return fmt.Sprintf("%x", md5.Sum([]byte(sign))) }