package mtpsapi import ( "crypto/sha1" "fmt" "net/http" "net/url" "sort" "strings" "time" "git.rosy.net.cn/baseapi/platform/common" "git.rosy.net.cn/baseapi/utils" "go.uber.org/zap" ) const ( clientTimeout = time.Second * 10 sleepSecondWhenLimited = 6 * time.Second maxRetryCountWhenNetworkException = 3 maxRetryCountWhenReachLimited = 10 ) const ( mtpsAPIURL = "https://peisongopen.meituan.com/api" ) const ( mtpsStatusSuccess = 0 mtpsStatusSystemError = 1 mtpsStatusMissingSystemParams = 2 mtpsStatusMissingBusinessParams = 3 ) type MTPSResult struct { Code int `json:"code"` Message string `json:"message"` Data map[string]interface{} `json:"data"` } type MTPSAPI struct { appKey string secret string sugarLogger *zap.SugaredLogger client *http.Client } // type MTPSOderStatus struct { // DeliveryId int64 `json:"delivery_id"` // MtPeiSongId string `json:"mt_peisong_id"` // OrderId string `json:"order_id"` // Status int `json:"status"` // OperateTime int `json:"operate_time"` // CourierName string `json:"courier_name"` // CourierPhone string `json:"courier_phone"` // CancelReasonId int `json:"cancel_reason_id"` // CancelReason string `json:"cancel_reason"` // } func NewMTPSAPI(appKey, secret string, sugarLogger *zap.SugaredLogger) *MTPSAPI { api := &MTPSAPI{ appKey: appKey, secret: secret, sugarLogger: sugarLogger, client: &http.Client{Timeout: clientTimeout}, } return api } func (m *MTPSAPI) signParams(params url.Values) string { keyValues := make([]string, 0) for k, v := range params { valStr := strings.Join(v, "") if valStr != "" { keyValues = append(keyValues, k+valStr) } } sort.Strings(keyValues) finalStr := m.secret + strings.Join(keyValues, "") // e.sugarLogger.Debugf("sign str:%v", finalStr) return fmt.Sprintf("%x", sha1.Sum([]byte(finalStr))) } func (m *MTPSAPI) AccessMTPS(action string, params map[string]interface{}) (retVal *MTPSResult, err error) { if params == nil { panic("params is nil!") } params["appkey"] = m.appKey params["timestamp"] = utils.GetCurTimestamp() params["version"] = "1.0" params2 := make(url.Values) for k, v := range params { params2[k] = []string{fmt.Sprint(v)} } params2["sign"] = []string{m.signParams(params2)} request, _ := http.NewRequest("POST", mtpsAPIURL+"/"+action, strings.NewReader(string(params2.Encode()))) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") apiAccess := &common.AccessPlatformAPIWithRetryParams{ MaxExceedLimitRetryCount: maxRetryCountWhenReachLimited, MaxRecoverableRetryCount: maxRetryCountWhenNetworkException, SleepSecondWhenExceedLimit: sleepSecondWhenLimited, Client: m.client, Request: request, SugarLogger: m.sugarLogger, } err = common.AccessPlatformAPIWithRetry(apiAccess, func(response *http.Response) (result int, err error) { jsonResult1, err := utils.HttpResponse2Json(response) if err != nil { m.sugarLogger.Warnf("HttpResponse2Json return:%v", err) return 0, err } code := int(utils.MustInterface2Int64(jsonResult1["code"])) retVal = &MTPSResult{ Code: code, } if code == mtpsStatusSuccess { retVal.Data = jsonResult1["data"].(map[string]interface{}) return common.PAErrorLevelSuccess, nil } retVal.Message = jsonResult1["message"].(string) return common.PAErrorLevelFailed, nil }) return retVal, err } func (m *MTPSAPI) QueryOrderStatus(deliveryId int64, MtPeiSongId string) (retVal map[string]interface{}, err error) { params := map[string]interface{}{ "delivery_id": deliveryId, "mt_peisong_id": MtPeiSongId, } if result, err := m.AccessMTPS("order/status/query", params); err != nil { return nil, err } else { return result.Data, nil } }