企业对接Walmart平台API流程(一)

发布时间:2023-05-09 09:42:47

 

对接方案

  • Walmart API授权基于OAuth Token OAuth2.0的授权模式不是授权模式;
  • 这种授权模式是一种使用凭证授权的方式,卖方需要 Walmart开发人员在后台生成一套包括Client在内的凭证信息 ID 和 Client Secret。
一、US站点

如果是US站点,您需要在开发人员的后台获取以下信息。

企业对接Walmart平台API流程(一)_API

请求头参数

企业对接Walmart平台API流程(一)_redis_02

  • WM_SVC.NAME Walmart Service Name 必填 例如:Walmart Marketplace
  • WM_QOS.CORRELATION_ID 每个请求的唯一ID 必填 例如: UUID
  • Authorization 使用Client ID and Client 由Secret组合生成的Base64 encodes 必填 例如:Basic YzcyotfjnmitNzi5MC
  • WM_CONSUMER.CHANNEL.TYPE 如果凭证由卖方自己使用,则该值为空。如果第三方服务提供商呼叫API,则该值需要第三方服务提供商通过业务合作从Walmart获得。该参数用于Walmart识别哪个第三方呼叫API
  • WM_SEC.ACCESS_TOKEN 必填,Client,通过使用 ID and Client Secret 要求Token API 获得access_token,有效期为15分钟
1.获取授权
/**     * 编码密钥     *     * @return     */    private String getAuthorization(String clientSecret, String clientId) {        String str = clientSecret+ ":" + clientId;        return "Basic " + Base64.encodebase64String(str.getBytes());    }
2.获取 Token
**     * 获得美国商店的token     *     * @return     */    public String getUSAAccessToken(String authorization, ShopSettings shopSettings) {//从redis中获得        String redisKey = String.format(WalmartConstant.ACCESS_TOKEN, shopSettings.getAccountName());        String accessToken = redisCache.getCacheObject(redisKey);        if (StringUtils.isNotEmpty(accessToken)) {            log.debug(”从redis获取token:{}", accessToken);            return accessToken;        }        Map<String, String> headers = new HashMap<>();        headers.put("Authorization", authorization);        headers.put("WM_SVC.NAME", shopSettings.getAccountName());        headers.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());        try {            HttpResponse response = HttpRequest.post(WalmartConstant.USA_TOKEN_URL)                    .addHeaders(headers)                    .body("grant_type=client_credentials", "application/x-www-form-urlencoded")                    .execute();            JSONObject jsonObject = JSONObject.parseObject(response.body());            accessToken = jsonObject.getString("access_token");            if (accessToken == null) {                throw new CustomException(未能获得沃尔玛接口调用凭证”, 500);            }        }catch (Exception e){            log.error([获得美国网站token值异常],{},e.getMessage());            return null;        }        redisCache.setCacheObject(redisKey, accessToken, 899, TimeUnit.SECONDS);        log.debug(生成的token为:{} accessToken);        return accessToken;    }
3.获取访问US站点API的请求头
/**     * 访问US站点API的请求头     *     * @return     */    public Map<String, String> getUsHeaders(Long accountId) {        ShopSettings shopSettings = shopSettingsService.getShopSettingCache(accountId, "walmart");        String authorization = getAuthorization(shopSettings.getClientSecret(), shopSettings.getClientId());        Map<String, String> headers = new HashMap<>();        headers.put("Authorization", authorization);        headers.put("WM_SVC.NAME", shopSettings.getAccountName());        headers.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());        headers.put("WM_SEC.ACCESS_TOKEN", getUSAccessToken(authorization, shopSettings));        return headers;    }
4.调用API测试
/**     * 在节点上获取商品库存     * @param sku     * @return     */    @GetMapping("/inventories/{sku}")    public AjaxResult getInventory(@PathVariable(value = "sku") String sku,                                   @RequestParam(required = false, value = "shipNode")String shipNode){        if (StringUtils.isBlank(sku)){            return AjaxResult.error(BaseError.CHECK_ERROR);        }        String url = "https://marketplace.walmartapis.com/v3/inventories/"+ sku;        if (StringUtils.isNotBlank(shipNode)){            url = url+"?shipNode=" + shipNode;        }        Map<String, String> headers = walmartUtil.getUsHeaders(60L);//执行请求,获取数据        HttpResponse response = HttpRequest.get(url)                .addHeaders(headers)                .contentType("application/json()//必须添加此行代码,否则可能会报错                .execute();        if (200 == response.getStatus()) {            return AjaxResult.success(JSONObject.parseObject(response.body()));        }        return AjaxResult.error();    }
二、CA站点

CA网站与US网站略有不同,CA网站位于卖家中心的Generala 点击API跳转到页面获取Consumer ID、Channel Type、Private Key。Consumer ID等同于US站点的Client ID,Private Key等同于Clientt Secret。Channel Type是请求头参数中的WM_CONSUMER.CHANNEL.TYPE

企业对接Walmart平台API流程(一)_API_03

企业对接Walmart平台API流程(一)_API_04

1.获取CA网站API的数字签名和时间戳
/**     * 访问加拿大商店API的数字签名和时间戳参数     *     * @param requestUrl     * @param requestMethod     * @return     */    public Map<String, String> getSignatureAndTimestamp(String requestUrl, String requestMethod, Long accountId) {        if (StringUtils.isEmpty(requestMethod) || StringUtils.isEmpty(requestUrl)) {            throw new CustomException(BaseError.CHECK_ERROR);        }        Map<String, String> result = new HashMap<>();        String timestamp = String.valueOf(System.currentTimeMillis());        String signature = getWalmartAuthSignature(requestUrl, requestMethod, timestamp, accountId);        result.put("authSignature", signature);        result.put("timestamp", timestamp);        return result;    } /**     * 获得沃尔玛认证的数字签名     *     * @param requestUrl    要调用的完整性 URL,包括路径和查询参数     * @param requestMethod GET  or  POST     * @param timestamp     时间戳     * @return     */    private String getWalmartAuthSignature(String requestUrl, String requestMethod, String timestamp, Long accountId) {        ShopSettings shopSettings = shopSettingsService.getShopSettingCache(accountId, "walmart");        ////登录后从开发者中心获取的Consumer ID        String consumerId = shopSettings.getConsumerId();        //私钥        String privateKey = shopSettings.getPrivateKey();        String stringToSign = consumerId + "\n" + requestUrl + "\n" + requestMethod + "\n" + timestamp + "\n";        return signData(stringToSign, privateKey);    }/**     * 签名算法     *     * @param stringToBeSigned  签名结构  消费者ID(Consumer ID) + "\n" + 完整路径(url) + "\n" + 时间戳(timestamp) + "\n";     * @param encodedPrivateKey 私密密钥Privatetet Key     * @return     */    private static String signData(String stringToBeSigned, String encodedPrivateKey) {        String signatureString = null;        try {            byte[] encodedKeyBytes = Base64.decodebase64(encodedPrivateKey);            PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(encodedKeyBytes);            KeyFactory kf = KeyFactory.getInstance("RSA");            PrivateKey myPrivateKey = kf.generatePrivate(privSpec);            Signature signature = Signature.getInstance(SHA256withRSA);            signature.initSign(myPrivateKey);            byte[] data = stringToBeSigned.getBytes("UTF-8");            signature.update(data);            byte[] signedBytes = signature.sign();            signatureString = Base64.encodebase64String(signedBytes);        } catch (Exception e) {            e.printStackTrace();        }        return signatureString;    }
2.获取访问CA网站API的请求头
/**     * 访问CA网站API的请求头     *     * @return     */    public Map<String, String> getCaHeaders(String requestUrl, String requestMethod, Long accountId) {        ShopSettings shopSettings = shopSettingsService.getShopSettingCache(accountId, "walmart");        Map<String, String> map = getSignatureAndTimestamp(requestUrl, requestMethod, accountId);        String authSignature = map.get("authSignature");        String timestamp = map.get("timestaximp");        log.debug(authSignature);        log.debug(timestamp);        Map<String, String> headers = new HashMap<>();        headers.put("WM_CONSUMER.CHANNEL.TYPE", shopSettings.getChannelType());        headers.put("WM_SVC.NAME", shopSettings.getAccountName());        headers.put("WM_QOS.CORRELATION_ID", UUID.randomUUID().toString());        headers.put("WM_SEC.TIMESTAMP", timestamp);        headers.put("WM_SEC.AUTH_SIGNATURE", authSignature);        headers.put("WM_CONSUMER.ID", shopSettings.getConsumerId());        return headers;    }
3.调用API测试
public JSONObject listItemsCa(ItemParams itemParams, Long accountId) {        String nextCursor = Optional.ofNullable(itemParams.getNextCursor()).orElse("*");        String limit = Optional.ofNullable(itemParams.getLimit()).orElse("50");        String url = "https://marketplace.walmartapis.com/v3/ca/items?nextCursor=" + nextCursor + "&limit=" + limit;        Map<String, String> headers = walmartUtil.getCaHeaders(url, "GET", accountId);        try {            HttpResponse response = HttpRequest.get(url)                    .addHeaders(headers)                    .execute();            if (200 == response.getStatus()){                return JSONObject.parseObject(response.body());            }        }catch (Exception e){            log.error("【walmart CA 查询商品错误】:{}", e.getMessage());        }        return new JSONObject();    }

上一篇 zephyr 环境设置
下一篇 开源开发者提交不安全代码,遭 Linus 炮轰

文章素材均来源于网络,如有侵权,请联系管理员删除。

标签: Java教程Java基础Java编程技巧面试题Java面试题