记录对接京东宙斯API -- 同步订单信息到自身系统

记录对接京东宙斯API -- 同步订单信息到自身系统

  • 目录
    • 1. 需求
    • 2. 准备工作一: 查看官方文档
    • 3. 准备工作二: 申请京东云鼎并入驻
    • 4. 创建一个新的项目并部署到云鼎.
    • 5. 调用订单API代码.
    • 6. JdService

目录

1. 需求

根据产品大大的需求描述:

  1. 对客户的京东旗舰店里的订单信息同步到自身开发的后台管理中.
  2. 实现对订单信息简单的搜索功能.
  3. 实现人工同步的功能.

2. 准备工作一: 查看官方文档

PS: 在寻找AIP时, 可根据需求的不同, 寻找对应的API文档.
记录对接京东宙斯API -- 同步订单信息到自身系统_第1张图片
找到官方API时, 当时的我感觉调用订单API的方式应该和其他API是一样的, 有了京东宙斯账号就可以, 但…实践调用以后, 很明显我错了.
在调用订单API时, 它返回了一个错误信息给我: 该api是敏感api,请将您的app入驻云鼎平台方可调用
返回的这条信息很明显的告诉我, 要我去申请京东云鼎平台的账号,并且还要入驻.
PS: 入驻云鼎是要钱的, 因为要购买云主机.

3. 准备工作二: 申请京东云鼎并入驻

入驻京东云鼎的具体流程这里我就展开讲述了, 官方有一套很完善的流程.
这是京东官方入驻云鼎的流程, 如果有感兴趣的小伙伴想了解一下可以点击这个链接: 入鼎公告
至此, 准备工作完成.

4. 创建一个新的项目并部署到云鼎.

PS: 之所以要创建一个新的项目并部署到云鼎, 是因为订单API是属于敏感类型的, 只能内部调用.

5. 调用订单API代码.

京东官方订单API文档

   /**
     * @Author 蠕动的小蜗牛
     * @Description 根据条件检索订单信息 (仅适用于SOP、LBP,SOPL类型,FBP类型请调取FBP订单检索  jingdong.pop.order.search)
     * @Date 16:45 2019/8/13
     * @Param [accessToken, startDateStr, endDateStr]
     * @Param [accessToken, 开始时间, 结束时间, 订单状态, 返回字段, 查询类型, 当前页, 页大小]
     * @return com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.enSearch.OrderListResult
     **/
    public OrderListResult findAllOrderData(String accessToken, String startDateStr, String endDateStr,
                                            String orderState, String optionalFields, Integer dateType,
                                            String page, String pageSize){

        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            PopOrderEnSearchRequest request = new PopOrderEnSearchRequest();
            /** WAIT_SELLER_STOCK_OUT 等待出库,则start_date可以为否(开始时间和结束时间均为空,默认返回前一个月的订单),
            order_state为其他值,则start_date必须为是(开始时间和结束时间,不得相差超过1个月。此时间仅针对订单状态及运单号修改的时间) */
            request.setStartDate(startDateStr);
            /**  WAIT_SELLER_STOCK_OUT 等待出库,则start_date可以为否(开始时间和结束时间均为空,默认返回前一个月的订单),
             order_state为其他值,则start_date必须为是(开始时间和结束时间,不得相差超过1个月。此时间仅针对订单状态及运单号修改的时间) */
            request.setEndDate(endDateStr);
            /**  多订单状态可以用英文逗号隔开,请用英文逗号拼接英文状态传递给jos,而不是数字。
                1)WAIT_SELLER_STOCK_OUT 等待出库
                2)WAIT_GOODS_RECEIVE_CONFIRM 等待确认收货
                3)WAIT_SELLER_DELIVERY 等待发货(只适用于海外购商家,含义为'等待境内发货'标签下的订单,非海外购商家无需使用)
                4) PAUSE 暂停(loc订单可通过此状态获取)
                5)FINISHED_L 完成
                6)TRADE_CANCELED 取消
                7)LOCKED 已锁定
                8)POP_ORDER_PAUSE pop业务暂停,如3c号卡/履约/黄金 可传此状态。*/
            request.setOrderState(orderState); //  测试接口阶段, 查询 已取消的订单
            /** 需返回的字段列表。可选值,请参考返回结果集中的对象参数描述:orderInfo结构体中的所有字段;字段之间用,分隔 */
            request.setOptionalFields(optionalFields);
            /** 查询的页数 */
            request.setPage(page);
            /** 每页的条数(最大page_size 100条) */
            request.setPageSize(pageSize);
            /** 排序方式,默认升序,1是降序,其它数字都是升序 */
            request.setSortType(1);
            /** 查询时间类型,默认按修改时间查询。 1为按订单创建时间查询;其它数字为按订单(订单状态、修改运单号)修改时间 */
            request.setDateType(dateType);
            PopOrderEnSearchResponse response = client.execute(request);
            LOGGER.warn("    京东旗舰店订单信息:    " + JSONUtils.toJsonString(response));
            if (response.getSearchorderinfoResult() != null) {
                LOGGER.warn("************ 查询京东旗舰店订单信息成功  ************");
                OrderListResult searchorderinfoResult = response.getSearchorderinfoResult();
                return searchorderinfoResult;
            }
        } catch (Exception e) {
            LOGGER.error("************ 查询京东旗舰店订单信息失败  ************", e);
            e.printStackTrace();
        }

        return null;
    }

6. JdService

package XXXX;

import com.alibaba.fastjson.JSONObject;
import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.jd.open.api.sdk.domain.delivery.DeliveryCompany;
import com.jd.open.api.sdk.domain.order.OrderNotPayService.response.notPayOrderInfo.OrderDataNotPayInfo;
import com.jd.open.api.sdk.domain.order.OrderNotPayService.response.notPayOrderInfo.PaginatedInfo;
import com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.enSearch.OrderListResult;
import com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.get.OrderResult;
import com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.get.OrderSearchInfo;
import com.jd.open.api.sdk.domain.order.OrderShipmentService.response.shipment.OperatorResult;
import com.jd.open.api.sdk.request.delivery.GetVenderAllDeliveryCompanyRequest;
import com.jd.open.api.sdk.request.imgzone.ImgzoneCategoryQueryRequest;
import com.jd.open.api.sdk.request.imgzone.ImgzonePictureUploadRequest;
import com.jd.open.api.sdk.request.order.PopOrderEnSearchRequest;
import com.jd.open.api.sdk.request.order.PopOrderGetRequest;
import com.jd.open.api.sdk.request.order.PopOrderNotPayOrderInfoRequest;
import com.jd.open.api.sdk.request.order.PopOrderShipmentRequest;
import com.jd.open.api.sdk.response.delivery.GetVenderAllDeliveryCompanyResponse;
import com.jd.open.api.sdk.response.imgzone.ImgzoneCategory;
import com.jd.open.api.sdk.response.imgzone.ImgzoneCategoryQueryResponse;
import com.jd.open.api.sdk.response.imgzone.ImgzonePictureUploadResponse;
import com.jd.open.api.sdk.response.order.PopOrderEnSearchResponse;
import com.jd.open.api.sdk.response.order.PopOrderGetResponse;
import com.jd.open.api.sdk.response.order.PopOrderNotPayOrderInfoResponse;
import com.jd.open.api.sdk.response.order.PopOrderShipmentResponse;
import XXX.Config;
import XXX.JSONUtils;
import XXX.CollectionUtils;
import XXX.DateUtils;
import XXX.HttpUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.*;

/**
 * @ClassName JdService
 * @Description: 京东API接口相关
 * @Auther: 蠕动的小蜗牛
 * @Date: 2019/4/16 16:05
 * @Version: 1.0
 **/
@Service
public class JdService {

    private static final Logger LOGGER = LoggerFactory.getLogger(JdService.class);

    /**
     * appKey
     */
    private String APPKEY = "XXX";
    /**
     * AppSecret
     */
    private String APPSECRET = "XXX";

    /**
     * 接口版本
     */
    private String V = "2.0";
    /**
     * 接口URL(线上)
     */
    private String SERVER_URL = "https://api.jd.com/routerjson";

    @Resource
    private Config config;


    /**
     * @Author 蠕动的小蜗牛
     * @Description sop出库发货接口 (jingdong.pop.order.shipment)
     * @Date 10:32 2019/8/17
     * @Param [accessToken, orderId, logiCoprId, logiNo, installId]
     * @Param [accessToken, 订单号, 物流公司ID, 运单号, 安装公司]
     * @return 0 发货失败,  1 发货成功
     **/
    public Boolean doShipment(String accessToken, Long orderId, String logiCoprId, String logiNo, Long installId){
        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            PopOrderShipmentRequest request = new PopOrderShipmentRequest();
            request.setOrderId(orderId);
            /** 物流公司ID(只可通过获取商家物流公司接口获得),多个物流公司以|分隔。
             如:2100|4700。请注意:如果填写厂家自送(1274),
             则不会保存物流单号,也不会有具体的跟踪信息。 request.setLogiCoprId("2100|4700") */
            request.setLogiCoprId(logiCoprId);
            /** 运单号(当厂家自送时运单号可为空,不同物流公司的运单号用|分隔,
             如果同一物流公司有多个运单号,则用英文逗号分隔) 。
             如:1200458628372,111232|468778814888,323232323
             request.setLogiNo("1200458628372,111232|468778814888,323232323 "); */
            request.setLogiNo(logiNo);
            request.setInstallId(installId);
            PopOrderShipmentResponse response = client.execute(request);
            LOGGER.warn("************* sop出库发货接口: " + JSONUtils.toJsonString(response));
            OperatorResult sopjosshipmentResult = response.getSopjosshipmentResult();
            if (sopjosshipmentResult != null) {
                    return sopjosshipmentResult.getSuccess();
            }

            return false;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }


    /**
     * @Author 蠕动的小蜗牛
     * @Description 获取商家物流公司
     * @Date 11:46 2019/8/17
     * @Param [accessToken]
     * @return void
     **/
    public List<DeliveryCompany> findAllJdCompanyData(String accessToken){
        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            GetVenderAllDeliveryCompanyRequest request = new GetVenderAllDeliveryCompanyRequest();
            request.setFields("id,name,description");
            GetVenderAllDeliveryCompanyResponse response = client.execute(request);
            LOGGER.warn("获取商家物流公司: " + JSONUtils.toJsonString(response));
            List<DeliveryCompany> deliveryList = response.getDeliveryList();
            if (CollectionUtils.notEmpty(deliveryList)) return deliveryList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @Author 蠕动的小蜗牛
     * @Description 输入单个SOP订单id,得到所有相关订单信息 (jingdong.pop.order.get) 拼接URI
     * @Date 16:03 2019/8/14
     * @Param [accessToken, optionalFields, orderId]
     * @Param [accessToken, 返回字段, orderId]
     * @return com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.get.OrderSearchInfo
     **/
    public JSONObject findOrderData(String accessToken, String optionalFields, Long orderId, String pin){


        // 生成签名
        String method = "jingdong.pop.order.get";
        String timestamp = DateUtils.convertDate2String(null, new Date());
        Map<String, Object> map = new HashMap<>();
        map.put("optional_fields", optionalFields);
        map.put("order_id", orderId);
        map.put("pin", pin);
        String requestParam = JSONUtils.toJsonString(map);


        HashMap<String, Object> params = new HashMap<>();
        params.put("v", V);
        params.put("method", method);
        params.put("timestamp", timestamp);
        params.put("app_key", APPKEY);
        params.put("app_secret", APPSECRET);
        params.put("access_token", accessToken);
        params.put("360buy_param_json", map);
        String sign = jdSign(params);

        try {
            // 拼接URL
            String url = SERVER_URL + "?v=" + V +
                    "&method=" + method +
                    "&app_key=" + APPKEY +
                    "&access_token=" + accessToken +
                    "&360buy_param_json=" + URLEncoder.encode(requestParam, "UTF-8") +
                    "×tamp=" + URLEncoder.encode(timestamp, "UTF-8") +
                    "&sign=" + sign;

            JSONObject jsonObject = HttpUtils.doGetJson(url);
            LOGGER.warn("===============京东API 输入单个SOP订单id,得到所有相关订单信息: " + jsonObject.toString() + "=====================");
            return jsonObject;
        } catch (Exception e) {
            LOGGER.warn("=============== 京东API 输入单个SOP订单id,得到所有相关订单信息!!! =====================");
            e.printStackTrace();
        }
        return null;
    }



    /**
     * @Author 蠕动的小蜗牛
     * @Description 输入单个SOP订单id,得到所有相关订单信息 (jingdong.pop.order.get)
     * @Date 16:03 2019/8/14
     * @Param [accessToken, optionalFields, orderId]
     * @Param [accessToken, 返回字段, orderId]
     * @return com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.get.OrderSearchInfo
     **/
    public OrderResult findOrderDetailsData(String accessToken, String optionalFields, Long orderId){

        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            PopOrderGetRequest request = new PopOrderGetRequest();
//            request.setOrderState("WAIT_SELLER_DELIVERY"); // 不是必填
            if (StringUtils.isBlank(optionalFields)) optionalFields = "pin";
            request.setOptionalFields(optionalFields);
            request.setOrderId(orderId); // 订单号,并且有效的订单号
            PopOrderGetResponse response = client.execute(request);
            LOGGER.warn("输入单个SOP订单id,得到所有相关订单信息: " + JSONUtils.toJsonString(response));
            OrderResult orderDetailInfo = response.getOrderDetailInfo();
            if (orderDetailInfo != null) return orderDetailInfo;
        } catch (Exception e) {
            LOGGER.warn("****************** 输入单个SOP订单id,得到所有相关订单信息失败 *****************");
            e.printStackTrace();
        }

        return null;
    }


    /**
     * @Author 蠕动的小蜗牛
     * @Description 批量查询未付款订单(jingdong.pop.order.notPayOrderInfo)
     * @Date 15:22 2019/8/14
     * @Param [accessToken, startDateStr, endDateStr, page,  pageSize]
     * @Param [accessToken,  开始时间,     结束时间, 当前页, 页大小]
     * @return java.util.List
     **/
    public List<OrderDataNotPayInfo> findWaitPayOrderData(String accessToken, Date startDateStr, Date endDateStr,
                                                          Integer page, Integer pageSize){

        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            PopOrderNotPayOrderInfoRequest request = new PopOrderNotPayOrderInfoRequest();
            request.setStartDate(startDateStr);
            request.setEndDate(endDateStr);
            request.setPage(page);
            request.setPageSize(pageSize);
            PopOrderNotPayOrderInfoResponse response = client.execute(request);
            LOGGER.warn("***************** 批量查询未付款订单: " + JSONUtils.toJsonString(response));
            PaginatedInfo paginatedInfo = response.getPaginatedInfo();
            if (paginatedInfo != null) {
                List<OrderDataNotPayInfo> pageList = paginatedInfo.getPageList();
                if (CollectionUtils.notEmpty(pageList)) return pageList;
            }
        } catch (Exception e) {
            LOGGER.warn("***************** 批量查询未付款订单失败 *****************");
            e.printStackTrace();
        }

        return null;
    }


    /**
     * @Author 蠕动的小蜗牛
     * @Description 根据条件检索订单信息 (仅适用于SOP、LBP,SOPL类型,FBP类型请调取FBP订单检索  jingdong.pop.order.search)
     * @Date 16:45 2019/8/13
     * @Param [accessToken, startDateStr, endDateStr]
     * @Param [accessToken, 开始时间, 结束时间, 订单状态, 返回字段, 查询类型, 当前页, 页大小]
     * @return com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.enSearch.OrderListResult
     **/
    public OrderListResult findAllOrderData(String accessToken, String startDateStr, String endDateStr,
                                            String orderState, String optionalFields, Integer dateType,
                                            String page, String pageSize){

        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            PopOrderEnSearchRequest request = new PopOrderEnSearchRequest();
            /** WAIT_SELLER_STOCK_OUT 等待出库,则start_date可以为否(开始时间和结束时间均为空,默认返回前一个月的订单),
            order_state为其他值,则start_date必须为是(开始时间和结束时间,不得相差超过1个月。此时间仅针对订单状态及运单号修改的时间) */
            request.setStartDate(startDateStr);
            /**  WAIT_SELLER_STOCK_OUT 等待出库,则start_date可以为否(开始时间和结束时间均为空,默认返回前一个月的订单),
             order_state为其他值,则start_date必须为是(开始时间和结束时间,不得相差超过1个月。此时间仅针对订单状态及运单号修改的时间) */
            request.setEndDate(endDateStr);
            /**  多订单状态可以用英文逗号隔开,请用英文逗号拼接英文状态传递给jos,而不是数字。
                1)WAIT_SELLER_STOCK_OUT 等待出库
                2)WAIT_GOODS_RECEIVE_CONFIRM 等待确认收货
                3)WAIT_SELLER_DELIVERY 等待发货(只适用于海外购商家,含义为'等待境内发货'标签下的订单,非海外购商家无需使用)
                4) PAUSE 暂停(loc订单可通过此状态获取)
                5)FINISHED_L 完成
                6)TRADE_CANCELED 取消
                7)LOCKED 已锁定
                8)POP_ORDER_PAUSE pop业务暂停,如3c号卡/履约/黄金 可传此状态。*/
            request.setOrderState(orderState); //  测试接口阶段, 查询 已取消的订单
            /** 需返回的字段列表。可选值,请参考返回结果集中的对象参数描述:orderInfo结构体中的所有字段;字段之间用,分隔 */
            request.setOptionalFields(optionalFields);
            /** 查询的页数 */
            request.setPage(page);
            /** 每页的条数(最大page_size 100条) */
            request.setPageSize(pageSize);
            /** 排序方式,默认升序,1是降序,其它数字都是升序 */
            request.setSortType(1);
            /** 查询时间类型,默认按修改时间查询。 1为按订单创建时间查询;其它数字为按订单(订单状态、修改运单号)修改时间 */
            request.setDateType(dateType);
            PopOrderEnSearchResponse response = client.execute(request);
            LOGGER.warn("    京东旗舰店订单信息:    " + JSONUtils.toJsonString(response));
            if (response.getSearchorderinfoResult() != null) {
                LOGGER.warn("************ 查询京东旗舰店订单信息成功  ************");
                OrderListResult searchorderinfoResult = response.getSearchorderinfoResult();
                return searchorderinfoResult;
            }
        } catch (Exception e) {
            LOGGER.error("************ 查询京东旗舰店订单信息失败  ************", e);
            e.printStackTrace();
        }

        return null;
    }



    /**
     * @Author 蠕动的小蜗牛
     * @Description 上传单张图片
     * @Date 11:29 2019/7/17
     * @Param [accessToken, imageData, pictureCateId, pictureName]
     * @Param [accessToken, 图片二进制文件流,允许png、jpg、gif、jpeg、bmp图片格式,1M以内,
     *                               上传到的图片分类ID,为空上传至 默认分类,
     *                                              图片名称,不超过64字节,为空默认 未命名]
     * @return com.alibaba.fastjson.JSONObject
     **/
    public ImgzonePictureUploadResponse pictureUpload(String accessToken, byte[] imageData, Long pictureCateId, String pictureName){


        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            ImgzonePictureUploadRequest request = new ImgzonePictureUploadRequest();
            request.setImageData(imageData);
            request.setPictureCateId(pictureCateId);
            request.setPictureName(pictureName);
            ImgzonePictureUploadResponse response = client.execute(request);
            LOGGER.warn("===============京东API 上传单张图片: " + JSONUtils.toJsonString(response) + "=====================");

            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * @Author 蠕动的小蜗牛
     * @Description 查询图片分类(所有参数为非必填, 不填时查询所有)
     * @Date 14:04 2019/7/17
     * @Param [accessToken, cateId, cateName, parentCateId]
     * @Param [accessToken, 分类ID, 分类名称,不支持模糊查询, 父分类ID,查询二级分类时为对应父分类id,查询一级分类时为0,查询全部分类的时候为空]
     * @return com.jd.open.api.sdk.response.imgzone.ImgzoneCategoryQueryResponse
     **/
    public List<ImgzoneCategory> imgzoneCategoryQuery(String accessToken, Long cateId, String cateName, Long parentCateId) {
        try {
            JdClient client = new DefaultJdClient(SERVER_URL, accessToken, APPKEY, APPSECRET);
            ImgzoneCategoryQueryRequest request = new ImgzoneCategoryQueryRequest();
            request.setCateId(cateId);
            request.setCateName(cateName);
            request.setParentCateId(parentCateId);
            ImgzoneCategoryQueryResponse response = client.execute(request);
            List<ImgzoneCategory> cateList = response.getCateList();
            if (CollectionUtils.notEmpty(cateList)) {
                return cateList;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }



    /**
     * @Author 蠕动的小蜗牛
     * @Description 京东签名规则
     *          1.  所有请求参数按照字母先后顺序排列.  例如: 将access_token,app_key,method,timestamp,v 排序为access_token,app_key,method,timestamp,v
     *          2. 把所有参数名和参数值进行拼装.       例如:access_tokenxxxapp_keyxxxmethodxxxxxxtimestampxxxxxxvx
     *          3. 把appSecret夹在字符串的两端         例如:appSecret+XXXX+appSecret
     *          4. 使用MD5进行加密,再转化成大写
     * @Date 10:24 2019/6/14
     * @Param [params, appSecret]
     * @return java.lang.String
     **/
    public String jdSign(HashMap<String, Object> params) {
        StringBuilder valueSb = new StringBuilder();
        valueSb.append(APPSECRET);
        // 1. 将参数以参数名的字典升序排序
        Map<String, Object> sortParams = new TreeMap<>(params);
        Set<Map.Entry<String, Object>> entrys = sortParams.entrySet();
        // 2. 遍历排序的字典,并拼接value1+value2......格式
        for (Map.Entry<String, Object> entry : entrys) {
            valueSb.append(entry.getValue());
        }
        // 3. 把appSecret夹在字符串的两端
        valueSb.append(APPSECRET);

        String sign = null;
        try {
            // 4. 使用MD5进行加密,再转化成大写
            String inStr = valueSb.toString();
            sign = DigestUtils.md5Hex(inStr.getBytes("UTF-8"));
        } catch (Exception e) {
            throw new RuntimeException("MD5签名过程中出现错误");
        }

        return sign.toUpperCase();
    }


}

PS: 记录日常开发中的点点滴滴…

你可能感兴趣的:(对接京东宙斯API,Java)