package ebaiapi import ( "crypto/md5" "fmt" "net/http" "net/url" "sort" "strings" "sync" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) const ( prodURL = "https://api-be.ele.me/" signKey = "sign" secretKey = "secret" ) const ( ResponseCodeSuccess = 0 ) const ( CmdOrderCreate = "order.create" CmdOrderDeliveryStatus = "order.deliveryStatus.push" CmdOrderPartRefund = "order.partrefund.push" CmdOrderStatus = "order.status.push" CmdOrderUserCancel = "order.user.cancel" ) type ResponseResult struct { ErrNo int `json:"errno"` Error string `json:"error"` Data interface{} `json:"data"` } type API struct { source string secret string encrypt string client *http.Client config *platformapi.APIConfig speedLimiter *platformapi.Limiter locker sync.RWMutex storeCookies map[string]string } func New(source, secret string, config ...*platformapi.APIConfig) *API { // baseapi.SugarLogger.Debugf("token=%v, appKey=%v, secret=%v", token, appKey, secret) curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } api := &API{ source: source, secret: secret, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, speedLimiter: platformapi.New(apiLimitConfigs, defaultAPILimitConfig), storeCookies: make(map[string]string), } return api } func (a *API) signParams(params url.Values) string { keyValues := make([]string, 0) for k, v := range params { if k != signKey { keyValues = append(keyValues, k+"="+v[0]) } } keyValues = append(keyValues, secretKey+"="+a.secret) sort.Strings(keyValues) finalStr := strings.Join(keyValues, "&") // baseapi.SugarLogger.Debugf("sign str:%v", finalStr) return fmt.Sprintf("%X", md5.Sum([]byte(finalStr))) } func (a *API) AccessAPI(cmd string, body map[string]interface{}) (retVal *ResponseResult, err error) { baseapi.SugarLogger.Debugf("ebai AccessAPI cmd:%s", cmd) // a.speedLimiter.AccessAPI(allAPI) a.speedLimiter.AccessAPI(cmd) if body == nil { body = make(map[string]interface{}, 0) } params := url.Values{ "cmd": []string{cmd}, "version": []string{"3"}, "timestamp": []string{utils.Int64ToStr(utils.GetCurTimestamp())}, "ticket": []string{utils.GetUpperUUID()}, "source": []string{a.source}, "body": []string{string(utils.MustMarshal(body))}, "encrypt": []string{a.encrypt}, } params[signKey] = []string{a.signParams(params)} encodedParams := params.Encode() err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodPost, prodURL, strings.NewReader(encodedParams)) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.Header.Set("User-Agent", "ebai-golang-api") return request }, a.config, func(jsonResult1 map[string]interface{}) (result string, err error) { Body := jsonResult1["body"].(map[string]interface{}) retVal = &ResponseResult{ ErrNo: int(utils.MustInterface2Int64(Body["errno"])), Error: utils.Interface2String(Body["error"]), Data: Body["data"], } if retVal.ErrNo == ResponseCodeSuccess { return platformapi.ErrLevelSuccess, nil } baseapi.SugarLogger.Debugf("ebai AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) newErr := utils.NewErrorIntCode(retVal.Error, retVal.ErrNo) // todo 包括访问超频的很多错误都是这个错误号... // if newErr.IntCode() == 20212 { // return platformapi.ErrLevelExceedLimit, newErr // } return platformapi.ErrLevelCodeIsNotOK, newErr }) return retVal, err }