抖音商家自研

源码基于抖店开放平台源码修改,因为用的VS版本比较老,所以很多地方做了调整,再加上自己的代码

 public class douyin
    {
        public static string appkey = "*******";//换成自己的appkey
        public static string appSecret = "*******************";//换成自己的appSecret
        public static string host = "https://openapi-fxg.jinritemai.com";
        public string Token = "";

        public douyin(string shopId, string shopName)
        {
            //获取当前Token;
            Token = GetToken(shopId, shopName);

        }

        public void GetSoldsByTime(string shopId, DateTime stateTime, DateTime endTime)
        {
            string method = "order.searchList";
            long timestamp = GetTimeStamp(DateTime.Now);
            long startTimeStamp = GetTimeStamp(stateTime);
            long endTimeStamp = GetTimeStamp(endTime);

            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("page", 1);
            dic.Add("size", 100);//最大支持100
            dic.Add("create_time_start", startTimeStamp);
            dic.Add("create_time_end", endTimeStamp);//测试账号需要 test_shop = "1"

            // 序列化参数
            var paramJson = Marshal(dic);
            // 计算签名
            var sign = Sign(appkey, appSecret, method, timestamp, paramJson);
            string msg = Fetch(method, timestamp.ToString(), paramJson, Token, sign);
        }


        public string GetToken(string shopId, string shopName)
        {
            TB_Login_Number tokenInfo = new TB_Login_Number();
            //根据shopId 判断当前数据库是否有存储Token
            //这里从数据库根据ShopId查询当前Token存不存在
            
            if (tokenInfo == null || string.IsNullOrWhiteSpace(tokenInfo.access_token))
            {
                //当Token不存在时,创建Token并存储
                TokenResult token = CreateToken(shopId);
                if (token != null)
                {
                   //这里可以存储Token到自己的数据库保存
                  
                    return token.access_token;
                }
                return "";
            }
            //Token存在时判断Token是否即将过期或者已过期
            var timespan = (tokenInfo.CTime.AddSeconds(Convert.ToInt32(tokenInfo.expires_in)) - DateTime.Now).TotalHours;
            if (timespan < 1)
            {
                var token = RefreshToken(tokenInfo.refresh_token);
                if (token != null)
                {
                    //刷新Token 之后修改数据库Token
                    
                    return token.access_token;
                }
                return "";
            }
            return tokenInfo.access_token;
        }


        public TokenResult CreateToken(string shopId)
        {
            var method = "token.create";
            long timestamp = GetTimeStamp(DateTime.Now);

            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("shop_id", shopId);
            dic.Add("code", "");
            dic.Add("grant_type", "authorization_self");
            dic.Add("test_shop", "1");//测试账号需要 test_shop = "1"

            // 序列化参数
            var paramJson = Marshal(dic);
            // 计算签名
            var sign = Sign(appkey, appSecret, method, timestamp, paramJson);

            var methodPath = method.Replace('.', '/');
            var url = host + "/" + methodPath +
                    "?method=" + HttpUtility.UrlEncode(method, Encoding.UTF8) +
                    "&app_key=" + HttpUtility.UrlEncode(appkey, Encoding.UTF8) +
                    "&timestamp=" + HttpUtility.UrlEncode(timestamp.ToString(), Encoding.UTF8) +
                    "&v=" + HttpUtility.UrlEncode("2", Encoding.UTF8) +
                    "&sign=" + HttpUtility.UrlEncode(sign, Encoding.UTF8) +
                    "&sign_method=" + HttpUtility.UrlEncode("hmac-sha256", Encoding.UTF8);
            var msg = HttpPost(url, paramJson);
            JObject job = JObject.Parse(msg);
            if (job.Value<int>("code") == 10000)
            {
                return JsonConvert.DeserializeObject<TokenResult>(job["data"].ToString());
            }
            return null;
        }

        public TokenResult RefreshToken(string refreshToken)
        {
            var method = "token.refresh";
            long timestamp = GetTimeStamp(DateTime.Now);

            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("refresh_token", refreshToken);
            dic.Add("grant_type", "refresh_token");

            // 序列化参数
            var paramJson = Marshal(dic);
            // 计算签名
            var sign = Sign(appkey, appSecret, method, timestamp, paramJson);
            var methodPath = method.Replace('.', '/');
            var url = host + "/" + methodPath +
                    "?method=" + HttpUtility.UrlEncode(method, Encoding.UTF8) +
                    "&app_key=" + HttpUtility.UrlEncode(appkey, Encoding.UTF8) +
                    "&timestamp=" + HttpUtility.UrlEncode(timestamp.ToString(), Encoding.UTF8) +
                    "&v=" + HttpUtility.UrlEncode("2", Encoding.UTF8) +
                    "&sign=" + HttpUtility.UrlEncode(sign, Encoding.UTF8) +
                    "&sign_method=" + HttpUtility.UrlEncode("hmac-sha256", Encoding.UTF8);
            var msg = HttpPost(url, paramJson);
            JObject job = JObject.Parse(msg);
            if (job.Value<int>("code") == 10000)
            {
                return JsonConvert.DeserializeObject<TokenResult>(job["data"].ToString());
            }
            return null;
        }

        // 调用Open Api,取回数据
        public string Fetch(string method, string timestamp, string paramJson,
            string accessToken, string sign)
        {

            var methodPath = method.Replace('.', '/');
            var url = host + "/" + methodPath +
                    "?method=" + HttpUtility.UrlEncode(method, Encoding.UTF8) +
                    "&app_key=" + HttpUtility.UrlEncode(appkey, Encoding.UTF8) +
                    "&access_token=" + HttpUtility.UrlEncode(accessToken, Encoding.UTF8) +
                    "&timestamp=" + HttpUtility.UrlEncode(timestamp.ToString(), Encoding.UTF8) +
                    "&v=" + HttpUtility.UrlEncode("2", Encoding.UTF8) +
                    "&sign=" + HttpUtility.UrlEncode(sign, Encoding.UTF8) +
                    "&sign_method=" + HttpUtility.UrlEncode("hmac-sha256", Encoding.UTF8);

            var msg = HttpPost(url, paramJson);
            return msg;
        }

        private string HttpPost(string url, string paramJson)
        {
            var context = Encoding.UTF8.GetBytes(paramJson);

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "POST";
            //request.Headers.Add("Accept", "*/*");
            request.ContentType = "application/json;charset=UTF-8";

            var s = request.GetRequestStream();
            s.Write(context, 0, context.Length);

            var response = (HttpWebResponse)request.GetResponse();
            var stream = response.GetResponseStream();
            StreamReader reader = new StreamReader(stream);

            return reader.ReadToEnd();
        }

        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        /// <returns></returns>
        private long GetTimeStamp(DateTime time)
        {
            // DateTime时间格式转换为Unix时间戳格式
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (long)(DateTime.Now - startTime).TotalSeconds;
        }
        // 计算签名
        private string Sign(string appKey, string appSecret, string method, long timestamp, string paramJson)
        {
            // 按给定规则拼接参数
            var paramPattern = "app_key" + appKey + "method" + method + "param_json" + paramJson + "timestamp" +
                               timestamp + "v2";
            var signPattern = appSecret + paramPattern + appSecret;
            Console.WriteLine("sign_pattern:" + signPattern);

            return Hmac(signPattern, appSecret);
        }

        // 计算hmac
        private string Hmac(string plainText, string appSecret)
        {
            var h = new HMACSHA256(Encoding.UTF8.GetBytes(appSecret));
            var sum = h.ComputeHash(Encoding.UTF8.GetBytes(plainText));

            var sb = new StringBuilder();
            foreach (byte b in sum)
            {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }
        // 序列化参数
        // 这一步看上去冗余,实际很重要。如果要自己实现,则必须保证这三点:
        // 1、保证JSON所有层级上Key的有序性
        // 2、保证JSON的所有数值不带多余的小数点
        // 3、保证转义逻辑与这段代码一致
        private static string Marshal(Dictionary<string, object> obj)
        {
            // 第一步:把字典按Key的字母顺序排序
            IDictionary<string, object> sortedParams = new SortedDictionary<string, object>(obj, StringComparer.Ordinal);
            return JsonConvert.SerializeObject(sortedParams);
        }

    }

 

posted @ 2022-05-29 15:31  Modelu  阅读(107)  评论(0)    收藏  举报