|
@@ -0,0 +1,232 @@
|
|
|
+package com.raycos.raycosdatacenterapi.authorize.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.raycos.raycoscommon.Internal.Result;
|
|
|
+import com.raycos.raycoscommon.Internal.datacenterapi.TbAmzToken;
|
|
|
+import com.raycos.raycoscommon.Internal.datacenterapi.vo.GetAmzTokenByLwaCodeVo;
|
|
|
+import com.raycos.raycoscommon.json.TokenAmz;
|
|
|
+import com.raycos.raycoscommon.json.TokenRetAmzJson;
|
|
|
+import com.raycos.raycosdatacenterapi.authorize.AmzTokenService;
|
|
|
+import com.raycos.raycosdatacenterapi.mapper.TbAmzTokenMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.http.HttpEntity;
|
|
|
+import org.springframework.http.HttpHeaders;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.Assert;
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.time.Instant;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class AmzTokenServiceImpl implements AmzTokenService {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
|
|
|
+ * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
|
|
|
+ * 5.1 -> grant_type 请求的访问授权的类型。必须是 。authorization_code
|
|
|
+ */
|
|
|
+ private final String AUTHORIZATION_CODE = "authorization_code";
|
|
|
+ /**
|
|
|
+ * 参考文档: https://developer-docs.amazon.com/sp-api/docs/connecting-to-the-selling-partner-api
|
|
|
+ * 文档: 步骤 1.申请 Login with Amazon 访问令牌
|
|
|
+ * refresh_token.将此函数用于需要销售合作伙伴授权的调用操作。所有非无授权操作都需要销售伙伴的授权。指定此值时,请包括rrefresh_token参数。
|
|
|
+ */
|
|
|
+ private final String REFRESH_TOKEN = "refresh_token";
|
|
|
+ /**
|
|
|
+ * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
|
|
|
+ * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
|
|
|
+ * 5.2 -> token_type 返回的 token 类型。应该是 bearer。
|
|
|
+ */
|
|
|
+ private final String BEARER = "bearer";
|
|
|
+ /**
|
|
|
+ * 参考文档:https://developer-docs.amazon.com/sp-api/docs/website-authorization-workflow
|
|
|
+ * 文档: 步骤 5:应用程序使用 LWA 授权码生成 LWA 刷新令牌
|
|
|
+ * LWA CODE 调用接口 返回令牌信息
|
|
|
+ */
|
|
|
+ private final String URL = "https://api.amazon.com/auth/o2/token";
|
|
|
+ /**
|
|
|
+ * 亚马逊授权成功 重定向浏览器页面 并且通过URL 携带
|
|
|
+ * LWA code 用于生成亚马逊令牌
|
|
|
+ */
|
|
|
+ private final String REDIRECTURI = "https://www.raycos.net/erp/authorize";
|
|
|
+ @Autowired
|
|
|
+ private TbAmzTokenMapper tbAmzTokenMapper;
|
|
|
+
|
|
|
+ @Resource(name = "ExternalNetwork")
|
|
|
+ private RestTemplate restTemplate;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 亚马逊刷新令牌接口
|
|
|
+ */
|
|
|
+ private String url = "https://api.amazon.com/auth/o2/token";
|
|
|
+
|
|
|
+
|
|
|
+ private String getRequestBody(GetAmzTokenByLwaCodeVo gatblcVo) {
|
|
|
+ TokenAmz amz = new TokenAmz();
|
|
|
+ amz.setGrantType(AUTHORIZATION_CODE);
|
|
|
+ amz.setCode(gatblcVo.getLwaCode());
|
|
|
+ amz.setRedirectUri(REDIRECTURI);
|
|
|
+ amz.setClientId("amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8");
|
|
|
+ amz.setClientSecret("amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54");
|
|
|
+ return JSONObject.toJSONString(amz);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addAmzToken(TbAmzToken tbAmzToken) throws Exception {
|
|
|
+ tbAmzTokenMapper.insert(tbAmzToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void delAmzToken(TbAmzToken tbAmzToken) throws Exception {
|
|
|
+ Assert.notNull(tbAmzToken.getId(), "请检查提交参数!");
|
|
|
+ tbAmzTokenMapper.delAmzToken(tbAmzToken.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void editAmzToken(TbAmzToken tbAmzToken) throws Exception {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<TbAmzToken> selAmzToken(TbAmzToken tbAmzToken) throws Exception {
|
|
|
+ return tbAmzTokenMapper.selectList(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public TbAmzToken selAmzTokenById(TbAmzToken tbAmzToken) throws Exception {
|
|
|
+ return tbAmzTokenMapper.selectById(tbAmzToken.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 刷新亚马逊 访问令牌过期时间
|
|
|
+ *
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Result<String> lwaRefreshToken(TbAmzToken tat) throws Exception {
|
|
|
+ Assert.hasLength(tat.getRefreshToken(), "请检查提交参数! getRefreshToken is empty ");
|
|
|
+ Result<String> rt = new Result<>();
|
|
|
+ // 设置请求头
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("grant_type", REFRESH_TOKEN);
|
|
|
+ params.put("refresh_token", tat.getRefreshToken());
|
|
|
+ params.put("client_id", "amzn1.application-oa2-client.2d001c4aeaaf438f98ee0b07070c1cf8");
|
|
|
+ params.put("client_secret", "amzn1.oa2-cs.v1.52b13f4ce04e83046b3426b620b6bfb94fd3ce61c815c6f68858af69d0ccbe54");
|
|
|
+
|
|
|
+ // 设置请求体
|
|
|
+ String requestBody = params.toString();
|
|
|
+ // 创建请求实体
|
|
|
+ HttpEntity<String> request = new HttpEntity<>(requestBody, headers);
|
|
|
+ // 发送 POST 请求
|
|
|
+ String response = restTemplate.postForObject(URL, request, String.class);
|
|
|
+ log.info("企业编码=>"+tat.getCompanyId()+" 调用亚马逊" + URL + " 接口刷新令牌信息: 入参数据=> " + params);
|
|
|
+ log.info("企业编码=>"+tat.getCompanyId()+" 调用亚马逊" + URL + " 接口刷新令牌信息: 接口返回=> " + response);
|
|
|
+ try {
|
|
|
+ // 数据校验
|
|
|
+ TokenRetAmzJson tokenJson = JSONObject.parseObject(response, TokenRetAmzJson.class);
|
|
|
+ Assert.notNull(tokenJson, " TokenRetAmzJson is null : 接口返回数据为空 ");
|
|
|
+ Assert.hasLength(tokenJson.getTokenType(), "getTokenType is empty :LWA 授权码 刷新令牌失败 接口返回=>" + response);
|
|
|
+ Assert.isTrue(BEARER.equals(tokenJson.getTokenType()), "getTokenType 类型 不等于 bearer :LWA 授权码 刷新令牌失败 接口返回=>" + response);
|
|
|
+ // 获取当前时间戳
|
|
|
+ long second = Instant.now().getEpochSecond();
|
|
|
+ // 计算过期时间 *0.8 让令牌过期时间提前 留给让刷令牌操作时间
|
|
|
+ second = (long) (second+tokenJson.getExpiresIn() * 0.8);
|
|
|
+
|
|
|
+ // 组织更新 数据
|
|
|
+ TbAmzToken tbAmzToken = new TbAmzToken();
|
|
|
+ tbAmzToken.setId(tat.getId());
|
|
|
+ tbAmzToken.setCompanyId(tat.getCompanyId());
|
|
|
+
|
|
|
+ tbAmzToken.setAccessToken(tokenJson.getAccessToken());
|
|
|
+ tbAmzToken.setTokenType(tokenJson.getTokenType());
|
|
|
+ tbAmzToken.setExpiresIn(second);
|
|
|
+ tbAmzToken.setRefreshToken(tokenJson.getRefreshToken());
|
|
|
+
|
|
|
+ //执行更新
|
|
|
+ tbAmzTokenMapper.updateAccessToken( tbAmzToken );
|
|
|
+
|
|
|
+ rt.success();
|
|
|
+ rt.setMsg("刷新令牌成功!");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + " 接口入参=>" + JSONObject.toJSONString(tat));
|
|
|
+ log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + " 接口返回=>" + JSONObject.toJSONString(response));
|
|
|
+ log.error("刷新令牌失败! 企业编号=>" + tat.getCompanyId() + " 异常信息=>" + e.getMessage(), e);
|
|
|
+ rt.fail();
|
|
|
+ rt.setMsg("刷新令牌失败!");
|
|
|
+ }
|
|
|
+ return rt;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用LWA code 获取亚马逊令牌
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Result<String> getAmzTokenByLwaCode(GetAmzTokenByLwaCodeVo gatblcVo) throws Exception {
|
|
|
+ Result<String> rt = new Result<>();
|
|
|
+ // 设置请求头
|
|
|
+ HttpHeaders headers = new HttpHeaders();
|
|
|
+ headers.setContentType(MediaType.APPLICATION_JSON);
|
|
|
+ //设置请求体
|
|
|
+ String params = this.getRequestBody(gatblcVo);
|
|
|
+ // 创建请求实体
|
|
|
+ HttpEntity<String> request = new HttpEntity<>(params, headers);
|
|
|
+ // 发送 POST 请求
|
|
|
+ String response = restTemplate.postForObject(URL, request, String.class);
|
|
|
+
|
|
|
+ log.info("企业编码=>"+gatblcVo.getCompanyId()+" 调用亚马逊" + URL + " 接口获取令牌信息: 入参数据=> " + params);
|
|
|
+ log.info("企业编码=>"+gatblcVo.getCompanyId()+" 调用亚马逊" + URL + " 接口获取令牌信息: 接口返回=> " + response);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 数据校验
|
|
|
+ TokenRetAmzJson tokenJson = JSONObject.parseObject(response, TokenRetAmzJson.class);
|
|
|
+ Assert.notNull(tokenJson, " TokenRetAmzJson is null : 接口返回数据为空 ");
|
|
|
+ Assert.hasLength(tokenJson.getTokenType(), "getTokenType is empty :LWA 授权码 刷新令牌失败 接口返回=>" + response);
|
|
|
+ Assert.isTrue(BEARER.equals(tokenJson.getTokenType()), "getTokenType 类型 不等于 bearer :LWA 授权码 刷新令牌失败 接口返回=>" + response);
|
|
|
+
|
|
|
+ // 获取当前时间戳
|
|
|
+ long second = Instant.now().getEpochSecond();
|
|
|
+ // 计算过期时间 *0.8 让令牌过期时间提前 留给让刷令牌操作时间
|
|
|
+ second = (long) (second+tokenJson.getExpiresIn() * 0.8);
|
|
|
+
|
|
|
+
|
|
|
+ // 组织保存数据
|
|
|
+ TbAmzToken tbAmzToken = new TbAmzToken();
|
|
|
+ tbAmzToken.setCompanyId(gatblcVo.getCompanyId());
|
|
|
+ tbAmzToken.setStoreId(gatblcVo.getStoreId());
|
|
|
+ tbAmzToken.setMarketId(gatblcVo.getSellingPartnerId());
|
|
|
+
|
|
|
+ tbAmzToken.setAccessToken(tokenJson.getAccessToken());
|
|
|
+ tbAmzToken.setTokenType(tokenJson.getTokenType());
|
|
|
+ tbAmzToken.setExpiresIn(second);
|
|
|
+ tbAmzToken.setRefreshToken(tokenJson.getRefreshToken());
|
|
|
+
|
|
|
+ //保存令牌 信息
|
|
|
+ this.addAmzToken(tbAmzToken);
|
|
|
+ rt.success();
|
|
|
+ rt.setMsg("LWA CODE 获取令牌成功!");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + " 接口入参=>" + JSONObject.toJSONString(gatblcVo));
|
|
|
+ log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + " 接口返回=>" + JSONObject.toJSONString(response));
|
|
|
+ log.error(" LWA CODE 获取令牌失败! 企业编号=>" + gatblcVo.getCompanyId() + " 异常信息=>" + e.getMessage(), e);
|
|
|
+ rt.fail();
|
|
|
+ rt.setMsg("LWA CODE 获取令牌失败!");
|
|
|
+ }
|
|
|
+ return rt;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|