当前位置:   article > 正文

简单对接抖音小店的接口_如何调用抖店内部接口

如何调用抖店内部接口

最近公司需要对接抖音小店的接口。然后其实对接起来还是蛮简单的,不过自己阅读文档的能力还有点问题,所以这里记录一下开发遇到的问题。

文档地址:https://op.jinritemai.com/docs/guide-docs/6/14

首先是需要准备的配置。

抖音小店的整个流程分两步,第一步先获取他们的access_token,因为调用接口的时候需要附带这个token作为url的参数去调用的,不然会报错。然后第二步就是上面说的再去正式调参。

所以我的做法是写了一个定时每隔10分钟去调用一次token。官方文档找不到了,所以我就贴下自己的方法,下图。

 

拿到了token保存到缓存就可以写接下来的代码了。

https://op.jinritemai.com/docs/guide-docs/10/23

官方文档说他们接口get,post都能调用。我也试了确实可以。调用接口的时候主要碰到的问题是拼参数的问题。因为我开始为了偷懒,就直接用字符串拼接了,但是他们的param格式是Map<String, String> 的字符串 {"id": "0"},所以在拼的时候就很容易出错。因为你要拼成这种格式需要这样写string param = "{\"id\": \"0\"}";。参数一个还行,多了就很容易出错,所以推荐用map然后转jsonObject再转字符串。这样就不会出错了。

然后我也推荐用treeMap去做为容器去装。因为treeMap再插入值的时候会对key进行排序。因为官方文档说明了param需要key从小到大排序,而treeMap也满足了这点要求。

然后抖店接口还有个sign值的参数。他是由很多参数加到一起然后加密的一个字符串,然后这个sign值在调用接口的时候是需要一同带过去的。

然后这个requestStr在拼接的时候也是需要将他的key值从大到小去排序。下面是加密方式,这个官方文档也是有的。

然后得到上述这些就可以去调用抖店的接口了。下面贴个简单的订单列表接口实例(其实确实蛮简单的,但是坑还是有的)

流程就是先拿到token,再拿到当前时间(其实好像不是当前时间也可以),然后根据他的method, param, date去获取sign(/order/list就是这个接口的api,然后order.list就是接口的method,文档都有:https://op.jinritemai.com/docs/api-docs/15/55

然后我这里json和date做了下转换是因为参数怕会有什么特殊字符,所以要转义一下。

然后就可以拼好url了(url + param)然后用http请求就行。

全部代码:

  1. package com.xxx.mall.core.utils;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.xxx.mall.common.DoudianConstant;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestMethod;
  6. import java.io.UnsupportedEncodingException;
  7. import java.math.BigInteger;
  8. import java.net.URLEncoder;
  9. import java.security.MessageDigest;
  10. import java.security.NoSuchAlgorithmException;
  11. import java.util.Date;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.TreeMap;
  15. public class DouDianUtils {
  16. /**
  17. * 抖店接口域名
  18. */
  19. private static final String DOUDIAN_URL = "https://openapi-fxg.jinritemai.com";
  20. /**
  21. * app key
  22. */
  23. private static final String APP_KEY = "your app key";
  24. /**
  25. * app secret
  26. */
  27. private static final String APP_SECRET = "your app secret";
  28. /**
  29. * 抖店cache的cacheName
  30. */
  31. private static final String DOUDIAN_CACHE_NAME = "doudianCache";
  32. /**
  33. * 抖店cache的cacheKey
  34. */
  35. private static final String DOUDIAN_TOKEN_KEY = "doudian_access_token";
  36. /**
  37. * 通过api取accessToken
  38. */
  39. public static void fetchAccessToken() {
  40. String url = DOUDIAN_URL + "/oauth2/access_token" + "?app_id=" + APP_KEY + "&app_secret="
  41. + APP_SECRET + "&grant_type=authorization_self";
  42. String response = HttpUtils.httpGet(url, 20000);
  43. if (StringUtils.isBlank(response)) {
  44. for (int i = 0; i < 3; i++) {
  45. response = HttpUtils.httpGet(url, 20000);
  46. if (StringUtils.isNotBlank(response)) {
  47. break;
  48. }
  49. try {
  50. Thread.sleep(1000);
  51. } catch (InterruptedException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }
  56. JSONObject jsonObject = JSONObject.parseObject(response);
  57. if (jsonObject.getIntValue("err_no") == 0) {
  58. JSONObject data = jsonObject.getJSONObject("data");
  59. if (null != data) {
  60. //用于调用API的access_token
  61. String accessToken = data.getString("access_token");
  62. if (StringUtils.isNotBlank(accessToken)) {
  63. CacheUtil.put(DOUDIAN_CACHE_NAME, DOUDIAN_TOKEN_KEY, accessToken);
  64. }
  65. }
  66. }
  67. }
  68. /**
  69. * 获取 输入参数签名结果 sign
  70. *
  71. * @param methodName 方法名
  72. * @param paramJson 传参
  73. * @param timeStamp 时间戳
  74. * @return sign
  75. */
  76. public static String fetchSign(String methodName, String paramJson, String timeStamp) {
  77. String requestStr = APP_SECRET + "app_key" + APP_KEY + "method" + methodName + "param_json" + paramJson + "timestamp"
  78. + timeStamp + "v2" + APP_SECRET;
  79. return paramToMD5(requestStr);
  80. }
  81. /**
  82. * 将param参数转成MD5
  83. *
  84. * @param requestStr 请求参数
  85. * @return String
  86. */
  87. public static String paramToMD5(String requestStr) {
  88. byte[] secretBytes;
  89. try {
  90. secretBytes = MessageDigest.getInstance("md5").digest(
  91. requestStr.getBytes());
  92. } catch (NoSuchAlgorithmException e) {
  93. throw new RuntimeException("没有这个md5算法!");
  94. }
  95. StringBuilder md5code = new StringBuilder(new BigInteger(1, secretBytes).toString(16));
  96. while (md5code.length() < 32) {
  97. md5code.insert(0, "0");
  98. }
  99. return md5code.toString();
  100. }
  101. /**
  102. * 获取订单列表 支持按照子订单状态和订单的创建时间、更新时间来检索订单,获取订单列表
  103. *
  104. * Tips:
  105. * 此接口做了限流,每个access_token每分钟1000次上限
  106. * 此接口,page最多返回100页,一页最多100单,故同样的请求,最多能拉到1万单
  107. * 通过该接口获取到的父订单,会在order_id后面会加上字母A做标识(这里和从店铺后台导出的订单有区别,从店铺后台导出的订单末尾没有A,
  108. * 但其实际和通过openapi获取的父订单是同一个,如依据运营导出的订单做核对,则请做订单末尾的A相关处理)
  109. * 如搜索时指定order_status,则搜索维度为子订单,即按照子订单状态搜索,total也为该状态子订单数量。返回结果的json结构不变,仍为父子订单结构,
  110. * 因此当有父订单包含多子订单时,返回的结构中父订单可能会有重复!
  111. * 由于订单同步会有延迟,建议在使用open接口拉取订单时,要做缓冲和兜底处理。比如,在今天的6:00去拉取5:30-5:40的数据后(20分钟后拉),明天的6:00时再拉取一次今天5:30-5:40的数据(兜底补拉)
  112. *
  113. * 拉订单最好不要100页的拉,要98-99页的拉,100页有的时候会出问题
  114. * start_time 开始时间
  115. * end_time 结束时间
  116. * order_by 1、默认按订单创建时间搜索 2、值为“create_time”:按订单创建时间;值为“update_time”:按订单更新时间
  117. * @return JSONArray
  118. * @throws UnsupportedEncodingException
  119. */
  120. public static JSONObject fetchOrderList() throws UnsupportedEncodingException {
  121. Map<String, String> map = new TreeMap<>();
  122. map.put("start_time", "2020/08/01 00:00:00");
  123. map.put("end_time", "2020/10/02 00:00:00");
  124. map.put("order_by", "create_time");
  125. String paramJson = JSONObject.toJSONString(map);
  126. String accessToken = (String) CacheUtil.get(DOUDIAN_CACHE_NAME, DOUDIAN_TOKEN_KEY);
  127. String url = DOUDIAN_URL + "/order/list";
  128. Date now = new Date();
  129. String dateStr = DateUtil.date2Str(now, "yyyy-MM-dd HH:mm:ss");
  130. String sign = fetchSign("order.list", paramJson, dateStr);
  131. //转码
  132. String paramJson2 = URLEncoder.encode(paramJson, "UTF-8");
  133. String dateStr2 = URLEncoder.encode(dateStr, "UTF-8");
  134. String param = "?app_key=" + APP_KEY + "&method=" + "order.list" + "&access_token="
  135. + accessToken + "&param_json=" + paramJson2 + "&timestamp=" + dateStr2 + "&v=2&sign=" + sign;
  136. String response = HttpUtils.httpGet(url + param, 20000);
  137. JSONObject jsonObject = JSONObject.parseObject(response);
  138. if (jsonObject.getIntValue("err_no") == 0) {
  139. return jsonObject.getJSONObject("data");
  140. }
  141. return null;
  142. }
  143. }

这里只是实例代码,可以根据实际要求优化代码,这就是后面的工作了。

 

=============================================================================================

更新一下遇到新的问题:

批量添加sku的时候(/sku/addAll),规格id取的是规格项的最上级的id。这里如果有三个sku的话就是拼成8|8|8

 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/357870
推荐阅读
相关标签
  

闽ICP备14008679号